diff options
Diffstat (limited to 'dom/base/test')
973 files changed, 75480 insertions, 0 deletions
diff --git a/dom/base/test/345339_iframe.html b/dom/base/test/345339_iframe.html new file mode 100644 index 0000000000..890fb0d1cd --- /dev/null +++ b/dom/base/test/345339_iframe.html @@ -0,0 +1,27 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/REC-html401-19991224/strict.dtd"> +<html> + <head> + <title>Form Elements</title> + <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> + </head> + <body> + <p> + <select id="select"> + <option value="Mozilla">Mozilla</option> + <option value="Firefox">Firefox</option> + </select> + <form name="radioform" id="radioform"> + <input type="radio" id="radio1" name="answer" value="Yes" + checked="checked" /> + <input type="radio" id="radio2" name="answer" value="No" /> + </form> + + <input type="password" id="password" /> + + <input type="hidden" id="hidden" /> + + <input type="file" id="file" /> + </p> + </body> +</html> diff --git a/dom/base/test/Ahem.ttf b/dom/base/test/Ahem.ttf Binary files differnew file mode 100644 index 0000000000..ac81cb0316 --- /dev/null +++ b/dom/base/test/Ahem.ttf diff --git a/dom/base/test/accesscontrol.resource b/dom/base/test/accesscontrol.resource new file mode 100644 index 0000000000..aca66f6f8d --- /dev/null +++ b/dom/base/test/accesscontrol.resource @@ -0,0 +1,7 @@ +:this file must be enconded in utf8 +:and its Content-Type must be equal to text/event-stream + +event: message +data: 1 + + diff --git a/dom/base/test/accesscontrol.resource^headers^ b/dom/base/test/accesscontrol.resource^headers^ new file mode 100644 index 0000000000..75f1f88972 --- /dev/null +++ b/dom/base/test/accesscontrol.resource^headers^ @@ -0,0 +1,5 @@ +Access-Control-Allow-Origin: http://mochi.test:8888 +Access-Control-Allow-Credentials: true +Content-Type: text/event-stream +Cache-Control: no-cache, must-revalidate + diff --git a/dom/base/test/audio.ogg b/dom/base/test/audio.ogg Binary files differnew file mode 100644 index 0000000000..bed764fbf1 --- /dev/null +++ b/dom/base/test/audio.ogg diff --git a/dom/base/test/audioEndedDuringPlaying.webm b/dom/base/test/audioEndedDuringPlaying.webm Binary files differnew file mode 100644 index 0000000000..6ae65448d8 --- /dev/null +++ b/dom/base/test/audioEndedDuringPlaying.webm diff --git a/dom/base/test/badContentType.eventsource b/dom/base/test/badContentType.eventsource new file mode 100644 index 0000000000..c9d0739e18 --- /dev/null +++ b/dom/base/test/badContentType.eventsource @@ -0,0 +1,5 @@ +retry:500 +event: message +data: 1 + + diff --git a/dom/base/test/badContentType.eventsource^headers^ b/dom/base/test/badContentType.eventsource^headers^ new file mode 100644 index 0000000000..a1f9e38d90 --- /dev/null +++ b/dom/base/test/badContentType.eventsource^headers^ @@ -0,0 +1 @@ +Content-Type: text/plain diff --git a/dom/base/test/badHTTPResponseCode.eventsource b/dom/base/test/badHTTPResponseCode.eventsource new file mode 100644 index 0000000000..c9d0739e18 --- /dev/null +++ b/dom/base/test/badHTTPResponseCode.eventsource @@ -0,0 +1,5 @@ +retry:500 +event: message +data: 1 + + diff --git a/dom/base/test/badHTTPResponseCode.eventsource^headers^ b/dom/base/test/badHTTPResponseCode.eventsource^headers^ new file mode 100644 index 0000000000..545a9a201c --- /dev/null +++ b/dom/base/test/badHTTPResponseCode.eventsource^headers^ @@ -0,0 +1,2 @@ +HTTP 404 Not Found +Content-Type: text/event-stream diff --git a/dom/base/test/badMessageEvent.eventsource b/dom/base/test/badMessageEvent.eventsource new file mode 100644 index 0000000000..0c635f0b57 --- /dev/null +++ b/dom/base/test/badMessageEvent.eventsource @@ -0,0 +1,4 @@ +retry:500 +event: message + + diff --git a/dom/base/test/badMessageEvent.eventsource^headers^ b/dom/base/test/badMessageEvent.eventsource^headers^ new file mode 100644 index 0000000000..9bb8badcad --- /dev/null +++ b/dom/base/test/badMessageEvent.eventsource^headers^ @@ -0,0 +1 @@ +Content-Type: text/event-stream diff --git a/dom/base/test/badMessageEvent2.eventsource b/dom/base/test/badMessageEvent2.eventsource new file mode 100644 index 0000000000..ad6fa694f4 --- /dev/null +++ b/dom/base/test/badMessageEvent2.eventsource @@ -0,0 +1,5 @@ +retry:500 +data: ok + +id: invalid-id +data: not-ok diff --git a/dom/base/test/badMessageEvent2.eventsource^headers^ b/dom/base/test/badMessageEvent2.eventsource^headers^ new file mode 100644 index 0000000000..9bb8badcad --- /dev/null +++ b/dom/base/test/badMessageEvent2.eventsource^headers^ @@ -0,0 +1 @@ +Content-Type: text/event-stream diff --git a/dom/base/test/browser.ini b/dom/base/test/browser.ini new file mode 100644 index 0000000000..60949f7a2d --- /dev/null +++ b/dom/base/test/browser.ini @@ -0,0 +1,28 @@ +[DEFAULT] +support-files = + empty.html + file_bug1011748_redirect.sjs + file_bug1011748_OK.sjs + file_messagemanager_unload.html + file_use_counter_outer.html + file_use_counter_svg_getElementById.svg + file_use_counter_svg_currentScale.svg + file_use_counter_svg_fill_pattern_definition.svg + file_use_counter_svg_fill_pattern.svg + file_use_counter_svg_fill_pattern_internal.svg + file_use_counter_svg_fill_pattern_data.svg + +[browser_bug593387.js] +[browser_bug902350.js] +tags = mcb +[browser_bug1011748.js] +[browser_bug1058164.js] +[browser_messagemanager_loadprocessscript.js] +[browser_messagemanager_targetframeloader.js] +[browser_messagemanager_unload.js] +[browser_pagehide_on_tab_close.js] +skip-if = e10s # this tests non-e10s behavior. it's not expected to work in e10s. +[browser_state_notifications.js] +skip-if = true # Bug 1271028 +[browser_use_counters.js] +[browser_bug1307747.js] diff --git a/dom/base/test/browser_bug1011748.js b/dom/base/test/browser_bug1011748.js new file mode 100644 index 0000000000..a2158500df --- /dev/null +++ b/dom/base/test/browser_bug1011748.js @@ -0,0 +1,31 @@ +const gHttpTestRoot = "http://example.com/browser/dom/base/test/"; + +add_task(function* () { + var statusTexts = []; + var xhr = new XMLHttpRequest(); + var observer = { + observe: function (aSubject, aTopic, aData) { + try { + var channel = aSubject.QueryInterface(Ci.nsIHttpChannel); + channel.getResponseHeader("Location"); + } catch (e) { + return; + } + statusTexts.push(xhr.statusText); + } + }; + + Services.obs.addObserver(observer, "http-on-examine-response", false); + yield new Promise((resolve) => { + xhr.addEventListener("load", function() { + statusTexts.push(this.statusText); + is(statusTexts[0], "", "Empty statusText value for HTTP 302"); + is(statusTexts[1], "OK", "OK statusText value for the redirect."); + resolve(); + }); + xhr.open("GET", gHttpTestRoot+ "file_bug1011748_redirect.sjs", true); + xhr.send(); + }); + + Services.obs.removeObserver(observer, "http-on-examine-response"); +}); diff --git a/dom/base/test/browser_bug1058164.js b/dom/base/test/browser_bug1058164.js new file mode 100644 index 0000000000..1ee01ca408 --- /dev/null +++ b/dom/base/test/browser_bug1058164.js @@ -0,0 +1,109 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const PAGE = "data:text/html,<html><body>A%20regular,%20everyday,%20normal%20page."; + +/** + * Returns a Promise that resolves when it sees a pageshow and + * pagehide events in a particular order, where each event must + * have the persisted property set to true. Will cause a test + * failure to be logged if it sees an event out of order. + * + * @param browser (<xul:browser>) + * The browser to expect the events from. + * @param expectedOrder (array) + * An array of strings describing what order the pageshow + * and pagehide events should be in. + * Example: + * ["pageshow", "pagehide", "pagehide", "pageshow"] + * @returns Promise + */ +function prepareForVisibilityEvents(browser, expectedOrder) { + return new Promise((resolve) => { + let order = []; + + let checkSatisfied = () => { + if (order.length < expectedOrder.length) { + // We're still waiting... + return; + } else { + browser.removeEventListener("pagehide", eventListener); + browser.removeEventListener("pageshow", eventListener); + + for (let i = 0; i < expectedOrder.length; ++i) { + is(order[i], expectedOrder[i], "Got expected event"); + } + resolve(); + } + }; + + let eventListener = (e) => { + if (e.persisted) { + order.push(e.type); + checkSatisfied(); + } + }; + + browser.addEventListener("pagehide", eventListener); + browser.addEventListener("pageshow", eventListener); + }); +} + +/** + * Tests that frame scripts get pageshow / pagehide events when + * swapping browser frameloaders (which occurs when moving a tab + * into a different window). + */ +add_task(function* test_swap_frameloader_pagevisibility_events() { + // Load a new tab that we'll tear out... + let tab = gBrowser.addTab(PAGE); + gBrowser.selectedTab = tab; + let firstBrowser = tab.linkedBrowser; + yield BrowserTestUtils.browserLoaded(firstBrowser); + + // Swap the browser out to a new window + let newWindow = gBrowser.replaceTabWithWindow(tab); + + // We have to wait for the window to load so we can get the selected browser + // to listen to. + yield BrowserTestUtils.waitForEvent(newWindow, "load"); + let newWindowBrowser = newWindow.gBrowser.selectedBrowser; + + // Wait for the expected pagehide and pageshow events on the initial browser + yield prepareForVisibilityEvents(newWindowBrowser, ["pagehide", "pageshow"]); + + // Now let's send the browser back to the original window + + // First, create a new, empty browser tab to replace the window with + let newTab = gBrowser.addTab(); + gBrowser.selectedTab = newTab; + let emptyBrowser = newTab.linkedBrowser; + + // Wait for that initial browser to show its pageshow event so that we + // don't confuse it with the other expected events. Note that we can't + // use BrowserTestUtils.waitForEvent here because we're using the + // e10s add-on shims in the e10s-case. I'm doing this because I couldn't + // find a way of sending down a frame script to the newly opened windows + // and tabs fast enough to attach the event handlers before they were + // fired. + yield new Promise((resolve) => { + emptyBrowser.addEventListener("pageshow", function onPageShow() { + emptyBrowser.removeEventListener("pageshow", onPageShow); + resolve(); + }); + }); + + // The empty tab we just added show now fire a pagehide as its replaced, + // and a pageshow once the swap is finished. + let emptyBrowserPromise = + prepareForVisibilityEvents(emptyBrowser, ["pagehide", "pageshow"]); + + gBrowser.swapBrowsersAndCloseOther(newTab, newWindow.gBrowser.selectedTab); + + yield emptyBrowserPromise; + + gBrowser.removeTab(gBrowser.selectedTab); +}); diff --git a/dom/base/test/browser_bug1307747.js b/dom/base/test/browser_bug1307747.js new file mode 100644 index 0000000000..8d1448cc23 --- /dev/null +++ b/dom/base/test/browser_bug1307747.js @@ -0,0 +1,32 @@ +/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ + +var {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); + +const BASE_URI = "http://mochi.test:8888/browser/dom/base/test/empty.html"; + +add_task(function* test_initialize() { + let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, BASE_URI); + let browser = gBrowser.getBrowserForTab(tab); + + let blob = yield ContentTask.spawn(browser, null, function() { + let blob = new Blob([new Array(1024*1024).join('123456789ABCDEF')]); + return blob; + }); + + ok(blob, "We have a blob!"); + is(blob.size, new Array(1024*1024).join('123456789ABCDEF').length, "The size matches"); + + let status = yield ContentTask.spawn(browser, blob, function(blob) { + return new Promise(resolve => { + let fr = new content.FileReader(); + fr.readAsText(blob); + fr.onloadend = function() { + resolve(fr.result == new Array(1024*1024).join('123456789ABCDEF')); + } + }); + }); + + ok(status, "Data match!"); + + yield BrowserTestUtils.removeTab(tab); +}); diff --git a/dom/base/test/browser_bug593387.js b/dom/base/test/browser_bug593387.js new file mode 100644 index 0000000000..aa4f9dc0f7 --- /dev/null +++ b/dom/base/test/browser_bug593387.js @@ -0,0 +1,70 @@ +/* + * Test for bug 593387 + * Loads a chrome document in a content docshell and then inserts a + * X-Frame-Options: DENY iframe into the document and verifies that the document + * loads. The policy we are enforcing is outlined here: + * https://bugzilla.mozilla.org/show_bug.cgi?id=593387#c17 +*/ + +add_task(function* test() { + yield BrowserTestUtils.withNewTab({ gBrowser, + url: "chrome://global/content/mozilla.xhtml" }, + function* (newBrowser) { + // NB: We load the chrome:// page in the parent process. + yield testXFOFrameInChrome(newBrowser); + + // Run next test (try the same with a content top-level context) + yield BrowserTestUtils.loadURI(newBrowser, "http://example.com/"); + yield BrowserTestUtils.browserLoaded(newBrowser); + + yield ContentTask.spawn(newBrowser, null, testXFOFrameInContent); + }); +}); + +function testXFOFrameInChrome(newBrowser) { + // Insert an iframe that specifies "X-Frame-Options: DENY" and verify + // that it loads, since the top context is chrome + var deferred = {}; + deferred.promise = new Promise((resolve) => { + deferred.resolve = resolve; + }); + + var frame = newBrowser.contentDocument.createElement("iframe"); + frame.src = "http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny"; + frame.addEventListener("load", function loaded() { + frame.removeEventListener("load", loaded, true); + + // Test that the frame loaded + var test = this.contentDocument.getElementById("test"); + is(test.tagName, "H1", "wrong element type"); + is(test.textContent, "deny", "wrong textContent"); + deferred.resolve(); + }, true); + + newBrowser.contentDocument.body.appendChild(frame); + return deferred.promise; +} + +function testXFOFrameInContent(newBrowser) { + // Insert an iframe that specifies "X-Frame-Options: DENY" and verify that it + // is blocked from loading since the top browsing context is another site + var deferred = {}; + deferred.promise = new Promise((resolve) => { + deferred.resolve = resolve; + }); + + var frame = content.document.createElement("iframe"); + frame.src = "http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny"; + frame.addEventListener("load", function loaded() { + frame.removeEventListener("load", loaded, true); + + // Test that the frame DID NOT load + var test = this.contentDocument.getElementById("test"); + Assert.equal(test, null, "should be about:blank"); + + deferred.resolve(); + }, true); + + content.document.body.appendChild(frame); + return deferred.promise; +} diff --git a/dom/base/test/browser_bug902350.js b/dom/base/test/browser_bug902350.js new file mode 100644 index 0000000000..cce0147798 --- /dev/null +++ b/dom/base/test/browser_bug902350.js @@ -0,0 +1,66 @@ +/* + * Mixed Content Block frame navigates for target="_top" - Test for Bug 902350 + */ + + +const PREF_ACTIVE = "security.mixed_content.block_active_content"; +const gHttpTestRoot = "https://example.com/tests/dom/base/test/"; +var origBlockActive; +var gTestBrowser = null; + +registerCleanupFunction(function() { + // Set preferences back to their original values + Services.prefs.setBoolPref(PREF_ACTIVE, origBlockActive); +}); + +function MixedTestsCompleted() { + gBrowser.removeCurrentTab(); + window.focus(); + finish(); +} + +function test() { + waitForExplicitFinish(); + + origBlockActive = Services.prefs.getBoolPref(PREF_ACTIVE); + + Services.prefs.setBoolPref(PREF_ACTIVE, true); + + var newTab = gBrowser.addTab(); + gBrowser.selectedTab = newTab; + gTestBrowser = gBrowser.selectedBrowser; + newTab.linkedBrowser.stop() + + BrowserTestUtils.browserLoaded(gTestBrowser, true /*includeSubFrames*/).then(MixedTest1A); + var url = gHttpTestRoot + "file_bug902350.html"; + gTestBrowser.loadURI(url); +} + +// Need to capture 2 loads, one for the main page and one for the iframe +function MixedTest1A() { + BrowserTestUtils.browserLoaded(gTestBrowser, true /*includeSubFrames*/).then(MixedTest1B); +} + +// Find the iframe and click the link in it +function MixedTest1B() { + BrowserTestUtils.browserLoaded(gTestBrowser).then(MixedTest1C); + + ContentTask.spawn(gTestBrowser, null, function() { + var frame = content.document.getElementById("testing_frame"); + var topTarget = frame.contentWindow.document.getElementById("topTarget"); + topTarget.click(); + }); + + // The link click should have caused a load and should not invoke the Mixed Content Blocker + let {gIdentityHandler} = gTestBrowser.ownerGlobal; + ok (!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"), + "Mixed Content Doorhanger did not appear when trying to navigate top"); +} + +function MixedTest1C() { + ContentTask.spawn(gTestBrowser, null, function() { + Assert.equal(content.location.href, "http://example.com/", + "Navigating to insecure domain through target='_top' failed.") + }).then(MixedTestsCompleted); +} + diff --git a/dom/base/test/browser_messagemanager_loadprocessscript.js b/dom/base/test/browser_messagemanager_loadprocessscript.js new file mode 100644 index 0000000000..feabfb43c6 --- /dev/null +++ b/dom/base/test/browser_messagemanager_loadprocessscript.js @@ -0,0 +1,114 @@ +var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"] + .getService(Ci.nsIMessageBroadcaster); +ppmm.QueryInterface(Ci.nsIProcessScriptLoader); + +function processScript() { + let cpmm = Components.classes["@mozilla.org/childprocessmessagemanager;1"] + .getService(Components.interfaces.nsISyncMessageSender); + if (cpmm !== this) { + dump("Test failed: wrong global object\n"); + return; + } + + this.cpmm = cpmm; + + addMessageListener("ProcessTest:Reply", function listener(msg) { + removeMessageListener("ProcessTest:Reply", listener); + sendAsyncMessage("ProcessTest:Finished"); + }); + sendSyncMessage("ProcessTest:Loaded"); +} +var processScriptURL = "data:,(" + processScript.toString() + ")()"; + +function initTestScript() { + let init = initialProcessData; + if (init.test123 != "hello") { + dump("Initial data incorrect\n"); + return; + } + + sendAsyncMessage("ProcessTest:InitGood", init.test456.get("hi")); +} +var initTestScriptURL = "data:,(" + initTestScript.toString() + ")()"; + +var checkProcess = Task.async(function*(mm) { + let { target } = yield promiseMessage(mm, "ProcessTest:Loaded"); + target.sendAsyncMessage("ProcessTest:Reply"); + yield promiseMessage(target, "ProcessTest:Finished"); + ok(true, "Saw process finished"); +}); + +function promiseMessage(messageManager, message) { + return new Promise(resolve => { + let listener = (msg) => { + messageManager.removeMessageListener(message, listener); + resolve(msg); + }; + + messageManager.addMessageListener(message, listener); + }) +} + +// Test that loading a process script loads in all existing processes +add_task(function*() { + let checks = []; + for (let i = 0; i < ppmm.childCount; i++) + checks.push(checkProcess(ppmm.getChildAt(i))); + + ppmm.loadProcessScript(processScriptURL, false); + yield Promise.all(checks); +}); + +// Test that loading a process script loads in new processes +add_task(function*() { + // This test is only relevant in e10s + if (!gMultiProcessBrowser) + return; + + is(ppmm.childCount, 2, "Should be two processes at this point"); + + // Load something in the main process + gBrowser.selectedBrowser.loadURI("about:robots"); + yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + + let init = ppmm.initialProcessData; + init.test123 = "hello"; + init.test456 = new Map(); + init.test456.set("hi", "bye"); + + // With no remote frames left we should be down to one process. + // However, stuff like remote thumbnails can cause a content + // process to exist nonetheless. This should be rare, though, + // so the test is useful most of the time. + if (ppmm.childCount == 1) { + let mainMM = ppmm.getChildAt(0); + + let check = checkProcess(ppmm); + ppmm.loadProcessScript(processScriptURL, true); + + // The main process should respond + yield check; + + check = checkProcess(ppmm); + // Reset the default browser to start a new child process + gBrowser.updateBrowserRemoteness(gBrowser.selectedBrowser, true); + gBrowser.selectedBrowser.loadURI("about:blank"); + yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser); + + is(ppmm.childCount, 2, "Should be back to two processes at this point"); + + // The new process should have responded + yield check; + + ppmm.removeDelayedProcessScript(processScriptURL); + + let childMM; + childMM = ppmm.getChildAt(0) == mainMM ? ppmm.getChildAt(1) : ppmm.getChildAt(0); + + childMM.loadProcessScript(initTestScriptURL, false); + let msg = yield promiseMessage(childMM, "ProcessTest:InitGood"); + is(msg.data, "bye", "initial process data was correct"); + } else { + info("Unable to finish test entirely"); + } +}); diff --git a/dom/base/test/browser_messagemanager_targetframeloader.js b/dom/base/test/browser_messagemanager_targetframeloader.js new file mode 100644 index 0000000000..32575d0738 --- /dev/null +++ b/dom/base/test/browser_messagemanager_targetframeloader.js @@ -0,0 +1,31 @@ +function frameScript() +{ + sendSyncMessage("Test:Message"); + sendAsyncMessage("Test:Message"); + sendAsyncMessage("Test:Done"); +} + +function test() { + waitForExplicitFinish(); + + var newTab = gBrowser.addTab("about:blank"); + gBrowser.selectedTab = newTab; + + let browser = newTab.linkedBrowser; + let frameLoader = browser.frameLoader; + ok(frameLoader !== null, "frameLoader looks okay"); + + browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false); + + browser.messageManager.addMessageListener("Test:Message", (msg) => { + ok(msg.target === browser, "<browser> is correct"); + ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct"); + ok(browser.frameLoader === msg.targetFrameLoader, "browser frameloader is correct"); + }); + + browser.messageManager.addMessageListener("Test:Done", () => { + info("Finished"); + gBrowser.removeCurrentTab(); + finish(); + }); +} diff --git a/dom/base/test/browser_messagemanager_unload.js b/dom/base/test/browser_messagemanager_unload.js new file mode 100644 index 0000000000..413e384932 --- /dev/null +++ b/dom/base/test/browser_messagemanager_unload.js @@ -0,0 +1,102 @@ +function frameScript() +{ + Components.utils.import("resource://gre/modules/Services.jsm"); + + function eventHandler(e) { + if (!docShell) { + sendAsyncMessage("Test:Fail", "docShell is null"); + } + + sendAsyncMessage("Test:Event", [e.type, e.target === content.document, e.eventPhase]); + } + + let outerID = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor). + getInterface(Components.interfaces.nsIDOMWindowUtils).outerWindowID; + function onOuterWindowDestroyed(subject, topic, data) { + if (docShell) { + sendAsyncMessage("Test:Fail", "docShell is non-null"); + } + + let id = subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data; + sendAsyncMessage("Test:Event", ["outer-window-destroyed", id == outerID]); + if (id == outerID) { + Services.obs.removeObserver(onOuterWindowDestroyed, "outer-window-destroyed"); + } + } + + let url = "https://example.com/browser/dom/base/test/file_messagemanager_unload.html"; + + content.location = url; + addEventListener("load", (e) => { + if (e.target.location != url) { + return; + } + + addEventListener("unload", eventHandler, false); + addEventListener("unload", eventHandler, true); + addEventListener("pagehide", eventHandler, false); + addEventListener("pagehide", eventHandler, true); + Services.obs.addObserver(onOuterWindowDestroyed, "outer-window-destroyed", false); + + sendAsyncMessage("Test:Ready"); + }, true); +} + +const EXPECTED = [ + // Unload events on the TabChildGlobal. These come first so that the + // docshell is available. + ["unload", false, 2], + ["unload", false, 2], + + // pagehide and unload events for the top-level page. + ["pagehide", true, 1], + ["pagehide", true, 3], + ["unload", true, 1], + + // pagehide and unload events for the iframe. + ["pagehide", false, 1], + ["pagehide", false, 3], + ["unload", false, 1], + + // outer-window-destroyed for both pages. + ["outer-window-destroyed", false], + ["outer-window-destroyed", true], +]; + +function test() { + waitForExplicitFinish(); + + var newTab = gBrowser.addTab("about:blank"); + gBrowser.selectedTab = newTab; + + let browser = newTab.linkedBrowser; + let frameLoader = browser.frameLoader; + ok(frameLoader !== null, "frameLoader looks okay"); + + browser.messageManager.loadFrameScript("data:,(" + frameScript.toString() + ")()", false); + + browser.messageManager.addMessageListener("Test:Fail", (msg) => { + ok(false, msg.data); + }, true); + + let index = 0; + browser.messageManager.addMessageListener("Test:Event", (msg) => { + ok(msg.target === browser, "<browser> is correct"); + ok(msg.targetFrameLoader === frameLoader, "frameLoader is correct"); + ok(browser.frameLoader === null, "browser frameloader null during teardown"); + + info(JSON.stringify(msg.data)); + + is(JSON.stringify(msg.data), JSON.stringify(EXPECTED[index]), "results match"); + index++; + + if (index == EXPECTED.length) { + finish(); + } + }, true); + + browser.messageManager.addMessageListener("Test:Ready", () => { + info("Got ready message"); + gBrowser.removeCurrentTab(); + }); +} diff --git a/dom/base/test/browser_pagehide_on_tab_close.js b/dom/base/test/browser_pagehide_on_tab_close.js new file mode 100644 index 0000000000..0da7617e16 --- /dev/null +++ b/dom/base/test/browser_pagehide_on_tab_close.js @@ -0,0 +1,17 @@ +function test() { + waitForExplicitFinish(); + + var tab = gBrowser.addTab(); + gBrowser.selectedTab = tab; + + tab.linkedBrowser.addEventListener("load", function onload() { + tab.linkedBrowser.removeEventListener("load", onload); + + tab.linkedBrowser.addEventListener("pagehide", function() { + ok(true, "got page hide event"); + finish(); + }); + + executeSoon(() => { gBrowser.removeTab(tab); }); + }, true); +} diff --git a/dom/base/test/browser_state_notifications.js b/dom/base/test/browser_state_notifications.js new file mode 100644 index 0000000000..3279acb39a --- /dev/null +++ b/dom/base/test/browser_state_notifications.js @@ -0,0 +1,189 @@ +/* globals Components: true, Promise: true, gBrowser: true, Test: true, + info: true, is: true, window: true, waitForExplicitFinish: true, + finish: true, ok: true*/ + +"use strict"; + +var { interfaces: Ci, classes: Cc, utils: Cu } = Components; +const { addObserver, removeObserver } = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); +const { openWindow } = Cc["@mozilla.org/embedcomp/window-watcher;1"]. + getService(Ci.nsIWindowWatcher); + +const Test = routine => () => { + waitForExplicitFinish(); + Task.spawn(routine) + .then(finish, error => { + ok(false, error); + finish(); + }); +}; + +// Returns promise for the observer notification subject for +// the given topic. If `receive("foo")` is called `n` times +// nth promise is resolved on an `nth` "foo" notification. +const receive = (topic, p, syncCallback) => { + const { promise, resolve, reject } = Promise.defer(); + const { queue } = receive; + const timeout = () => { + queue.splice(queue.indexOf(resolve) - 1, 2); + reject(new Error("Timeout")); + }; + + const observer = { + observe: subject => { + // Browser loads bunch of other documents that we don't care + // about so we let allow filtering notifications via `p` function. + if (p && !p(subject)) return; + // If observer is a first one with a given `topic` + // in a queue resolve promise and take it off the queue + // otherwise keep waiting. + const index = queue.indexOf(topic); + if (queue.indexOf(resolve) === index + 1) { + removeObserver(observer, topic); + clearTimeout(id, reject); + queue.splice(index, 2); + // Some tests need to be executed synchronously when the event is fired. + if (syncCallback) { + syncCallback(subject); + } + resolve(subject); + } + } + }; + const id = setTimeout(timeout, 90000); + addObserver(observer, topic, false); + queue.push(topic, resolve); + + return promise; +}; +receive.queue = []; + +const openTab = uri => gBrowser.selectedTab = gBrowser.addTab(uri); + +const sleep = ms => { + const { promise, resolve } = Promise.defer(); + setTimeout(resolve, ms); + return promise; +}; + +const isData = document => document.URL.startsWith("data:"); + +const uri1 = "data:text/html;charset=utf-8,<h1>1</h1>"; +// For whatever reason going back on load event doesn't work so timeout it is :( +const uri2 = "data:text/html;charset=utf-8,<h1>2</h1><script>setTimeout(SpecialPowers.wrap(window).back,100)</script>"; +const uri3 = "data:text/html;charset=utf-8,<h1>3</h1>"; + +const uri4 = "chrome://browser/content/license.html"; + +const test = Test(function*() { + let documentInteractive = receive("content-document-interactive", isData, d => { + // This test is executed synchronously when the event is received. + is(d.readyState, "interactive", "document is interactive"); + is(d.URL, uri1, "document.URL matches tab url"); + }); + let documentLoaded = receive("content-document-loaded", isData); + let pageShown = receive("content-page-shown", isData); + + info("open: uri#1"); + const tab1 = openTab(uri1); + const browser1 = gBrowser.getBrowserForTab(tab1); + + let interactiveDocument1 = yield documentInteractive; + + let loadedDocument1 = yield documentLoaded; + is(loadedDocument1.readyState, "complete", "document is loaded"); + is(interactiveDocument1, loadedDocument1, "interactive document is loaded"); + + let shownPage = yield pageShown; + is(interactiveDocument1, shownPage, "loaded document is shown"); + + // Wait until history entry is created before loading new uri. + yield receive("sessionstore-state-write-complete"); + + info("load uri#2"); + + documentInteractive = receive("content-document-interactive", isData, d => { + // This test is executed synchronously when the event is received. + is(d.readyState, "interactive", "document is interactive"); + is(d.URL, uri2, "document.URL matches URL loaded"); + }); + documentLoaded = receive("content-document-loaded", isData); + pageShown = receive("content-page-shown", isData); + let pageHidden = receive("content-page-hidden", isData); + + browser1.loadURI(uri2); + + let hiddenPage = yield pageHidden; + is(interactiveDocument1, hiddenPage, "loaded document is hidden"); + + let interactiveDocument2 = yield documentInteractive; + + let loadedDocument2 = yield documentLoaded; + is(loadedDocument2.readyState, "complete", "document is loaded"); + is(interactiveDocument2, loadedDocument2, "interactive document is loaded"); + + shownPage = yield pageShown; + is(interactiveDocument2, shownPage, "loaded document is shown"); + + info("go back to uri#1"); + + + documentInteractive = receive("content-document-interactive", isData, d => { + // This test is executed synchronously when the event is received. + is(d.readyState, "interactive", "document is interactive"); + is(d.URL, uri3, "document.URL matches URL loaded"); + }); + documentLoaded = receive("content-document-loaded", isData); + pageShown = receive("content-page-shown", isData); + pageHidden = receive("content-page-hidden", isData); + + hiddenPage = yield pageHidden; + is(interactiveDocument2, hiddenPage, "new document is hidden"); + + shownPage = yield pageShown; + is(interactiveDocument1, shownPage, "previous document is shown"); + + info("load uri#3"); + + browser1.loadURI(uri3); + + pageShown = receive("content-page-shown", isData); + + let interactiveDocument3 = yield documentInteractive; + + let loadedDocument3 = yield documentLoaded; + is(loadedDocument3.readyState, "complete", "document is loaded"); + is(interactiveDocument3, loadedDocument3, "interactive document is loaded"); + + shownPage = yield pageShown; + is(interactiveDocument3, shownPage, "previous document is shown"); + + gBrowser.removeTab(tab1); + + info("load chrome uri"); + + const tab2 = openTab(uri4); + documentInteractive = receive("chrome-document-interactive", null, d => { + // This test is executed synchronously when the event is received. + is(d.readyState, "interactive", "document is interactive"); + is(d.URL, uri4, "document.URL matches URL loaded"); + }); + documentLoaded = receive("chrome-document-loaded"); + pageShown = receive("chrome-page-shown"); + + const interactiveDocument4 = yield documentInteractive; + + let loadedDocument4 = yield documentLoaded; + is(loadedDocument4.readyState, "complete", "document is loaded"); + is(interactiveDocument4, loadedDocument4, "interactive document is loaded"); + + shownPage = yield pageShown; + is(interactiveDocument4, shownPage, "loaded chrome document is shown"); + + pageHidden = receive("chrome-page-hidden"); + gBrowser.removeTab(tab2); + + hiddenPage = yield pageHidden; + is(interactiveDocument4, hiddenPage, "chrome document hidden"); +}); diff --git a/dom/base/test/browser_use_counters.js b/dom/base/test/browser_use_counters.js new file mode 100644 index 0000000000..68bd04f880 --- /dev/null +++ b/dom/base/test/browser_use_counters.js @@ -0,0 +1,305 @@ +/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */ + +requestLongerTimeout(2); + +var {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {}); +Cu.import("resource://gre/modules/Services.jsm"); + +const gHttpTestRoot = "http://example.com/browser/dom/base/test/"; + +/** + * Enable local telemetry recording for the duration of the tests. + */ +var gOldContentCanRecord = false; +var gOldParentCanRecord = false; +add_task(function* test_initialize() { + let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); + gOldParentCanRecord = Telemetry.canRecordExtended + Telemetry.canRecordExtended = true; + + // Because canRecordExtended is a per-process variable, we need to make sure + // that all of the pages load in the same content process. Limit the number + // of content processes to at most 1 (or 0 if e10s is off entirely). + yield SpecialPowers.pushPrefEnv({ set: [[ "dom.ipc.processCount", 1 ]] }); + + gOldContentCanRecord = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () { + let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); + let old = telemetry.canRecordExtended; + telemetry.canRecordExtended = true; + return old; + }); + info("canRecord for content: " + gOldContentCanRecord); +}); + +add_task(function* () { + // Check that use counters are incremented by SVGs loaded directly in iframes. + yield check_use_counter_iframe("file_use_counter_svg_getElementById.svg", + "SVGSVGELEMENT_GETELEMENTBYID"); + yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg", + "SVGSVGELEMENT_CURRENTSCALE_getter"); + yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg", + "SVGSVGELEMENT_CURRENTSCALE_setter"); + + // Check that even loads from the imglib cache update use counters. The + // images should still be there, because we just loaded them in the last + // set of tests. But we won't get updated counts for the document + // counters, because we won't be re-parsing the SVG documents. + yield check_use_counter_iframe("file_use_counter_svg_getElementById.svg", + "SVGSVGELEMENT_GETELEMENTBYID", false); + yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg", + "SVGSVGELEMENT_CURRENTSCALE_getter", false); + yield check_use_counter_iframe("file_use_counter_svg_currentScale.svg", + "SVGSVGELEMENT_CURRENTSCALE_setter", false); + + // Check that use counters are incremented by SVGs loaded as images. + // Note that SVG images are not permitted to execute script, so we can only + // check for properties here. + yield check_use_counter_img("file_use_counter_svg_getElementById.svg", + "PROPERTY_FILL"); + yield check_use_counter_img("file_use_counter_svg_currentScale.svg", + "PROPERTY_FILL"); + + // Check that use counters are incremented by directly loading SVGs + // that reference patterns defined in another SVG file. + yield check_use_counter_direct("file_use_counter_svg_fill_pattern.svg", + "PROPERTY_FILLOPACITY", /*xfail=*/true); + + // Check that use counters are incremented by directly loading SVGs + // that reference patterns defined in the same file or in data: URLs. + yield check_use_counter_direct("file_use_counter_svg_fill_pattern_internal.svg", + "PROPERTY_FILLOPACITY"); + // data: URLs don't correctly propagate to their referring document yet. + //yield check_use_counter_direct("file_use_counter_svg_fill_pattern_data.svg", + // "PROPERTY_FILL_OPACITY"); +}); + +add_task(function* () { + let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); + Telemetry.canRecordExtended = gOldParentCanRecord; + + yield ContentTask.spawn(gBrowser.selectedBrowser, { oldCanRecord: gOldContentCanRecord }, function (arg) { + Cu.import("resource://gre/modules/PromiseUtils.jsm"); + yield new Promise(resolve => { + let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); + telemetry.canRecordExtended = arg.oldCanRecord; + resolve(); + }); + }); +}); + + +function waitForDestroyedDocuments() { + let deferred = promise.defer(); + SpecialPowers.exactGC(deferred.resolve); + return deferred.promise; +} + +function waitForPageLoad(browser) { + return ContentTask.spawn(browser, null, function*() { + Cu.import("resource://gre/modules/PromiseUtils.jsm"); + yield new Promise(resolve => { + let listener = () => { + removeEventListener("load", listener, true); + resolve(); + } + addEventListener("load", listener, true); + }); + }); +} + +function grabHistogramsFromContent(use_counter_middlefix, page_before = null) { + let telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); + let suffix = Services.appinfo.browserTabsRemoteAutostart ? "#content" : ""; + let gather = () => [ + telemetry.getHistogramById("USE_COUNTER2_" + use_counter_middlefix + "_PAGE" + suffix).snapshot().sum, + telemetry.getHistogramById("USE_COUNTER2_" + use_counter_middlefix + "_DOCUMENT" + suffix).snapshot().sum, + telemetry.getHistogramById("CONTENT_DOCUMENTS_DESTROYED" + suffix).snapshot().sum, + telemetry.getHistogramById("TOP_LEVEL_CONTENT_DOCUMENTS_DESTROYED" + suffix).snapshot().sum, + ]; + return BrowserTestUtils.waitForCondition(() => { + return page_before != telemetry.getHistogramById("USE_COUNTER2_" + use_counter_middlefix + "_PAGE" + suffix).snapshot().sum; + }).then(gather, gather); +} + +var check_use_counter_iframe = Task.async(function* (file, use_counter_middlefix, check_documents=true) { + info("checking " + file + " with histogram " + use_counter_middlefix); + + let newTab = gBrowser.addTab( "about:blank"); + gBrowser.selectedTab = newTab; + newTab.linkedBrowser.stop(); + + // Hold on to the current values of the telemetry histograms we're + // interested in. + let [histogram_page_before, histogram_document_before, + histogram_docs_before, histogram_toplevel_docs_before] = + yield grabHistogramsFromContent(use_counter_middlefix); + + gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html"); + yield waitForPageLoad(gBrowser.selectedBrowser); + + // Inject our desired file into the iframe of the newly-loaded page. + yield ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) { + Cu.import("resource://gre/modules/PromiseUtils.jsm"); + let deferred = PromiseUtils.defer(); + + let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); + + let iframe = content.document.getElementById('content'); + iframe.src = opts.file; + let listener = (event) => { + event.target.removeEventListener("load", listener, true); + + // We flush the main document first, then the iframe's document to + // ensure any propagation that might happen from content->parent should + // have already happened when counters are reported to telemetry. + wu.forceUseCounterFlush(content.document); + wu.forceUseCounterFlush(iframe.contentDocument); + + deferred.resolve(); + }; + iframe.addEventListener("load", listener, true); + + return deferred.promise; + }); + + // Tear down the page. + gBrowser.removeTab(newTab); + + // The histograms only get recorded when the document actually gets + // destroyed, which might not have happened yet due to GC/CC effects, etc. + // Try to force document destruction. + yield waitForDestroyedDocuments(); + + // Grab histograms again and compare. + let [histogram_page_after, histogram_document_after, + histogram_docs_after, histogram_toplevel_docs_after] = + yield grabHistogramsFromContent(use_counter_middlefix, histogram_page_before); + + is(histogram_page_after, histogram_page_before + 1, + "page counts for " + use_counter_middlefix + " after are correct"); + ok(histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1, + "top level document counts are correct"); + if (check_documents) { + is(histogram_document_after, histogram_document_before + 1, + "document counts for " + use_counter_middlefix + " after are correct"); + } +}); + +var check_use_counter_img = Task.async(function* (file, use_counter_middlefix) { + info("checking " + file + " as image with histogram " + use_counter_middlefix); + + let newTab = gBrowser.addTab("about:blank"); + gBrowser.selectedTab = newTab; + newTab.linkedBrowser.stop(); + + // Hold on to the current values of the telemetry histograms we're + // interested in. + let [histogram_page_before, histogram_document_before, + histogram_docs_before, histogram_toplevel_docs_before] = + yield grabHistogramsFromContent(use_counter_middlefix); + + gBrowser.selectedBrowser.loadURI(gHttpTestRoot + "file_use_counter_outer.html"); + yield waitForPageLoad(gBrowser.selectedBrowser); + + // Inject our desired file into the img of the newly-loaded page. + yield ContentTask.spawn(gBrowser.selectedBrowser, { file: file }, function(opts) { + Cu.import("resource://gre/modules/PromiseUtils.jsm"); + let deferred = PromiseUtils.defer(); + + let img = content.document.getElementById('display'); + img.src = opts.file; + let listener = (event) => { + img.removeEventListener("load", listener, true); + + // Flush for the image. It matters what order we do these in, so that + // the image can propagate its use counters to the document prior to the + // document reporting its use counters. + let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); + wu.forceUseCounterFlush(img); + + // Flush for the main window. + wu.forceUseCounterFlush(content.document); + + deferred.resolve(); + }; + img.addEventListener("load", listener, true); + + return deferred.promise; + }); + + // Tear down the page. + gBrowser.removeTab(newTab); + + // The histograms only get recorded when the document actually gets + // destroyed, which might not have happened yet due to GC/CC effects, etc. + // Try to force document destruction. + yield waitForDestroyedDocuments(); + + // Grab histograms again and compare. + let [histogram_page_after, histogram_document_after, + histogram_docs_after, histogram_toplevel_docs_after] = + yield grabHistogramsFromContent(use_counter_middlefix, histogram_page_before); + is(histogram_page_after, histogram_page_before + 1, + "page counts for " + use_counter_middlefix + " after are correct"); + is(histogram_document_after, histogram_document_before + 1, + "document counts for " + use_counter_middlefix + " after are correct"); + ok(histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1, + "top level document counts are correct"); + // 2 documents: one for the outer html page containing the <img> element, and + // one for the SVG image itself. + ok(histogram_docs_after >= histogram_docs_before + 2, + "document counts are correct"); +}); + +var check_use_counter_direct = Task.async(function* (file, use_counter_middlefix, xfail=false) { + info("checking " + file + " with histogram " + use_counter_middlefix); + + let newTab = gBrowser.addTab( "about:blank"); + gBrowser.selectedTab = newTab; + newTab.linkedBrowser.stop(); + + // Hold on to the current values of the telemetry histograms we're + // interested in. + let [histogram_page_before, histogram_document_before, + histogram_docs_before, histogram_toplevel_docs_before] = + yield grabHistogramsFromContent(use_counter_middlefix); + + gBrowser.selectedBrowser.loadURI(gHttpTestRoot + file); + yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() { + Cu.import("resource://gre/modules/PromiseUtils.jsm"); + yield new Promise(resolve => { + let listener = () => { + removeEventListener("load", listener, true); + + let wu = content.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); + wu.forceUseCounterFlush(content.document); + + setTimeout(resolve, 0); + } + addEventListener("load", listener, true); + }); + }); + + // Tear down the page. + gBrowser.removeTab(newTab); + + // The histograms only get recorded when the document actually gets + // destroyed, which might not have happened yet due to GC/CC effects, etc. + // Try to force document destruction. + yield waitForDestroyedDocuments(); + + // Grab histograms again and compare. + let [histogram_page_after, histogram_document_after, + histogram_docs_after, histogram_toplevel_docs_after] = + yield grabHistogramsFromContent(use_counter_middlefix, histogram_page_before); + if (!xfail) { + is(histogram_page_after, histogram_page_before + 1, + "page counts for " + use_counter_middlefix + " after are correct"); + is(histogram_document_after, histogram_document_before + 1, + "document counts for " + use_counter_middlefix + " after are correct"); + } + ok(histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1, + "top level document counts are correct"); + ok(histogram_docs_after >= histogram_docs_before + 1, + "document counts are correct"); +}); diff --git a/dom/base/test/bug282547.sjs b/dom/base/test/bug282547.sjs new file mode 100644 index 0000000000..8476a61724 --- /dev/null +++ b/dom/base/test/bug282547.sjs @@ -0,0 +1,9 @@ +function handleRequest(request, response) +{ + response.setStatusLine(null, 401, "Unauthorized"); + + response.setHeader("WWW-Authenticate", "basic realm=\"restricted\"", false); + + response.setHeader("Access-Control-Allow-Origin", "*", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); +} diff --git a/dom/base/test/bug298064-subframe.html b/dom/base/test/bug298064-subframe.html new file mode 100644 index 0000000000..af497f5905 --- /dev/null +++ b/dom/base/test/bug298064-subframe.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> + <head> + <script> + function test_func() { + var bar = new Option(); + parent.is(bar.ownerDocument, document, + "Unexpected document for our new option"); + bar = new Image(); + parent.is(bar.ownerDocument, document, + "Unexpected document for our new image"); + bar = new parent.Option(); + parent.is(bar.ownerDocument, parent.document, + "Unexpected document for parent new option"); + bar = new parent.Image(); + parent.is(bar.ownerDocument, parent.document, + "Unexpected document for parent new image"); + parent.isnot(parent.document, document, "Documents should be different"); + } + </script> + </head> +<html> + + diff --git a/dom/base/test/bug313646.txt b/dom/base/test/bug313646.txt new file mode 100644 index 0000000000..150f5ea6d1 --- /dev/null +++ b/dom/base/test/bug313646.txt @@ -0,0 +1 @@ +Nothing to see here. Just need to request this file via XHR. diff --git a/dom/base/test/bug382113_object.html b/dom/base/test/bug382113_object.html new file mode 100644 index 0000000000..935f00afd1 --- /dev/null +++ b/dom/base/test/bug382113_object.html @@ -0,0 +1,6 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<title></title> +<body onload="parent.childGotOnload = true;"> + <p>A Document in an <object></p> +</body> + diff --git a/dom/base/test/bug403852_fileOpener.js b/dom/base/test/bug403852_fileOpener.js new file mode 100644 index 0000000000..5e3b4936ac --- /dev/null +++ b/dom/base/test/bug403852_fileOpener.js @@ -0,0 +1,17 @@ +var { classes: Cc, interfaces: Ci, utils: Cu } = Components; +Cu.importGlobalProperties(["File"]); + +var testFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIDirectoryService) + .QueryInterface(Ci.nsIProperties) + .get("ProfD", Ci.nsIFile); +testFile.append("prefs.js"); + +addMessageListener("file.open", function () { + sendAsyncMessage("file.opened", { + file: File.createFromNsIFile(testFile), + mtime: testFile.lastModifiedTime, + fileWithDate: File.createFromNsIFile(testFile, { lastModified: 123 }), + fileDate: 123, + }); +}); diff --git a/dom/base/test/bug419132.html b/dom/base/test/bug419132.html new file mode 100644 index 0000000000..ab2934c2d4 --- /dev/null +++ b/dom/base/test/bug419132.html @@ -0,0 +1,22 @@ +<html><head> +</head><body> +<span> +<span id="a" tabindex="1"> +<span> + +<select> +<script> +document.getElementById('a').focus(); +</script> +</select> + +<style> +#a:focus { float:right;} +body *:first-child {-moz-binding:url(data:text/xml;charset=utf-8,%3Cbindings%20xmlns%3D%22http%3A//www.mozilla.org/xbl%22%3E%0A%3Cbinding%20id%3D%22a%22%20inheritstyle%3D%22false%22%3E%0A%3Ccontent%3E%0A%3Cchildren/%3E%0A%3Cinput%20xmlns%3D%22http%3A//www.w3.org/1999/xhtml%22%20style%3D%22display%3A%20table%3B%20overflow%3A%20hidden%3B%22%20/%3E%0A%3C/content%3E%0A%3C/binding%3E%0A%3C/bindings%3E); +</style> + +</span> +</span> +</span> +</body> +</html> diff --git a/dom/base/test/bug426308-redirect.sjs b/dom/base/test/bug426308-redirect.sjs new file mode 100644 index 0000000000..331f31d96a --- /dev/null +++ b/dom/base/test/bug426308-redirect.sjs @@ -0,0 +1,4 @@ +function handleRequest(request, response) { + response.setStatusLine(null, 302, "Found"); + response.setHeader("Location", request.queryString, false); +} diff --git a/dom/base/test/bug435425.sjs b/dom/base/test/bug435425.sjs new file mode 100644 index 0000000000..3ef8c656ac --- /dev/null +++ b/dom/base/test/bug435425.sjs @@ -0,0 +1,24 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/plain", false); + if (request.method == "GET") { + response.write(request.queryString); + } else { + var body = new BinaryInputStream(request.bodyInputStream); + + var avail; + var bytes = []; + + while ((avail = body.available()) > 0) + Array.prototype.push.apply(bytes, body.readByteArray(avail)); + + var data = String.fromCharCode.apply(null, bytes); + response.bodyOutputStream.write(data, data.length); + } +} + diff --git a/dom/base/test/bug435425_redirect.sjs b/dom/base/test/bug435425_redirect.sjs new file mode 100644 index 0000000000..e8c8f2aa4a --- /dev/null +++ b/dom/base/test/bug435425_redirect.sjs @@ -0,0 +1,6 @@ +function handleRequest(request, response) +{ + response.setStatusLine(null, 302, "Moved"); + response.setHeader("Location", "http://nosuchdomain.localhost", false); +} + diff --git a/dom/base/test/bug444322.js b/dom/base/test/bug444322.js new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/dom/base/test/bug444322.js diff --git a/dom/base/test/bug444322.txt b/dom/base/test/bug444322.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/dom/base/test/bug444322.txt diff --git a/dom/base/test/bug444546.sjs b/dom/base/test/bug444546.sjs new file mode 100644 index 0000000000..b98588d402 --- /dev/null +++ b/dom/base/test/bug444546.sjs @@ -0,0 +1,20 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/plain", false); + + var body = new BinaryInputStream(request.bodyInputStream); + + var avail; + var bytes = []; + while ((avail = body.available()) > 0) + Array.prototype.push.apply(bytes, body.readByteArray(avail)); + + var data = String.fromCharCode.apply(null, bytes); + response.bodyOutputStream.write(data, data.length); +} + diff --git a/dom/base/test/bug455629-helper.svg b/dom/base/test/bug455629-helper.svg new file mode 100644 index 0000000000..38098585ed --- /dev/null +++ b/dom/base/test/bug455629-helper.svg @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<svg xmlns="http://www.w3.org/2000/svg"> + <g transform="scale(0.5)"> + <foreignObject id="f" width="100" height="100"/> + </g> +</svg> diff --git a/dom/base/test/bug457746.sjs b/dom/base/test/bug457746.sjs new file mode 100644 index 0000000000..d014df2cee --- /dev/null +++ b/dom/base/test/bug457746.sjs @@ -0,0 +1,11 @@ +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/plain; charset=ISO-8859-1", false); + const body = [0xC1]; + var bos = Components.classes["@mozilla.org/binaryoutputstream;1"] + .createInstance(Components.interfaces.nsIBinaryOutputStream); + bos.setOutputStream(response.bodyOutputStream); + + bos.writeByteArray(body, body.length); +} + diff --git a/dom/base/test/bug461735-post-redirect.js b/dom/base/test/bug461735-post-redirect.js new file mode 100644 index 0000000000..bae1963d3c --- /dev/null +++ b/dom/base/test/bug461735-post-redirect.js @@ -0,0 +1,3 @@ +var a = 0; +var b = 0; +c();
\ No newline at end of file diff --git a/dom/base/test/bug461735-redirect1.sjs b/dom/base/test/bug461735-redirect1.sjs new file mode 100644 index 0000000000..a31eb066a3 --- /dev/null +++ b/dom/base/test/bug461735-redirect1.sjs @@ -0,0 +1,4 @@ +function handleRequest(request, response) { + response.setStatusLine(null, 302, "Found"); + response.setHeader("Location", "http://example.com/tests/dom/base/test/bug461735-post-redirect.js", false); +} diff --git a/dom/base/test/bug461735-redirect2.sjs b/dom/base/test/bug461735-redirect2.sjs new file mode 100644 index 0000000000..cfd9299785 --- /dev/null +++ b/dom/base/test/bug461735-redirect2.sjs @@ -0,0 +1,4 @@ +function handleRequest(request, response) { + response.setStatusLine(null, 302, "Found"); + response.setHeader("Location", "http://mochi.test:8888/tests/dom/base/test/bug461735-post-redirect.js", false); +} diff --git a/dom/base/test/bug466080.sjs b/dom/base/test/bug466080.sjs new file mode 100644 index 0000000000..0d7c089b70 --- /dev/null +++ b/dom/base/test/bug466080.sjs @@ -0,0 +1,17 @@ + +function handleRequest(request, response) +{ + var body = "loaded"; + var origin = "localhost"; + try { + var origin = request.getHeader("Origin"); + } catch(e) {} + + response.setHeader("Access-Control-Allow-Origin", + origin, + false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.setHeader("Connection", "Keep-alive", false); + + response.bodyOutputStream.write(body, body.length); +} diff --git a/dom/base/test/bug466409-empty.css b/dom/base/test/bug466409-empty.css new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/dom/base/test/bug466409-empty.css diff --git a/dom/base/test/bug466409-page.html b/dom/base/test/bug466409-page.html new file mode 100644 index 0000000000..69ce7c2272 --- /dev/null +++ b/dom/base/test/bug466409-page.html @@ -0,0 +1,12 @@ +<html> + <head> + <link rel="stylesheet" type="text/css" href="bug466409-empty.css"> + <title>Bug</title> + <SCRIPT LANGUAGE="JavaScript"> + document.write("Hello, world!"); + </SCRIPT> + </head> + <body> + + </body> +</html> diff --git a/dom/base/test/bug475156.sjs b/dom/base/test/bug475156.sjs new file mode 100644 index 0000000000..e648636160 --- /dev/null +++ b/dom/base/test/bug475156.sjs @@ -0,0 +1,27 @@ +function handleRequest(request, response) +{ + if (request.queryString == "") + { + var etag = request.hasHeader("If-Match") ? request.getHeader("If-Match") : null; + if (!etag || etag == getState("etag")) + { + response.setStatusLine(request.httpVersion, 200, "Ok"); + response.setHeader("Content-Type", "text/html"); + response.setHeader("ETag", getState("etag")); + response.setHeader("Cache-control", "max-age=36000"); + response.write(getState("etag")); + } + else if (etag) + { + response.setStatusLine(request.httpVersion, 412, "Precondition Failed"); + } + } + else + { + var etag = request.queryString.match(/^etag=(.*)$/); + if (etag) + setState("etag", etag[1]); + + response.setStatusLine(request.httpVersion, 204, "No content"); + } +} diff --git a/dom/base/test/bug482935.sjs b/dom/base/test/bug482935.sjs new file mode 100644 index 0000000000..daadb5ab2f --- /dev/null +++ b/dom/base/test/bug482935.sjs @@ -0,0 +1,12 @@ +function handleRequest(request, response) { + var body = "initial"; + + try { + body = request.getHeader("X-Request"); + } catch(e) { + body = "request.getHeader() failed! Exception: " + e; + } + + response.setHeader("Cache-Control", "max-age=3600"); + response.bodyOutputStream.write(body, body.length); +} diff --git a/dom/base/test/bug540854.sjs b/dom/base/test/bug540854.sjs new file mode 100644 index 0000000000..3c147a135e --- /dev/null +++ b/dom/base/test/bug540854.sjs @@ -0,0 +1,19 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/plain", false); + + var body = new BinaryInputStream(request.bodyInputStream); + + var avail; + var bytes = []; + while ((avail = body.available()) > 0) + Array.prototype.push.apply(bytes, body.readByteArray(avail)); + + var data = String.fromCharCode.apply(null, bytes); + response.bodyOutputStream.write(data, data.length); +} diff --git a/dom/base/test/bug578096LoadChromeScript.js b/dom/base/test/bug578096LoadChromeScript.js new file mode 100644 index 0000000000..edb785491e --- /dev/null +++ b/dom/base/test/bug578096LoadChromeScript.js @@ -0,0 +1,16 @@ +var file; +Components.utils.importGlobalProperties(["File"]); + +addMessageListener("file.create", function (message) { + file = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("TmpD", Components.interfaces.nsIFile); + file.append("foo.txt"); + file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0o600); + sendAsyncMessage("file.created", File.createFromNsIFile(file)); +}); + +addMessageListener("file.remove", function (message) { + file.remove(false); + sendAsyncMessage("file.removed", {}); +}); diff --git a/dom/base/test/bug638112-response.txt b/dom/base/test/bug638112-response.txt Binary files differnew file mode 100644 index 0000000000..9ce788da79 --- /dev/null +++ b/dom/base/test/bug638112-response.txt diff --git a/dom/base/test/bug638112.sjs b/dom/base/test/bug638112.sjs new file mode 100644 index 0000000000..3b4f8331b2 --- /dev/null +++ b/dom/base/test/bug638112.sjs @@ -0,0 +1,26 @@ +function getInputStream(path) +{ + var file = Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("CurWorkD", Components.interfaces.nsILocalFile); + var fis = Components.classes['@mozilla.org/network/file-input-stream;1']. + createInstance(Components.interfaces.nsIFileInputStream); + var split = path.split("/"); + for(var i = 0; i < split.length; ++i) { + file.append(split[i]); + } + fis.init(file, -1, -1, false); + return fis; +} + + + +function handleRequest(request, response) +{ + var inputStream = getInputStream("tests/dom/base/test/bug638112-response.txt") + response.seizePower(); + response.bodyOutputStream.writeFrom(inputStream, + inputStream.available()); + response.finish(); + inputStream.close(); +} diff --git a/dom/base/test/bug696301-script-1.js b/dom/base/test/bug696301-script-1.js new file mode 100644 index 0000000000..b139b2fdfd --- /dev/null +++ b/dom/base/test/bug696301-script-1.js @@ -0,0 +1,3 @@ +var a = 0; +var global = "ran"; +c();
\ No newline at end of file diff --git a/dom/base/test/bug696301-script-1.js^headers^ b/dom/base/test/bug696301-script-1.js^headers^ new file mode 100644 index 0000000000..cb762eff80 --- /dev/null +++ b/dom/base/test/bug696301-script-1.js^headers^ @@ -0,0 +1 @@ +Access-Control-Allow-Origin: * diff --git a/dom/base/test/bug696301-script-2.js b/dom/base/test/bug696301-script-2.js new file mode 100644 index 0000000000..b139b2fdfd --- /dev/null +++ b/dom/base/test/bug696301-script-2.js @@ -0,0 +1,3 @@ +var a = 0; +var global = "ran"; +c();
\ No newline at end of file diff --git a/dom/base/test/bug704320.sjs b/dom/base/test/bug704320.sjs new file mode 100644 index 0000000000..dff77f4b3f --- /dev/null +++ b/dom/base/test/bug704320.sjs @@ -0,0 +1,299 @@ +var BASE_URL = 'example.com/tests/dom/base/test/bug704320.sjs'; + +function createTestUrl(schemeFrom, schemeTo, policy, action, type) { + return schemeTo + '://' + BASE_URL + '?' + + 'action=' + action + '&' + + 'scheme=' + schemeFrom + '-to-' + schemeTo + '&' + + 'policy=' + policy + '&' + + 'type=' + type; +} + +function create2ndLevelIframeUrl(schemeFrom, schemeTo, policy, type) { + return schemeFrom + '://' + BASE_URL + '?' + + 'action=create-2nd-level-iframe&' + + 'scheme-from=' + schemeFrom + '&' + + 'scheme-to=' + schemeTo + '&' + + 'policy=' + policy + '&' + + 'type=' + type; +} + +// Creates the following test cases for the specified scheme and referrer +// policy combination: +// <link> +// @import +// font-face +// bg-url +// <script> +// <img> +// <iframe> +// <audio> +// <video> +// <object type="bogus"> +// <object type="image/svg+xml"> +// <a> +// <a ping> +// <form> +// window.location +// window.open +// XMLHttpRequest +// EventSource +// TODO: XSLT? +// +// This returns a page that loads all of the above resources and contains a +// script that clicks a link after all resources are (hopefully) +// loaded. The click triggers a redirection to file_bug704320_redirect.html, +// which in turn notifies the main window that it's time to check the test +// results. +function createTest(schemeFrom, schemeTo, policy, optionalEarlierPolicy) { + var _createTestUrl = createTestUrl.bind( + null, schemeFrom, schemeTo, policy, 'test'); + + var _create2ndLevelIframeUrl = create2ndLevelIframeUrl.bind( + null, schemeFrom, schemeTo, policy); + + var metaReferrerPolicyString = ''; + if (optionalEarlierPolicy && optionalEarlierPolicy != '') { + metaReferrerPolicyString += '<meta name="referrer" content="' + optionalEarlierPolicy + '">\n'; + } + metaReferrerPolicyString += '<meta name="referrer" content="' + policy + '">'; + + return '<!DOCTYPE HTML>\n\ + <html>\n\ + <head>\n\ + '+metaReferrerPolicyString+'\n\ + <link rel="stylesheet" type="text/css" href="' + _createTestUrl('stylesheet') + '">\n\ + <style type="text/css">\n\ + @import "' + _createTestUrl('import-css') + '";\n\ + @font-face {\n\ + font-family: "Fake Serif Bold";\n\ + src: url("' + _createTestUrl('font-face') + '");\n\ + }\n\ + body {\n\ + font-family: "Fake Serif Bold", serif;\n\ + background: url("' + _createTestUrl('bg-url') + '");\n\ + }\n\ + </style>\n\ + </head>\n\ + <body>\n\ + <script src="' + _createTestUrl('script') + '"></script>\n\ + <img src="' + _createTestUrl('img') + '"></img>\n\ + <iframe src="' + _createTestUrl('iframe') + '"></iframe>\n\ + <audio src="' + _createTestUrl('audio') + '"></audio>\n\ + <video src="' + _createTestUrl('video') + '"></video>\n\ + <object type="bogus" data="' + _createTestUrl('object') + '"></object>\n\ + <object type="image/svg+xml" data="' + _createTestUrl('object-svg') + '"></object>\n\ + <a id="link" href="' + _createTestUrl('link') + '" ping="' + _createTestUrl('link-ping') + '"></a>\n\ + <iframe src="' + _create2ndLevelIframeUrl('form') + '"></iframe>\n\ + <iframe src="' + _create2ndLevelIframeUrl('window.location') + '"></iframe>\n\ + <script>\n\ + var _testFinished = 0\n\ + (function() {\n\ + var x = new XMLHttpRequest();\n\ + x.open("GET", "' + _createTestUrl('xmlhttprequest') + '");\n\ + x.send();\n\ + })();\n\ + (function() {\n\ + var eventSource = new EventSource("' + _createTestUrl('eventsource') + '");\n\ + })();' + + + // LOAD EVENT (most of the tests) + // fires when the resources for the page are loaded + 'var _isLoaded = false;\n\ + window.addEventListener("load", function() {\n\ + this._isLoaded = true;\n\ + this.checkForFinish();\n\ + }.bind(window), false);' + + + // WINDOW.OPEN test + // listen for incoming status from window.open, close the window + // and check if we're done. + 'var _openedWindowLoaded = false;\n\ + window.addEventListener("message", function(message) {\n\ + if (message.data == "window.open") {\n\ + this._openedWindowLoaded = true;\n\ + this.win.close();\n\ + this.checkForFinish();\n\ + }\n\ + }.bind(window), false);\n\ + var win = window.open("' + _createTestUrl('window.open') + '", "");' + + + // called by the two things that must complete: window.open page + // and the window load event. When both are complete, this + // "finishes" the iframe subtest by clicking the link. + // _testFinished avoids calling this function twice (which may happen) + 'function checkForFinish() {\n\ + if (window._isLoaded && window._openedWindowLoaded && !window._testFinished) {\n\ + window._testFinished = 1;\n\ + document.getElementById("link").click();\n\ + }\n\ + }\n\ + </script>\n\ + </body>\n\ + </html>'; +} + +function createIframedFormTest(schemeFrom, schemeTo, policy) { + var actionUrl = schemeTo + '://' + BASE_URL; + + return '<!DOCTYPE HTML>\n\ + <html>\n\ + <head>\n\ + <meta name="referrer" content="' + policy + '">\n\ + </head>\n\ + <body>\n\ + <form id="form" action="' + actionUrl + '">\n\ + <input type="hidden" name="action" value="test">\n\ + <input type="hidden" name="scheme" value="' + schemeFrom + '-to-' + schemeTo + '">\n\ + <input type="hidden" name="policy" value="' + policy + '">\n\ + <input type="hidden" name="type" value="form">\n\ + </form>\n\ + <script>\n\ + document.getElementById("form").submit();\n\ + </script>\n\ + </body>\n\ + </html>'; +} + +function createIframedWindowLocationTest(schemeFrom, schemeTo, policy) { + var url = createTestUrl( + schemeFrom, schemeTo, policy, 'test', 'window.location'); + + return '<!DOCTYPE HTML>\n\ + <html>\n\ + <head>\n\ + <meta name="referrer" content="' + policy + '">\n\ + </head>\n\ + <body>\n\ + <script>\n\ + window.location = "' + url + '";\n\ + </script>\n\ + </body>\n\ + </html>'; +} + +function createPolicyTest(policy, optionalEarlierPolicy) { + var metaReferrerPolicyString = ''; + if (optionalEarlierPolicy && optionalEarlierPolicy != '') { + metaReferrerPolicyString += '<meta name="referrer" content="' + optionalEarlierPolicy + '">\n'; + } + metaReferrerPolicyString += '<meta name="referrer" content="' + policy + '">'; + + return '<!DOCTYPE HTML>\n\ + <html>\n\ + <head>\n\ + '+metaReferrerPolicyString+'\n\ + <script type="text/javascript" src="/tests/dom/base/test/file_bug704320_preload_common.js"></script>\n\ + </head>\n\ + <body>\n\ + <img src="/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\ + onload="incrementLoad2(\'img\', 2);">\n\ + <img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\ + onload="incrementLoad2(\'img\', 2);">\n\ + </body>\n\ + </html>'; +} + +function handleRequest(request, response) { + if (request.method == 'HEAD') { + // respond to a HEAD request with a 418 so that we can easily distinguish + // HSTS priming responses and ignore them + response.setStatusLine('1.1', 418, "I'm a teapot"); + return; + } + var sharedKey = 'bug704320.sjs'; + var params = request.queryString.split('&'); + var action = params[0].split('=')[1]; + + if (action === 'create-1st-level-iframe') { + // ?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=origin + var schemeFrom = params[1].split('=')[1]; + var schemeTo = params[2].split('=')[1]; + var policy = params[3].split('=')[1]; + var optionalEarlierPolicy = ''; + if (params[4]) { + optionalEarlierPolicy = params[4].split('=')[1]; + } + + response.setHeader('Content-Type', 'text/html; charset=utf-8', false); + response.setHeader('Cache-Control', 'no-cache', false); + response.write(createTest(schemeFrom, schemeTo, policy, optionalEarlierPolicy)); + } + else if (action === 'create-2nd-level-iframe') { + // ?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=origin&type=form" + var schemeFrom = params[1].split('=')[1]; + var schemeTo = params[2].split('=')[1]; + var policy = params[3].split('=')[1]; + var type = params[4].split('=')[1]; + + response.setHeader('Content-Type', 'text/html; charset=utf-8', false); + response.setHeader('Cache-Control', 'no-cache', false); + + if (type === 'form') { + response.write(createIframedFormTest(schemeFrom, schemeTo, policy)); + } else if (type === 'window.location') { + response.write(createIframedWindowLocationTest( + schemeFrom, schemeTo, policy)); + } + } + else if (action === 'test') { + // ?action=test&scheme=http-to-https&policy=origin&type=img + var scheme = params[1].split('=')[1]; + var policy = params[2].split('=')[1]; + var type = params[3].split('=')[1]; + var result = getSharedState(sharedKey); + + if (result === '') { + result = {}; + } else { + result = JSON.parse(result); + } + + if (!result[type]) { + result[type] = {}; + } + + if (!result[type][scheme]) { + result[type][scheme] = {}; + } + + if (request.hasHeader('Referer')) { + result[type][scheme][policy] = request.getHeader('Referer'); + } else { + result[type][scheme][policy] = ''; + } + + setSharedState(sharedKey, JSON.stringify(result)); + + if (type === 'link') { + var loc = 'https://example.com/tests/dom/base/test/file_bug704320_redirect.html'; + response.setStatusLine('1.1', 302, 'Found'); + response.setHeader('Location', loc, false); + } + + if (type === 'window.open') { + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/html', false); + response.write('<html><body><script>' + + 'window.opener.postMessage("window.open", "*");' + + '</script></body></html>'); + } + } + else if (action === 'get-test-results') { + // ?action=get-result + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/plain', false); + response.write(getSharedState(sharedKey)); + } + else if (action === 'generate-policy-test') { + // ?action=generate-policy-test&policy=b64-encoded-string + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/html', false); + var policy = unescape(params[1].split('=')[1]); + var optionalEarlierPolicy = ''; + if (params[2]) { + optionalEarlierPolicy = params[2].split('=')[1]; + } + + response.write(createPolicyTest(policy, optionalEarlierPolicy)); + } +} diff --git a/dom/base/test/bug704320_counter.sjs b/dom/base/test/bug704320_counter.sjs new file mode 100644 index 0000000000..907d224932 --- /dev/null +++ b/dom/base/test/bug704320_counter.sjs @@ -0,0 +1,94 @@ +// Handle counting loads for bug 704320. + +const SHARED_KEY="bug704320_counter"; +const DEFAULT_STATE = {'css': {'count': 0, 'referrers': []}, + 'img': {'count': 0, 'referrers': []}, + 'js': {'count': 0, 'referrers': []}}; +const TYPE_MAP = {'css': 'text/css', + 'js': 'application/javascript', + 'img': 'image/png', + 'html': 'text/html'}; + +// Writes an image to the response +function WriteOutImage(response) +{ + var file = Components.classes["@mozilla.org/file/directory_service;1"] + .getService(Components.interfaces.nsIProperties) + .get("CurWorkD", Components.interfaces.nsIFile); + + file.append("tests"); + file.append("image"); + file.append("test"); + file.append("mochitest"); + file.append('blue.png'); + + var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1'] + .createInstance(Components.interfaces.nsIFileInputStream); + fileStream.init(file, 1, 0, false); + response.bodyOutputStream.writeFrom(fileStream, fileStream.available()); +} + +function handleRequest(request, response) +{ + var query = {}; + request.queryString.split('&').forEach(function (val) { + var [name, value] = val.split('='); + query[name] = unescape(value); + }); + + var referrerLevel = "none"; + if (request.hasHeader('Referer')) { + let referrer = request.getHeader('Referer'); + if (referrer.indexOf("bug704320") > 0) { + referrerLevel = "full"; + } else if (referrer == "http://mochi.test:8888/") { + referrerLevel = "origin"; + } + } + + var state = getSharedState(SHARED_KEY); + if (state === '') { + state = DEFAULT_STATE; + } else { + state = JSON.parse(state); + } + + response.setStatusLine(request.httpVersion, 200, "OK"); + + + //avoid confusing cache behaviors + response.setHeader("Cache-Control", "no-cache", false); + + if ("reset" in query) { + //reset server state + setSharedState(SHARED_KEY, JSON.stringify(DEFAULT_STATE)); + //serve any CSS that we want to use. + response.write(""); + return; + } + + if ("results" in query) { + response.setHeader("Content-Type", "text/javascript", false); + response.write(JSON.stringify(state)); + return; + } + + if ('type' in query) { + state[query.type].count++; + response.setHeader("Content-Type", TYPE_MAP[query.type], false); + if (state[query.type].referrers.indexOf(referrerLevel) < 0) { + state[query.type].referrers.push(referrerLevel); + } + + if (query.type == 'img') { + WriteOutImage(response); + } + } + + if ('content' in query) { + response.write(unescape(query['content'])); + } + + setSharedState(SHARED_KEY, JSON.stringify(state)); + return; +} diff --git a/dom/base/test/bug819051.sjs b/dom/base/test/bug819051.sjs new file mode 100644 index 0000000000..07f6a041d6 --- /dev/null +++ b/dom/base/test/bug819051.sjs @@ -0,0 +1,7 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "Ok"); + response.setHeader("X-appended-result", request.getHeader("X-appended-to-this")); + response.setHeader("X-Accept-Result", request.getHeader("Accept")); + response.write(""); +} diff --git a/dom/base/test/chrome.ini b/dom/base/test/chrome.ini new file mode 100644 index 0000000000..f7e67ef6b9 --- /dev/null +++ b/dom/base/test/chrome.ini @@ -0,0 +1,27 @@ +[DEFAULT] +skip-if = os == 'android' +support-files = + file_empty.html + file_bug945152.jar + file_bug945152_worker.js + file_bug1008126_worker.js + mozbrowser_api_utils.js + +[test_anonymousContent_xul_window.xul] +[test_bug715041.xul] +[test_bug715041_removal.xul] +[test_bug945152.html] +[test_bug1008126.html] +[test_bug1016960.html] +[test_copypaste.xul] +subsuite = clipboard +[test_domrequesthelper.xul] +[test_messagemanager_principal.html] +[test_messagemanager_send_principal.html] +skip-if = buildapp == 'mulet' +[test_mozbrowser_apis_allowed.html] +[test_navigator_resolve_identity_xrays.xul] +support-files = file_navigator_resolve_identity_xrays.xul +[test_sandboxed_blob_uri.html] +[test_sendQueryContentAndSelectionSetEvent.html] +[test_websocket_frame.html] diff --git a/dom/base/test/chrome/blockNoPlugins.xml b/dom/base/test/chrome/blockNoPlugins.xml new file mode 100644 index 0000000000..e4e191b370 --- /dev/null +++ b/dom/base/test/chrome/blockNoPlugins.xml @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310001"> + <emItems> + </emItems> + <pluginItems> + </pluginItems> +</blocklist> diff --git a/dom/base/test/chrome/blockPluginHard.xml b/dom/base/test/chrome/blockPluginHard.xml new file mode 100644 index 0000000000..24eb5bc6fc --- /dev/null +++ b/dom/base/test/chrome/blockPluginHard.xml @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1336406310000"> + <emItems> + </emItems> + <pluginItems> + <pluginItem blockID="p9999"> + <match name="filename" exp="libnptest\.so|nptest\.dll|Test\.plugin" /> + <versionRange severity="2"></versionRange> + </pluginItem> + </pluginItems> +</blocklist> diff --git a/dom/base/test/chrome/bug418986-1.js b/dom/base/test/chrome/bug418986-1.js new file mode 100644 index 0000000000..918d90775b --- /dev/null +++ b/dom/base/test/chrome/bug418986-1.js @@ -0,0 +1,73 @@ +// The main test function. +var test = function (isContent) { + SimpleTest.waitForExplicitFinish(); + + let { ww } = SpecialPowers.Services; + window.chromeWindow = ww.activeWindow; + + // The pairs of values expected to be the same when + // fingerprinting resistance is enabled. + let pairs = [ + ["screenX", 0], + ["screenY", 0], + ["mozInnerScreenX", 0], + ["mozInnerScreenY", 0], + ["screen.pixelDepth", 24], + ["screen.colorDepth", 24], + ["screen.availWidth", "innerWidth"], + ["screen.availHeight", "innerHeight"], + ["screen.left", 0], + ["screen.top", 0], + ["screen.availLeft", 0], + ["screen.availTop", 0], + ["screen.width", "innerWidth"], + ["screen.height", "innerHeight"], + ["screen.orientation.type", "'landscape-primary'"], + ["screen.orientation.angle", 0], + ["screen.mozOrientation", "'landscape-primary'"], + ["devicePixelRatio", 1] + ]; + + // checkPair: tests if members of pair [a, b] are equal when evaluated. + let checkPair = function (a, b) { + is(eval(a), eval(b), a + " should be equal to " + b); + }; + + // Returns generator object that iterates through pref values. + let prefVals = (for (prefVal of [false, true]) prefVal); + + // The main test function, runs until all pref values are exhausted. + let nextTest = function () { + let {value : prefValue, done} = prefVals.next(); + if (done) { + SimpleTest.finish(); + return; + } + SpecialPowers.pushPrefEnv({set : [["privacy.resistFingerprinting", prefValue]]}, + function () { + // We will be resisting fingerprinting if the pref is enabled, + // and we are in a content script (not chrome). + let resisting = prefValue && isContent; + // Check each of the pairs. + pairs.map(function ([item, onVal]) { + if (resisting) { + checkPair("window." + item, onVal); + } else { + if (!item.startsWith("moz")) { + checkPair("window." + item, "chromeWindow." + item); + } + } + }); + if (!resisting) { + // Hard to predict these values, but we can enforce constraints: + ok(window.mozInnerScreenX >= chromeWindow.mozInnerScreenX, + "mozInnerScreenX"); + ok(window.mozInnerScreenY >= chromeWindow.mozInnerScreenY, + "mozInnerScreenY"); + } + nextTest(); + }); + } + + nextTest(); +} diff --git a/dom/base/test/chrome/bug421622-referer.sjs b/dom/base/test/chrome/bug421622-referer.sjs new file mode 100644 index 0000000000..850b320a23 --- /dev/null +++ b/dom/base/test/chrome/bug421622-referer.sjs @@ -0,0 +1,8 @@ +function handleRequest(request, response) { + response.setHeader("Content-Type", "text/plain", false); + response.setHeader("Cache-Control", "no-cache", false); + + var referer = request.hasHeader("Referer") ? request.getHeader("Referer") + : ""; + response.write("Referer: " + referer); +} diff --git a/dom/base/test/chrome/bug884693.sjs b/dom/base/test/chrome/bug884693.sjs new file mode 100644 index 0000000000..30d4f8a033 --- /dev/null +++ b/dom/base/test/chrome/bug884693.sjs @@ -0,0 +1,8 @@ +function handleRequest(request, response) +{ + let [status, statusText, body] = request.queryString.split("&"); + response.setStatusLine(request.httpVersion, status, statusText); + response.setHeader("Content-Type", "text/xml", false); + response.setHeader("Content-Length", "" + body.length, false); + response.write(body); +} diff --git a/dom/base/test/chrome/chrome.ini b/dom/base/test/chrome/chrome.ini new file mode 100644 index 0000000000..765bbd2dfb --- /dev/null +++ b/dom/base/test/chrome/chrome.ini @@ -0,0 +1,76 @@ +[DEFAULT] +skip-if = os == 'android' +support-files = + blockNoPlugins.xml + blockPluginHard.xml + bug418986-1.js + cpows_child.js + cpows_parent.xul + file_bug549682.xul + file_bug616841.xul + file_bug816340.xul + file_bug990812-1.xul + file_bug990812-2.xul + file_bug990812-3.xul + file_bug990812-4.xul + file_bug990812-5.xul + file_bug1139964.xul + file_bug1209621.xul + fileconstructor_file.png + frame_bug814638.xul + frame_registerElement_content.html + registerElement_ep.js + host_bug814638.xul + window_nsITextInputProcessor.xul + title_window.xul + window_swapFrameLoaders.xul + window_groupedSHistory.xul + +[test_bug120684.xul] +[test_bug206691.xul] +[test_bug289714.xul] +[test_bug339494.xul] +[test_bug357450.xul] +support-files = ../file_bug357450.js +[test_bug380418.html] +[test_bug380418.html^headers^] +[test_bug383430.html] +[test_bug418986-1.xul] +[test_bug421622.xul] +[test_bug429785.xul] +[test_bug430050.xul] +[test_bug467123.xul] +[test_bug549682.xul] +[test_bug571390.xul] +[test_bug1098074_throw_from_ReceiveMessage.xul] +[test_bug616841.xul] +[test_bug635835.xul] +[test_bug682305.html] +[test_bug683852.xul] +[test_bug752226-3.xul] +[test_bug752226-4.xul] +[test_bug765993.html] +[test_bug780199.xul] +[test_bug780529.xul] +[test_bug800386.xul] +[test_bug814638.xul] +[test_bug816340.xul] +[test_bug884693.xul] +[test_bug914381.html] +[test_bug990812.xul] +[test_bug1063837.xul] +[test_bug1139964.xul] +[test_bug1209621.xul] +[test_cpows.xul] +[test_registerElement_content.xul] +[test_registerElement_ep.xul] +[test_domparsing.xul] +[test_fileconstructor.xul] +[test_fileconstructor_tempfile.xul] +[test_nsITextInputProcessor.xul] +[test_range_getClientRectsAndTexts.html] +[test_title.xul] +[test_windowroot.xul] +[test_swapFrameLoaders.xul] +[test_groupedSHistory.xul] +[test_bug1339722.html] diff --git a/dom/base/test/chrome/cpows_child.js b/dom/base/test/chrome/cpows_child.js new file mode 100644 index 0000000000..28ae4d1a79 --- /dev/null +++ b/dom/base/test/chrome/cpows_child.js @@ -0,0 +1,382 @@ +dump('loaded child cpow test\n'); + +var Cu = Components.utils; +var Ci = Components.interfaces; + +(function start() { + [is_remote] = sendRpcMessage("cpows:is_remote"); + + var tests = [ + parent_test, + error_reporting_test, + dom_test, + xray_test, + symbol_test, + compartment_test, + regexp_test, + postmessage_test, + sync_test, + async_test, + rpc_test, + lifetime_test, + cancel_test, + cancel_test2, + dead_test, + unsafe_test, + ]; + + function go() { + if (tests.length == 0) { + sendRpcMessage("cpows:done", {}); + return; + } + + var test = tests[0]; + tests.shift(); + test(function() { + go(); + }); + } + + go(); +})(); + +function ok(condition, message) { + dump('condition: ' + condition + ', ' + message + '\n'); + if (!condition) { + sendAsyncMessage("cpows:fail", { message: message }); + throw 'failed check: ' + message; + } +} + +var sync_obj; +var async_obj; + +function make_object() +{ + let o = { }; + o.i = 5; + o.b = true; + o.s = "hello"; + o.x = { i: 10 }; + o.f = function () { return 99; }; + o.ctor = function() { this.a = 3; } + + // Doing anything with this Proxy will throw. + var throwing = new Proxy({}, new Proxy({}, { + get: function (trap) { throw trap; } + })); + + let array = [1, 2, 3]; + + let for_json = { "n": 3, "a": array, "s": "hello", o: { "x": 10 } }; + + let proto = { data: 42 }; + let with_proto = Object.create(proto); + + let with_null_proto = Object.create(null); + + content.document.title = "Hello, Kitty"; + return { "data": o, + "throwing": throwing, + "document": content.document, + "array": array, + "for_json": for_json, + "with_proto": with_proto, + "with_null_proto": with_null_proto + }; +} + +function make_json() +{ + return { check: "ok" }; +} + +function parent_test(finish) +{ + function f(check_func) { + // Make sure this doesn't crash. + let array = new Uint32Array(10); + content.crypto.getRandomValues(array); + + let result = check_func(10); + ok(result == 20, "calling function in parent worked"); + return result; + } + + addMessageListener("cpows:from_parent", (msg) => { + let obj = msg.objects.obj; + ok(obj.a == 1, "correct value from parent"); + + // Test that a CPOW reference to a function in the chrome process + // is callable from unprivileged content. Greasemonkey uses this + // functionality. + let func = msg.objects.func; + let sb = Cu.Sandbox('http://www.example.com', {}); + sb.func = func; + ok(sb.eval('func()') == 101, "can call parent's function in child"); + + finish(); + }); + sendRpcMessage("cpows:parent_test", {}, {func: f}); +} + +function error_reporting_test(finish) { + sendRpcMessage("cpows:error_reporting_test", {}, {}); + finish(); +} + +function dom_test(finish) +{ + let element = content.document.createElement("div"); + element.id = "it_works"; + content.document.body.appendChild(element); + + sendRpcMessage("cpows:dom_test", {}, {element: element}); + Components.utils.schedulePreciseGC(function() { + sendRpcMessage("cpows:dom_test_after_gc"); + finish(); + }); +} + +function xray_test(finish) +{ + let element = content.document.createElement("div"); + element.wrappedJSObject.foo = "hello"; + + sendRpcMessage("cpows:xray_test", {}, {element: element}); + finish(); +} + +function symbol_test(finish) +{ + let iterator = Symbol.iterator; + let named = Symbol.for("cpow-test"); + + let object = { + [iterator]: iterator, + [named]: named, + }; + let test = ['a']; + sendRpcMessage("cpows:symbol_test", {}, {object: object, test: test}); + finish(); +} + +// Parent->Child references should go X->parent.privilegedJunkScope->child.privilegedJunkScope->Y +// Child->Parent references should go X->child.privilegedJunkScope->parent.unprivilegedJunkScope->Y +function compartment_test(finish) +{ + // This test primarily checks various compartment invariants for CPOWs, and + // doesn't make sense to run in-process. + if (!is_remote) { + finish(); + return; + } + + let sb = Cu.Sandbox('http://www.example.com', { wantGlobalProperties: ['XMLHttpRequest'] }); + sb.eval('function getUnprivilegedObject() { var xhr = new XMLHttpRequest(); xhr.expando = 42; return xhr; }'); + function testParentObject(obj) { + let results = []; + function is(a, b, msg) { results.push({ result: a === b ? "PASS" : "FAIL", message: msg }) }; + function ok(x, msg) { results.push({ result: x ? "PASS" : "FAIL", message: msg }) }; + + let cpowLocation = Cu.getCompartmentLocation(obj); + ok(/Privileged Junk/.test(cpowLocation), + "child->parent CPOWs should live in the privileged junk scope: " + cpowLocation); + is(obj(), 42, "child->parent CPOW is invokable"); + try { + obj.expando; + ok(false, "child->parent CPOW cannot access properties"); + } catch (e) { + ok(true, "child->parent CPOW cannot access properties"); + } + + return results; + } + sendRpcMessage("cpows:compartment_test", {}, { getUnprivilegedObject: sb.getUnprivilegedObject, + testParentObject: testParentObject }); + finish(); +} + +function regexp_test(finish) +{ + sendRpcMessage("cpows:regexp_test", {}, { regexp: /myRegExp/g }); + finish(); +} + +function postmessage_test(finish) +{ + sendRpcMessage("cpows:postmessage_test", {}, { win: content.window }); + finish(); +} + +function sync_test(finish) +{ + dump('beginning cpow sync test\n'); + sync_obj = make_object(); + sendRpcMessage("cpows:sync", + make_json(), + make_object()); + finish(); +} + +function async_test(finish) +{ + dump('beginning cpow async test\n'); + async_obj = make_object(); + sendAsyncMessage("cpows:async", + make_json(), + async_obj); + + addMessageListener("cpows:async_done", finish); +} + +var rpc_obj; + +function rpc_test(finish) +{ + dump('beginning cpow rpc test\n'); + rpc_obj = make_object(); + rpc_obj.data.reenter = function () { + sendRpcMessage("cpows:reenter", { }, { data: { valid: true } }); + return "ok"; + } + sendRpcMessage("cpows:rpc", + make_json(), + rpc_obj); + finish(); +} + +function lifetime_test(finish) +{ + if (!is_remote) { + // Only run this test when running out-of-process. Otherwise it + // will fail, since local CPOWs don't follow the same ownership + // rules. + finish(); + return; + } + + dump("beginning lifetime test\n"); + var obj = {"will_die": {"f": 1}}; + let [result] = sendRpcMessage("cpows:lifetime_test_1", {}, {obj: obj}); + ok(result == 10, "got sync result"); + ok(obj.wont_die.f == 2, "got reverse CPOW"); + obj.will_die = null; + Components.utils.schedulePreciseGC(function() { + addMessageListener("cpows:lifetime_test_3", (msg) => { + ok(obj.wont_die.f == 2, "reverse CPOW still works"); + finish(); + }); + sendRpcMessage("cpows:lifetime_test_2"); + }); +} + +function cancel_test(finish) +{ + if (!is_remote) { + // No point in doing this in single-process mode. + finish(); + return; + } + + let fin1 = false, fin2 = false; + + // CPOW from the parent runs f. When it sends a sync message, the + // CPOW is canceled. The parent starts running again immediately + // after the CPOW is canceled; f also continues running. + function f() { + let res = sendSyncMessage("cpows:cancel_sync_message"); + ok(res[0] == 12, "cancel_sync_message result correct"); + fin1 = true; + if (fin1 && fin2) finish(); + } + + sendAsyncMessage("cpows:cancel_test", null, {f: f}); + addMessageListener("cpows:cancel_test_done", msg => { + fin2 = true; + if (fin1 && fin2) finish(); + }); +} + +function cancel_test2(finish) +{ + if (!is_remote) { + // No point in doing this in single-process mode. + finish(); + return; + } + + let fin1 = false, fin2 = false; + + // CPOW from the parent runs f. When it does a sync XHR, the + // CPOW is canceled. The parent starts running again immediately + // after the CPOW is canceled; f also continues running. + function f() { + let req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]. + createInstance(Components.interfaces.nsIXMLHttpRequest); + let fin = false; + let reqListener = () => { + if (req.readyState != req.DONE) { + return; + } + ok(req.status == 200, "XHR succeeded"); + fin = true; + }; + + req.onload = reqListener; + req.open("get", "http://example.com", false); + req.send(null); + + ok(fin == true, "XHR happened"); + + fin1 = true; + if (fin1 && fin2) finish(); + } + + sendAsyncMessage("cpows:cancel_test2", null, {f: f}); + addMessageListener("cpows:cancel_test2_done", msg => { + fin2 = true; + if (fin1 && fin2) finish(); + }); +} + +function unsafe_test(finish) +{ + if (!is_remote) { + // Only run this test when running out-of-process. + finish(); + return; + } + + function f() {} + + sendAsyncMessage("cpows:unsafe", null, {f}); + addMessageListener("cpows:unsafe_done", msg => { + sendRpcMessage("cpows:safe", null, {f}); + addMessageListener("cpows:safe_done", finish); + }); +} + +function dead_test(finish) +{ + if (!is_remote) { + // Only run this test when running out-of-process. + finish(); + return; + } + + let gcTrigger = function() { + // Force the GC to dead-ify the thing. + content.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .garbageCollect(); + } + + { + let thing = { value: "Gonna croak" }; + sendAsyncMessage("cpows:dead", null, { thing, gcTrigger }); + } + + addMessageListener("cpows:dead_done", finish); +} diff --git a/dom/base/test/chrome/cpows_parent.xul b/dom/base/test/chrome/cpows_parent.xul new file mode 100644 index 0000000000..f633f0a791 --- /dev/null +++ b/dom/base/test/chrome/cpows_parent.xul @@ -0,0 +1,493 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window title="MessageManager CPOW tests" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start()"> + + <!-- test results are displayed in the html:body --> + <label value="CPOWs"/> + + <script type="application/javascript"><![CDATA[ + var test_state = "remote"; + var test_node = null; + var reentered = false; + var savedMM = null; + const Cu = Components.utils; + + function info(message) { + return opener.wrappedJSObject.info(message); + } + + function ok(condition, message) { + return opener.wrappedJSObject.ok(condition, message); + } + + function is(v1, v2, message) { + return opener.wrappedJSObject.is(v1, v2, message); + } + + function todo_is(v1, v2, message) { + return opener.wrappedJSObject.todo_is(v1, v2, message); + } + + // Make sure that an error in this file actually causes the test to fail. + var gReceivedErrorProbe = false; + window.onerror = function (msg, url, line) { + if (/Test Error Probe/.test(msg)) { + gReceivedErrorProbe = true; + return; + } + ok(false, "Error while executing: \n" + msg + "\n" + url + ":" + line); + }; + + function testCpowMessage(message) { + ok(message.json.check == "ok", "correct json"); + + ok(!Components.utils.isCrossProcessWrapper(message.json), "not everything is a CPOW"); + + let data = message.objects.data; + let document = message.objects.document; + if (test_state == "remote") { + ok(Components.utils.isCrossProcessWrapper(data), "got a CPOW"); + ok(Components.utils.isCrossProcessWrapper(document), "got a CPOW"); + } + ok(data.i === 5, "integer property"); + ok(data.b === true, "boolean property"); + ok(data.s === "hello", "string property"); + ok(data.x.i === 10, "nested property"); + ok(data.f() === 99, "function call"); + is(Object.getOwnPropertyDescriptor(data, "doesn't exist"), undefined, + "getOwnPropertyDescriptor returns undefined for non-existant properties"); + ok(Object.getOwnPropertyDescriptor(data, "i").value, 5, + "getOwnPropertyDescriptor.value works"); + let obj = new data.ctor(); + ok(obj.a === 3, "constructor call"); + is(document.title, "Hello, Kitty", "document node"); + is(typeof document.cookie, "string", "can get document.cookie"); + is(typeof document.defaultView.navigator.userAgent, "string", "can get navigator.userAgent"); + + // Don't crash. + document.defaultView.screen; + + data.i = 6; + data.b = false; + data.s = "bye"; + data.x = null; + ok(data.i === 6, "integer property"); + ok(data.b === false, "boolean property"); + ok(data.s === "bye", "string property"); + ok(data.x === null, "nested property"); + + let throwing = message.objects.throwing; + // Based on the table on: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy + let tests = [ + () => Object.getOwnPropertyDescriptor(throwing, 'test'), + () => Object.getOwnPropertyNames(throwing), + () => Object.defineProperty(throwing, 'test', {value: 1}), + () => delete throwing.test, + () => "test" in throwing, + () => Object.prototype.hasOwnProperty.call(throwing, 'test'), + () => throwing.test, + () => { throwing.test = 1 }, + // () => { for (let prop in throwing) {} }, Bug 783829 + () => { for (let prop of throwing) {} }, + () => Object.keys(throwing), + () => Function.prototype.call.call(throwing), + () => new throwing, + () => Object.preventExtensions(throwing), + () => Object.freeze(throwing), + () => Object.seal(throwing), + ] + + for (let test of tests) { + let threw = false; + try { + test() + } catch (e) { + threw = true; + } + ok(threw, "proxy operation threw exception"); + } + + let array = message.objects.array; + let i = 1; + for (let elt of array) { + ok(elt === i, "correct element found"); + i++; + } + ok(i === 4, "array has correct length"); + + let j = message.objects.for_json; + let str = JSON.stringify(j); + let j2 = JSON.parse(str); + ok(j2.n === 3, "JSON integer property"); + ok(j2.a[0] === 1, "JSON array index"); + ok(j2.a[1] === 2, "JSON array index"); + ok(j2.a[2] === 3, "JSON array index"); + ok(j2.s === "hello", "JSON string property"); + ok(j2.o.x === 10, "JSON object property"); + + let with_proto = message.objects.with_proto; + let proto = Object.getPrototypeOf(with_proto); + ok(proto.data == 42, "Object.getPrototypeOf works on CPOW"); + + let with_null_proto = message.objects.with_null_proto; + proto = Object.getPrototypeOf(with_null_proto); + ok(proto === null, "Object.getPrototypeOf works on CPOW (null proto)"); + } + + function recvAsyncMessage(message) { + testCpowMessage(message); + savedMM.sendAsyncMessage("cpows:async_done"); + } + + function recvSyncMessage(message) { + testCpowMessage(message); + } + + function recvRpcMessage(message) { + ok(message.json.check == "ok", "correct json"); + + let data = message.objects.data; + + // Sanity check. + ok(data.i === 5, "integer property"); + + // Check that we re-enter. + reentered = false; + let result = data.reenter(); + ok(reentered, "re-entered rpc"); + ok(result == "ok", "got correct result"); + } + + function recvReenterMessage(message) { + ok(message.objects.data.valid === true, "cpows work"); + reentered = true; + } + + function recvNestedSyncMessage(message) { + message.objects.data.reenter(); + } + + function recvReenterSyncMessage(message) { + ok(false, "should not have received re-entered sync message"); + } + + function recvFailMessage(message) { + ok(false, message.json.message); + } + + function recvDoneMessage(message) { + if (test_state == "remote") { + test_node.parentNode.removeChild(test_node); + run_tests("inprocess"); + return; + } + + finish(); + } + + function recvParentTest(message) { + let func = message.objects.func; + let result = func(n => 2*n); + ok(result == 20, "result == 20"); + function f() { + return 101; + } + let obj = {a:1, __exposedProps__: {"a": "r"}}; + savedMM.sendAsyncMessage("cpows:from_parent", {}, {obj: obj, func: f}); + } + + // Make sure errors in this file actually hit window.onerror. + function recvErrorReportingTest(message) { + throw "Test Error Probe"; + } + + let savedElement = null; + function recvDomTest(message) { + savedElement = message.objects.element; + + is(savedElement.QueryInterface(Components.interfaces.nsISupports), savedElement, + "QI to nsISupports works"); + is(savedElement.QueryInterface(Components.interfaces.nsIDOMNode), savedElement, + "QI to a random (implemented) interface works"); + + function testNoInterface(savedElement, i) { + try { + savedElement.QueryInterface(i); + ok(false, "should have thrown an exception"); + } catch (e) { + is(e.result, Components.results.NS_ERROR_NO_INTERFACE, "threw the right exception"); + } + } + + testNoInterface(savedElement, Components.interfaces.nsIDOMAttr); + testNoInterface(savedElement, Components.interfaces.nsIClassInfo); + + // Test to ensure that we don't pass CPOWs to C++-implemented interfaces. + // See bug 1072980. + if (test_state == "remote") { + // This doesn't work because we intercept toString and QueryInterface specially + // and don't cache the function pointer. + // See bug 1140636. + todo_is(savedElement.toString, savedElement.toString, "toString identity works"); + todo_is(savedElement.QueryInterface, savedElement.QueryInterface, "toString identity works"); + + is(Object.prototype.toString.call(savedElement), "[object HTMLDivElement]", + "prove that this works (and doesn't leak)"); + + is(Object.prototype.toString.call(savedElement), "[object HTMLDivElement]", + "prove that this works twice (since we cache it and doesn't leak)"); + + // This does work because we create a CPOW for isEqualNode that stays + // alive as long as we have a reference to the first CPOW (so as long + // as it's detectable). + is(savedElement.isEqualNode, savedElement.isEqualNode, "webidl function identity works"); + + let walker = Components.classes["@mozilla.org/inspector/deep-tree-walker;1"] + .createInstance(Components.interfaces.inIDeepTreeWalker); + const SHOW_ELEMENT = Components.interfaces.nsIDOMNodeFilter.SHOW_ELEMENT; + walker.showAnonymousContent = true; + walker.showSubDocuments = false; + + try { + walker.init(savedElement, SHOW_ELEMENT); + ok(false, "expected exception passing CPOW to C++"); + } catch (e) { + is(e.result, Components.results.NS_ERROR_XPC_CANT_PASS_CPOW_TO_NATIVE, + "got exception when passing CPOW to C++"); + } + } + } + + function recvDomTestAfterGC(message) { + let id; + try { + id = savedElement.id; + } catch (e) { + ok(false, "Got exception using DOM element"); + } + is(id, "it_works", "DOM element has expected ID"); + } + + function recvXrayTest(message) { + let element = message.objects.element; + is(element.foo, undefined, "DOM element does not expose content properties"); + } + + function recvSymbolTest(message) { + let object = message.objects.object; + is(object[Symbol.iterator], Symbol.iterator, "Should use Symbol.iterator"); + is(Symbol.keyFor(object[Symbol.for("cpow-test")]), "cpow-test", "Symbols aren't registered correctly"); + let symbols = Object.getOwnPropertySymbols(object); + is(symbols.length, 2, "Object should have two symbol keys"); + let test = undefined; + for (let x of message.objects.test) { + test = x; + } + is(test, "a", "for .. of iteration should work"); + } + + let systemGlobal = this; + function recvCompartmentTest(message) { + let getUnprivilegedObject = message.objects.getUnprivilegedObject; + let testParentObject = message.objects.testParentObject; + + // Make sure that parent->child CPOWs live in the parent's privileged junk scope. + let unprivilegedObject = getUnprivilegedObject(); + is(Cu.getGlobalForObject(getUnprivilegedObject), + Cu.getGlobalForObject(unprivilegedObject), + "all parent->child CPOWs should live in the same scope"); + let cpowLocation = Cu.getCompartmentLocation(getUnprivilegedObject); + ok(/Privileged Junk/.test(cpowLocation), + "parent->child CPOWs should live in the privileged junk scope: " + cpowLocation); + + // Make sure that parent->child CPOWs point through a privileged scope in the child + // (the privileged junk scope, but we don't have a good way to test for that + // specifically). + is(unprivilegedObject.expando, undefined, "parent->child references should get Xrays"); + is(unprivilegedObject.wrappedJSObject.expando, 42, "parent->child references should get waivable Xrays"); + + // Send an object to the child to let it verify invariants in the other direction. + function passMe() { return 42; }; + passMe.expando = 42; + let results = testParentObject(passMe); + ok(results.length > 0, "Need results"); + results.forEach((x) => is(x.result, "PASS", x.message)); + } + + function recvRegExpTest(message) { + let regexp = message.objects.regexp; + + // These work generically. + is(regexp.toString(), "/myRegExp/g", "toString works right"); + ok(regexp.test("I like myRegExp to match"), "No false positives"); + ok(!regexp.test("asdfsdf"), "No false positives"); + + // These go over regexp_toShared. + is("filler myRegExp filler".search(regexp), 7, "String.prototype.match works right"); + var shell = /x/; + shell.compile(regexp); + is(regexp.toString(), shell.toString(), ".compile works right"); + } + + function recvPostMessageTest(message) { + let win = message.objects.win; + win.postMessage('nookery', '*'); + ok(true, "Didn't crash invoking postMessage over CPOW"); + } + + let savedWilldieObj; + let wontDie = {f:2, __exposedProps__: {"f": "r"}}; + function recvLifetimeTest1(message) { + let obj = message.objects.obj; + savedWilldieObj = obj.will_die; + ok(savedWilldieObj.f == 1, "limited-lifetime CPOW works at first"); + obj.wont_die = wontDie; + obj = null; + return 10; + } + function recvLifetimeTest2(message) { + let threw = false; + try { + savedWilldieObj.f; + } catch (e) { + threw = true; + } + ok(threw, "limited-lifetime CPOW stopped working"); + wontDie = null; + Components.utils.schedulePreciseGC(function() { + savedMM.sendAsyncMessage("cpows:lifetime_test_3"); + }); + } + + function recvCancelTest(msg) { + let failed = false; + try { + msg.objects.f(); + } catch (e if /cross-process JS call failed/.test(String(e))) { + failed = true; + } + ok(failed, "CPOW should fail due to cancelation"); + msg.target.messageManager.sendAsyncMessage("cpows:cancel_test_done"); + } + + function recvCancelSyncMessage() { + return 12; + } + + function recvCancelTest2(msg) { + let failed = false; + try { + msg.objects.f(); + } catch (e if /cross-process JS call failed/.test(String(e))) { + failed = true; + } + ok(failed, "CPOW should fail due to cancelation"); + msg.target.messageManager.sendAsyncMessage("cpows:cancel_test2_done"); + } + + function recvUnsafe(msg) { + let failed = false; + + const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser"; + opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true); + try { + msg.objects.f(); + } catch (e if /unsafe CPOW usage forbidden/.test(String(e))) { + failed = true; + } + opener.wrappedJSObject.SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN); + ok(failed, "CPOW should fail when unsafe"); + msg.target.messageManager.sendAsyncMessage("cpows:unsafe_done"); + } + + function recvSafe(msg) { + const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser"; + opener.wrappedJSObject.SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, true); + try { + msg.objects.f(); + } catch (e if /unsafe CPOW usage forbidden/.test(String(e))) { + ok(false, "cpow failed"); + } + opener.wrappedJSObject.SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN); + msg.target.messageManager.sendAsyncMessage("cpows:safe_done"); + } + + function recvDead(msg) { + // Need to do this in a separate turn of the event loop. + setTimeout(() => { + msg.objects.gcTrigger(); + try { + msg.objects.thing.value; + ok(false, "Should have been a dead CPOW"); + } catch(e if /dead CPOW/.test(String(e))) { + ok(true, "Got the expected dead CPOW"); + ok(e.stack, "The exception has a stack"); + } + msg.target.messageManager.sendAsyncMessage("cpows:dead_done"); + }, 0); + } + + function run_tests(type) { + info("Running tests: " + type); + var node = document.getElementById('cpowbrowser_' + type); + + test_state = type; + test_node = node; + + function recvIsRemote(message) { + return type == "remote"; + } + + var mm = node.messageManager; + savedMM = mm; + mm.addMessageListener("cpows:is_remote", recvIsRemote); + mm.addMessageListener("cpows:async", recvAsyncMessage); + mm.addMessageListener("cpows:sync", recvSyncMessage); + mm.addMessageListener("cpows:rpc", recvRpcMessage); + mm.addMessageListener("cpows:reenter", recvReenterMessage); + mm.addMessageListener("cpows:reenter", recvReenterMessage); + mm.addMessageListener("cpows:nested_sync", recvNestedSyncMessage); + mm.addMessageListener("cpows:reenter_sync", recvReenterSyncMessage); + mm.addMessageListener("cpows:done", recvDoneMessage); + mm.addMessageListener("cpows:fail", recvFailMessage); + mm.addMessageListener("cpows:parent_test", recvParentTest); + mm.addMessageListener("cpows:error_reporting_test", recvErrorReportingTest); + mm.addMessageListener("cpows:dom_test", recvDomTest); + mm.addMessageListener("cpows:dom_test_after_gc", recvDomTestAfterGC); + mm.addMessageListener("cpows:xray_test", recvXrayTest); + if (typeof Symbol === "function") { + mm.addMessageListener("cpows:symbol_test", recvSymbolTest); + } + mm.addMessageListener("cpows:compartment_test", recvCompartmentTest); + mm.addMessageListener("cpows:regexp_test", recvRegExpTest); + mm.addMessageListener("cpows:postmessage_test", recvPostMessageTest); + mm.addMessageListener("cpows:lifetime_test_1", recvLifetimeTest1); + mm.addMessageListener("cpows:lifetime_test_2", recvLifetimeTest2); + mm.addMessageListener("cpows:cancel_test", recvCancelTest); + mm.addMessageListener("cpows:cancel_sync_message", recvCancelSyncMessage); + mm.addMessageListener("cpows:cancel_test2", recvCancelTest2); + mm.addMessageListener("cpows:unsafe", recvUnsafe); + mm.addMessageListener("cpows:safe", recvSafe); + mm.addMessageListener("cpows:dead", recvDead); + mm.loadFrameScript("chrome://mochitests/content/chrome/dom/base/test/chrome/cpows_child.js", true); + } + + function start() { + run_tests('remote'); + } + + function finish() { + ok(gReceivedErrorProbe, "Should have reported error probe"); + opener.setTimeout("done()", 0); + window.close(); + } + ]]></script> + + <browser type="content" src="about:blank" id="cpowbrowser_remote" remote="true"/> + <browser type="content" src="about:blank" id="cpowbrowser_inprocess"/> +</window> diff --git a/dom/base/test/chrome/file_bug1139964.xul b/dom/base/test/chrome/file_bug1139964.xul new file mode 100644 index 0000000000..2513343014 --- /dev/null +++ b/dom/base/test/chrome/file_bug1139964.xul @@ -0,0 +1,62 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1139964 +--> +<window title="Mozilla Bug 1139964" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="run()"> + <label value="Mozilla Bug 1139964"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var Cc = Components.classes; + var Ci = Components.interfaces; + + var ppm = Cc["@mozilla.org/parentprocessmessagemanager;1"] + .getService(Ci.nsIMessageBroadcaster); + + function ok(cond, msg) { + opener.wrappedJSObject.ok(cond, msg); + } + + var msgName = "TEST:Global_has_Promise"; + + function mmScriptForPromiseTest() { + sendAsyncMessage("TEST:Global_has_Promise", + { + hasPromise: ("Promise" in this), + hasTextEncoder: ("TextEncoder" in this), + hasWindow: ("Window" in this), + }); + } + + function processListener(m) { + ppm.removeMessageListener(msgName, processListener); + ok(m.data.hasPromise, "ProcessGlobal should have Promise object in the global scope!"); + ok(m.data.hasTextEncoder, "ProcessGlobal should have TextEncoder object in the global scope!"); + ok(!m.data.hasWindow, "ProcessGlobal should not have Window object in the global scope!"); + + messageManager.addMessageListener(msgName, tabListener) + messageManager.loadFrameScript("data:,(" + mmScriptForPromiseTest.toString() + ")()", true); + } + + function tabListener(m) { + messageManager.removeMessageListener(msgName, tabListener); + ok(m.data.hasPromise, "TabChildGlobal should have Promise object in the global scope!"); + ok(m.data.hasTextEncoder, "TabChildGlobal should have TextEncoder object in the global scope!"); + ok(!m.data.hasWindow, "TabChildGlobal should not have Window object in the global scope!"); + + opener.setTimeout("done()", 0); + window.close(); + } + + function run() { + ppm.addMessageListener(msgName, processListener) + ppm.loadProcessScript("data:,(" + mmScriptForPromiseTest.toString() + ")()", true); + } + + ]]></script> + <browser type="content" src="about:blank" id="ifr"/> +</window> diff --git a/dom/base/test/chrome/file_bug1209621.xul b/dom/base/test/chrome/file_bug1209621.xul new file mode 100644 index 0000000000..05d81c3fb1 --- /dev/null +++ b/dom/base/test/chrome/file_bug1209621.xul @@ -0,0 +1,79 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1209621 +--> +<window title="Mozilla Bug 1209621" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="run()"> + <label value="Mozilla Bug 1209621"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var Cc = Components.classes; + var Ci = Components.interfaces; + var Cr = Components.results; + var Cu = Components.utils; + function ok(cond, msg) { + opener.wrappedJSObject.ok(cond, msg); + } + + function is(actual, expected, msg) { + opener.wrappedJSObject.is(actual, expected, msg); + } + + function run() { + var docshell = window.getInterface(Ci.nsIDocShell); + ok(docshell, "Active window should have a DocShell"); + var treeOwner = docshell.treeOwner; + ok(treeOwner, "Active docshell should have a TreeOwner!"); + + is(treeOwner.primaryContentShell, null, + "There shouldn't be primaryContentShell because no browser has type=content-primary."); + is(treeOwner.primaryTabParent, null, + "There shouldn't be primaryTabParent because no remote browser has type=content-primary."); + + var ip = document.getElementById("inprocess"); + var remote = document.getElementById("remote"); + var remote2 = document.getElementById("remote2"); + + ip.setAttribute("type", "content-primary"); + ok(ip.docShell, "non-remote browser should have a DocShell."); + is(treeOwner.primaryContentShell, ip.docShell, + "content-primary browser should be the primaryContentShell."); + is(treeOwner.primaryTabParent, null, + "There shouldn't be primaryTabParent because no remote browser has type=content-primary."); + + ip.setAttribute("type", "content"); + remote.setAttribute("type", "content-primary"); + is(treeOwner.primaryContentShell, null, + "There shouldn't be primaryContentShell because no browser has type=content-primary."); + var tp = remote.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.tabParent; + ok(tp, "Remote browsers should have a TabParent."); + is(treeOwner.primaryTabParent, tp, + "content-primary remote browser should be the primaryTabParent."); + + remote.setAttribute("type", "content"); + is(treeOwner.primaryContentShell, null, + "There shouldn't be primaryContentShell because no browser has type=content-primary."); + is(treeOwner.primaryTabParent, null, + "There shouldn't be primaryTabParent because no remote browser has type=content-primary."); + + remote2.setAttribute("type", "content-primary"); + var tp2 = remote2.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.tabParent; + ok(tp2, "Remote browsers should have a TabParent."); + is(treeOwner.primaryTabParent, tp2, + "content-primary remote browser should be the primaryTabParent."); + is(treeOwner.primaryContentShell, null, + "There shouldn't be primaryContentShell because no browser has type=content-primary."); + + opener.setTimeout("done()", 0); + window.close(); + } + + ]]></script> + <browser type="content" src="about:blank" id="inprocess"/> + <browser type="content" remote="true" src="about:blank" id="remote"/> + <browser type="content" remote="true" src="about:blank" id="remote2"/> +</window> diff --git a/dom/base/test/chrome/file_bug549682.xul b/dom/base/test/chrome/file_bug549682.xul new file mode 100644 index 0000000000..667e7ca0b6 --- /dev/null +++ b/dom/base/test/chrome/file_bug549682.xul @@ -0,0 +1,226 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=549682 +--> +<window title="Mozilla Bug 549682" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="run()"> + <label value="Mozilla Bug 549682"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var Cc = Components.classes; + var Ci = Components.interfaces; + var Cr = Components.results; + var Cu = Components.utils; + + var didRunAsync = false; + var didRunLocal = false; + + var global = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Components.interfaces.nsIMessageBroadcaster); + var ppm = Cc["@mozilla.org/parentprocessmessagemanager;1"] + .getService(Components.interfaces.nsIMessageBroadcaster); + var cpm = Cc["@mozilla.org/childprocessmessagemanager;1"] + .getService(Components.interfaces.nsISyncMessageSender); + + Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + + function ok(cond, msg) { + opener.wrappedJSObject.ok(cond, msg); + } + + function is(actual, expected, msg) { + opener.wrappedJSObject.is(actual, expected, msg); + } + + var asyncPPML = false; + function ppmASL(m) { + asyncPPML = true; + } + var syncPPML = false; + function ppmSL(m) { + syncPPML = true; + } + ppm.addMessageListener("processmessageAsync", ppmASL); + ppm.addMessageListener("processmessageSync", ppmSL); + + cpm.sendAsyncMessage("processmessageAsync", ""); + cpm.sendSyncMessage("processmessageSync", ""); + + var asyncCPML = false; + function cpmASL(m) { + asyncCPML = true; + } + cpm.addMessageListener("childprocessmessage", cpmASL); + ppm.broadcastAsyncMessage("childprocessmessage", ""); + + function checkPMMMessages() { + ok(asyncPPML, "should have handled async message"); + ok(syncPPML, "should have handled sync message"); + ok(asyncCPML, "should have handled async message"); + ppm.removeMessageListener("processmessageAsync", ppmASL); + ppm.removeMessageListener("processmessageSync", ppmSL); + cpm.removeMessageListener("childprocessmessage", cpmASL); + } + + var globalListenerCallCount = 0; + function globalListener(m) { + ++globalListenerCallCount; + if (m.name == "sync") { + global.removeMessageListener("async", globalListener); + global.removeMessageListener("sync", globalListener); + global.removeMessageListener("global-sync", globalListener); + // Note, the result depends on what other windows are open. + ok(globalListenerCallCount >= 4, + "Global listener should have been called at least 4 times!"); + ok(didRunLocal, "Local message received."); + } + } + + function asyncL(m) { + didRunAsync = true; + is(m.name, "async", "Wrong message!"); + is(m.json.data, 1234, "Wrong data!"); + } + + function syncL(m) { + is(m.name, "sync", "Wrong message!"); + is(m.json.data, 1234, "Wrong data!"); + ok(didRunAsync, "Should have run async!"); + } + + function localL(m) { + is(m.name, "lasync", "Wrong message!"); + is(m.json.data, 2345, "Wrong data!"); + didRunLocal = true; + } + + var weakMessageReceived = false; + var weakListener = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, + Ci.nsISupportsWeakReference]), + + receiveMessage: function(msg) { + if (weakMessageReceived) { + ok(false, 'Weak listener fired twice.'); + return; + } + + ok(true, 'Weak listener fired once.'); + weakMessageReceived = true; + document.getElementById('ifr').messageManager + .removeWeakMessageListener('weak', weakListener); + } + }; + + var weakListener2 = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener, + Ci.nsISupportsWeakReference]), + + receiveMessage: function(msg) { + ok(false, 'Should not have received a message.'); + } + }; + + function weakDoneListener() { + ok(weakMessageReceived, 'Got "weak" message.'); + finish(); + } + + function finish() { + opener.setTimeout("done()", 0); + var i = document.getElementById("ifr"); + i.parentNode.removeChild(i); // This is a crash test! + window.close(); + } + + function loadScript() { + // Async should be processed first! + messageManager.loadFrameScript("data:,\ + sendAsyncMessage('async', { data: 1234 });\ + sendSyncMessage('sync', { data: 1234 });\ + sendAsyncMessage('weak', {});\ + sendAsyncMessage('weak', {});\ + sendAsyncMessage('weakdone', {});", false); + } + + function run() { + var localmm = document.getElementById('ifr').messageManager; + + var wn = document.getElementById('ifr').contentWindow + .getInterface(Components.interfaces.nsIWebNavigation); + ok(wn, "Should have webnavigation"); + var cfmm = wn.getInterface(Components.interfaces.nsIContentFrameMessageManager); + ok(cfmm, "Should have content messageManager"); + + var didGetSyncMessage = false; + function syncContinueTestFn() { + didGetSyncMessage = true; + } + localmm.addMessageListener("syncContinueTest", syncContinueTestFn); + cfmm.sendSyncMessage("syncContinueTest", {}); + localmm.removeMessageListener("syncContinueTest", syncContinueTestFn); + ok(didGetSyncMessage, "Should have got sync message!"); + + localmm.addMessageListener("lasync", localL); + localmm.loadFrameScript("data:,sendAsyncMessage('lasync', { data: 2345 })", false); + + messageManager.addMessageListener("async", asyncL); + messageManager.addMessageListener("sync", syncL); + global.addMessageListener("async", globalListener); + global.addMessageListener("sync", globalListener); + global.addMessageListener("global-sync", globalListener); + global.loadFrameScript("data:,sendSyncMessage('global-sync', { data: 1234 });", true); + var toBeRemovedScript = "data:,sendAsyncMessage('toberemoved', { data: 2345 })"; + var c = 0; + messageManager.addMessageListener("toberemoved", function() { + ++c; + is(c, 1, "Should be called only once!"); + }); + // This loads the script in the existing <browser> + messageManager.loadFrameScript(toBeRemovedScript, true); + // But it won't be loaded in the dynamically created <browser> + messageManager.removeDelayedFrameScript(toBeRemovedScript); + + var oldValue = globalListenerCallCount; + var b = document.createElement("browser"); + b.setAttribute("type", "content"); + document.documentElement.appendChild(b); + is(globalListenerCallCount, oldValue + 1, + "Wrong message count"); + + localmm.addWeakMessageListener('weak', weakListener); + localmm.addMessageListener('weakdone', weakDoneListener); + + // Add weakListener2 as a weak message listener, then force weakListener2 + // to be gc'ed. weakListener2 shouldn't be run. + var weakRef = Cu.getWeakReference(weakListener2); + localmm.addWeakMessageListener('weak', weakListener2); + weakListener2 = null; + + // Force a gc/cc in a loop until weakRef's referent has gone away. + function waitForWeakRefToDie() { + if (weakRef.get()) { + var mgr = Cc["@mozilla.org/memory-reporter-manager;1"] + .getService(Ci.nsIMemoryReporterManager); + mgr.minimizeMemoryUsage(waitForWeakRefToDie); + + // Print a message so that if the test hangs in a minimizeMemoryUsage + // loop, we'll be able to see it in the log. + ok(true, "waitForWeakRefToDie spinning..."); + return; + } + + setTimeout(checkPMMMessages, 0); + setTimeout(loadScript, 0); + } + + waitForWeakRefToDie(); + } + + ]]></script> + <browser type="content" src="about:blank" id="ifr"/> +</window> diff --git a/dom/base/test/chrome/file_bug616841.xul b/dom/base/test/chrome/file_bug616841.xul new file mode 100644 index 0000000000..5110c0c9e8 --- /dev/null +++ b/dom/base/test/chrome/file_bug616841.xul @@ -0,0 +1,63 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=616841 +--> +<window title="Mozilla Bug 616841" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start()"> + <label value="Mozilla Bug 616841"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + const FRAME_SCRIPT = +"data:,addMessageListener(\n"+ +" 'cmp',\n"+ +" function (m) {\n"+ +" sendAsyncMessage('cmp', { i: m.json.i,\n"+ +" cmp: m.json.a.localeCompare(m.json.b) });\n"+ +" });\n"+ +"sendAsyncMessage('contentReady');"; + + var toCompare = [ [ "C", "D" ], + [ "D", "C" ], + [ "\u010C", "D" ], + [ "D", "\u010C" ] ]; + var nCmps = 0; + + function recvContentReady(m) { + for (var i = 0; i < toCompare.length; ++i) { + var pair = toCompare[i]; + messageManager.broadcastAsyncMessage("cmp", + { i: i, a: pair[0], b: pair[1] }); + } + } + + function recvCmp(m) { + var i = m.json.i, cmp = m.json.cmp; + var pair = toCompare[i]; + opener.wrappedJSObject.is(pair[0].localeCompare(pair[1]), cmp, "localeCompare returned same result in frame script"); + + if (toCompare.length == ++nCmps) { + messageManager.removeMessageListener("cmp", recvCmp); + finish(); + } + } + + function start() { + messageManager.addMessageListener("contentReady", recvContentReady); + messageManager.addMessageListener("cmp", recvCmp); + messageManager.loadFrameScript(FRAME_SCRIPT, true); + } + + function finish() { + opener.setTimeout("done()", 0); + window.close(); + } + + ]]></script> + + <browser id="browser" type="content" src="about:blank"/> +</window> diff --git a/dom/base/test/chrome/file_bug816340.xul b/dom/base/test/chrome/file_bug816340.xul new file mode 100644 index 0000000000..bf980e4373 --- /dev/null +++ b/dom/base/test/chrome/file_bug816340.xul @@ -0,0 +1,70 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=816340 +--> +<window title="Mozilla Bug 816340" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <label value="Mozilla Bug 816340"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + function ok(val, msg) { + opener.wrappedJSObject.ok(val, msg); + } + + var elems = + [ + "input", + "textarea", + "select", + "fieldset", + "button", + ]; + + var chromeDidGetEvent = false; + function chromeListener() { + chromeDidGetEvent = true; + } + + function testElement(el, disabled, contentShouldGetEvent) { + chromeDidGetEvent = false; + var b = document.getElementById("browser"); + b.contentDocument.body.innerHTML = null; + var e = b.contentDocument.createElement(el); + if (disabled) { + e.setAttribute("disabled", "true"); + } + b.contentDocument.body.appendChild(e); + var contentDidGetEvent = false; + b.contentDocument.body.addEventListener("foo", + function() { contentDidGetEvent = true }, true); + + b.addEventListener("foo", chromeListener, true); + e.dispatchEvent(new Event("foo")); + b.removeEventListener("foo", chromeListener, true); + ok(contentDidGetEvent == contentShouldGetEvent, "content: " + el + (disabled ? " disabled" : "")); + ok(chromeDidGetEvent, "chrome: " + el + (disabled ? " disabled" : "")); + } + + function start() { + // Test common element. + testElement("div", false, true); + testElement("div", true, true); + + for (var i = 0; i < elems.length; ++i) { + testElement(elems[i], false, true); + testElement(elems[i], true, false); + } + ok(true, "done"); + opener.setTimeout("done()", 0); + window.close(); + } + + ]]></script> + + <browser id="browser" type="content" src="about:blank"/> +</window> diff --git a/dom/base/test/chrome/file_bug990812-1.xul b/dom/base/test/chrome/file_bug990812-1.xul new file mode 100644 index 0000000000..1e085e76a2 --- /dev/null +++ b/dom/base/test/chrome/file_bug990812-1.xul @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990812 +--> +<window title="Mozilla Bug 990812" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <label value="Mozilla Bug 990812"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + var FRAME_SCRIPT_GLOBAL = "data:,sendSyncMessage('test', 'global')"; + var FRAME_SCRIPT_WINDOW = "data:,sendSyncMessage('test', 'window')"; + var FRAME_SCRIPT_GROUP = "data:,sendSyncMessage('test', 'group')"; + + var Cc = Components.classes; + var Ci = Components.interfaces; + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager); + + function is(val, exp, msg) { + opener.wrappedJSObject.is(val, exp, msg); + } + + /** + * Ensures that delayed frame scripts are loaded in the expected order. + * Global frame scripts will be loaded before delayed frame scripts from + * window message managers. The latter will be loaded before group message + * manager frame scripts. + */ + function start() { + globalMM.loadFrameScript(FRAME_SCRIPT_GLOBAL, true); + messageManager.loadFrameScript(FRAME_SCRIPT_WINDOW, true); + getGroupMessageManager("test").loadFrameScript(FRAME_SCRIPT_GROUP, true); + + var order = ["global", "window", "group"]; + + messageManager.addMessageListener("test", function onMessage(msg) { + var next = order.shift(); + opener.wrappedJSObject.is(msg.data, next, "received test:" + next); + + if (order.length == 0) { + opener.setTimeout("next()"); + window.close(); + } + }); + + var browser = document.createElement("browser"); + browser.setAttribute("messagemanagergroup", "test"); + browser.setAttribute("src", "about:mozilla"); + browser.setAttribute("type", "content-targetable"); + document.documentElement.appendChild(browser); + + globalMM.removeDelayedFrameScript(FRAME_SCRIPT_GLOBAL); + messageManager.removeDelayedFrameScript(FRAME_SCRIPT_WINDOW); + getGroupMessageManager("test").removeDelayedFrameScript(FRAME_SCRIPT_GROUP); + } + + ]]></script> + +</window> diff --git a/dom/base/test/chrome/file_bug990812-2.xul b/dom/base/test/chrome/file_bug990812-2.xul new file mode 100644 index 0000000000..957861cd4b --- /dev/null +++ b/dom/base/test/chrome/file_bug990812-2.xul @@ -0,0 +1,59 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990812 +--> +<window title="Mozilla Bug 990812" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <label value="Mozilla Bug 990812"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + var FRAME_SCRIPT = "data:,sendAsyncMessage('test')"; + var order = ["group", "window", "global"]; + + var Cc = Components.classes; + var Ci = Components.interfaces; + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager); + + function is(val, exp, msg) { + opener.wrappedJSObject.is(val, exp, msg); + } + + function promiseMessage(type, mm) { + return new Promise(function (resolve) { + mm.addMessageListener("test", function onMessage() { + mm.removeMessageListener("test", onMessage); + is(type, order.shift(), "correct type " + type); + resolve(); + }); + }); + } + + /** + * Tests that async messages sent by frame scripts bubble up as expected, + * passing the group, window, and global message managers in that order. + */ + function start() { + var global = promiseMessage("global", globalMM); + var window = promiseMessage("window", messageManager); + var group = promiseMessage("group", getGroupMessageManager("test")); + + var browser = document.querySelector("browser"); + browser.messageManager.loadFrameScript(FRAME_SCRIPT, true); + + Promise.all([global, window, group]).then(function () { + opener.setTimeout("next()"); + self.close(); + }); + } + + ]]></script> + + <browser messagemanagergroup="test" type="content-targetable" src="about:mozilla" /> + +</window> diff --git a/dom/base/test/chrome/file_bug990812-3.xul b/dom/base/test/chrome/file_bug990812-3.xul new file mode 100644 index 0000000000..6dc25c9bbf --- /dev/null +++ b/dom/base/test/chrome/file_bug990812-3.xul @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990812 +--> +<window title="Mozilla Bug 990812" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <label value="Mozilla Bug 990812"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + var FRAME_SCRIPT = "data:,addMessageListener('test', function (msg) {" + + "sendSyncMessage('test', msg.data)})"; + + var Cc = Components.classes; + var Ci = Components.interfaces; + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager); + + function is(val, exp, msg) { + opener.wrappedJSObject.is(val, exp, msg); + } + + function promiseMessage(type, mm) { + var order = [type, "window", "global"]; + + return new Promise(function (resolve) { + mm.addMessageListener("test", function onMessage(msg) { + is(msg.data, order.shift(), "correct message " + msg.data); + + if (order.length == 0) { + mm.removeMessageListener("test", onMessage); + resolve(); + } + }); + }); + } + + /** + * Ensures that broadcasting an async message does only reach descendants + * of a specific message manager and respects message manager groups. + */ + function start() { + var mm1 = document.querySelector("browser").messageManager; + var promise1 = promiseMessage("group1", mm1); + mm1.loadFrameScript(FRAME_SCRIPT, true); + + var mm2 = document.querySelector("browser + browser").messageManager; + var promise2 = promiseMessage("group2", mm2); + mm2.loadFrameScript(FRAME_SCRIPT, true); + + getGroupMessageManager("test1").broadcastAsyncMessage("test", "group1"); + getGroupMessageManager("test2").broadcastAsyncMessage("test", "group2"); + messageManager.broadcastAsyncMessage("test", "window"); + globalMM.broadcastAsyncMessage("test", "global"); + + Promise.all([promise1, promise2]).then(function () { + opener.setTimeout("next()"); + window.close(); + }); + } + + ]]></script> + + <browser messagemanagergroup="test1" type="content-targetable" src="about:mozilla" /> + <browser messagemanagergroup="test2" type="content-targetable" src="about:mozilla" /> + +</window> diff --git a/dom/base/test/chrome/file_bug990812-4.xul b/dom/base/test/chrome/file_bug990812-4.xul new file mode 100644 index 0000000000..c6d2c04e9e --- /dev/null +++ b/dom/base/test/chrome/file_bug990812-4.xul @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990812 +--> +<window title="Mozilla Bug 990812" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <label value="Mozilla Bug 990812"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + var FRAME_SCRIPT1 = "data:,addMessageListener('test', function () {" + + "sendSyncMessage('test', 'frame1')})"; + var FRAME_SCRIPT2 = "data:,addMessageListener('test', function () {" + + "sendSyncMessage('test', 'frame2')})"; + + var Cc = Components.classes; + var Ci = Components.interfaces; + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager); + + function is(val, exp, msg) { + opener.wrappedJSObject.is(val, exp, msg); + } + + function promiseMessage(type, mm) { + return new Promise(function (resolve) { + mm.addMessageListener("test", function onMessage(msg) { + mm.removeMessageListener("test", onMessage); + is(msg.data, type, "correct message " + type); + resolve(); + }); + }); + } + + /** + * Tests that swapping docShells works as expected wrt to groups. + */ + function start() { + var browser1 = document.querySelector("browser"); + browser1.messageManager.loadFrameScript(FRAME_SCRIPT1, true); + + var browser2 = document.querySelector("browser + browser"); + browser2.messageManager.loadFrameScript(FRAME_SCRIPT2, true); + + var promise1 = promiseMessage("frame2", getGroupMessageManager("test1")); + var promise2 = promiseMessage("frame1", getGroupMessageManager("test2")); + + var flo1 = browser1.QueryInterface(Ci.nsIFrameLoaderOwner); + var flo2 = browser2.QueryInterface(Ci.nsIFrameLoaderOwner); + flo1.swapFrameLoaders(flo2); + messageManager.broadcastAsyncMessage("test"); + + Promise.all([promise1, promise2]).then(function () { + opener.setTimeout("next()"); + window.close(); + }); + } + + ]]></script> + + <browser messagemanagergroup="test1" type="content-targetable" src="about:mozilla" /> + <browser messagemanagergroup="test2" type="content-targetable" src="about:mozilla" /> + +</window> diff --git a/dom/base/test/chrome/file_bug990812-5.xul b/dom/base/test/chrome/file_bug990812-5.xul new file mode 100644 index 0000000000..b00e05bc5b --- /dev/null +++ b/dom/base/test/chrome/file_bug990812-5.xul @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990812 +--> +<window title="Mozilla Bug 990812" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <label value="Mozilla Bug 990812"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + var FRAME_SCRIPT1 = "data:,addMessageListener('test', function () {" + + "sendSyncMessage('test', 'group1')})"; + var FRAME_SCRIPT2 = "data:,addMessageListener('test', function () {" + + "sendSyncMessage('test', 'group2')})"; + + var Cc = Components.classes; + var Ci = Components.interfaces; + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager); + + function is(val, exp, msg) { + opener.wrappedJSObject.is(val, exp, msg); + } + + function promiseTwoMessages(type, mm) { + var numLeft = 2; + + return new Promise(function (resolve) { + mm.addMessageListener("test", function onMessage(msg) { + is(msg.data, type, "correct message " + type); + + if (--numLeft == 0) { + mm.removeMessageListener("test", onMessage); + resolve(); + } + }); + }); + } + + /** + * This test ensures that having multiple message manager groups with + * multiple frame loaders in those works as expected. For a specific + * group message manager, frame scripts should only be loaded by its + * descendants and messages should only be received by and from those + * child message managers. + */ + function start() { + var gmm1 = getGroupMessageManager("test1"); + gmm1.loadFrameScript(FRAME_SCRIPT1, true); + + var gmm2 = getGroupMessageManager("test2"); + gmm2.loadFrameScript(FRAME_SCRIPT2, true); + + var promise1 = promiseTwoMessages("group1", gmm1); + var promise2 = promiseTwoMessages("group2", gmm2); + + messageManager.broadcastAsyncMessage("test"); + + Promise.all([promise1, promise2]).then(function () { + opener.setTimeout("next()"); + window.close(); + }); + } + + ]]></script> + + <browser messagemanagergroup="test1" type="content-targetable" src="about:mozilla" /> + <browser messagemanagergroup="test1" type="content-targetable" src="about:mozilla" /> + + <browser messagemanagergroup="test2" type="content-targetable" src="about:mozilla" /> + <browser messagemanagergroup="test2" type="content-targetable" src="about:mozilla" /> + +</window> diff --git a/dom/base/test/chrome/file_bug990812.xul b/dom/base/test/chrome/file_bug990812.xul new file mode 100644 index 0000000000..e14661fe9a --- /dev/null +++ b/dom/base/test/chrome/file_bug990812.xul @@ -0,0 +1,58 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990812 +--> +<window title="Mozilla Bug 990812" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <label value="Mozilla Bug 990812"/> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + var FRAME_SCRIPT_GLOBAL = "data:,sendSyncMessage('test', 'global')"; + var FRAME_SCRIPT_WINDOW = "data:,sendSyncMessage('test', 'window')"; + var FRAME_SCRIPT_GROUP = "data:,sendSyncMessage('test', 'group')"; + + var Cc = Components.classes; + var Ci = Components.interfaces; + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager); + + function is(val, exp, msg) { + opener.wrappedJSObject.is(val, exp, msg); + } + + function start() { + globalMM.loadFrameScript(FRAME_SCRIPT_GLOBAL, true); + messageManager.loadFrameScript(FRAME_SCRIPT_WINDOW, true); + getGroupMessageManager("test").loadFrameScript(FRAME_SCRIPT_GROUP, true); + + var order = ["global", "window", "group"]; + + messageManager.addMessageListener("test", function onMessage(msg) { + var next = order.shift(); + opener.wrappedJSObject.is(msg.data, next, "received test:" + next); + + if (order.length == 0) { + opener.setTimeout("next()"); + window.close(); + } + }); + + var browser = document.createElement("browser"); + browser.setAttribute("messagemanagergroup", "test"); + browser.setAttribute("src", "about:mozilla"); + browser.setAttribute("type", "content-targetable"); + document.documentElement.appendChild(browser); + + globalMM.removeDelayedFrameScript(FRAME_SCRIPT_GLOBAL); + messageManager.removeDelayedFrameScript(FRAME_SCRIPT_WINDOW); + getGroupMessageManager("test").removeDelayedFrameScript(FRAME_SCRIPT_GROUP); + } + + ]]></script> + +</window> diff --git a/dom/base/test/chrome/fileconstructor_file.png b/dom/base/test/chrome/fileconstructor_file.png Binary files differnew file mode 100644 index 0000000000..51e8aaf38c --- /dev/null +++ b/dom/base/test/chrome/fileconstructor_file.png diff --git a/dom/base/test/chrome/frame_bug814638.xul b/dom/base/test/chrome/frame_bug814638.xul new file mode 100644 index 0000000000..3543a42c33 --- /dev/null +++ b/dom/base/test/chrome/frame_bug814638.xul @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=814638 +--> +<window title="Mozilla Bug 814638" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <keyset> + <key key="T" modifiers="control" oncommand="receivedKeyEvent()"/> + </keyset> + + <iframe flex="1" src="about:"/> + +</window> diff --git a/dom/base/test/chrome/frame_registerElement_content.html b/dom/base/test/chrome/frame_registerElement_content.html new file mode 100644 index 0000000000..aa1d75863d --- /dev/null +++ b/dom/base/test/chrome/frame_registerElement_content.html @@ -0,0 +1,5 @@ +<html> +<body> +<x-bar></x-bar> +</body> +</html> diff --git a/dom/base/test/chrome/host_bug814638.xul b/dom/base/test/chrome/host_bug814638.xul new file mode 100644 index 0000000000..081a12578f --- /dev/null +++ b/dom/base/test/chrome/host_bug814638.xul @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=814638 +--> +<window title="Mozilla Bug 814638" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <iframe flex="1" src="frame_bug814638.xul"/> +</window> diff --git a/dom/base/test/chrome/nochrome_bug765993.html b/dom/base/test/chrome/nochrome_bug765993.html new file mode 100644 index 0000000000..158b20c884 --- /dev/null +++ b/dom/base/test/chrome/nochrome_bug765993.html @@ -0,0 +1,3 @@ +<!DOCTYPE HTML> +<html> +</html> diff --git a/dom/base/test/chrome/nochrome_bug765993.js b/dom/base/test/chrome/nochrome_bug765993.js new file mode 100644 index 0000000000..a84113e1e1 --- /dev/null +++ b/dom/base/test/chrome/nochrome_bug765993.js @@ -0,0 +1,4 @@ +//# sourceMappingURL=bar.js.map + +// Define a single function to prevent script source from being gc'd +function foo() {} diff --git a/dom/base/test/chrome/nochrome_bug765993.js^headers^ b/dom/base/test/chrome/nochrome_bug765993.js^headers^ new file mode 100644 index 0000000000..8efacff3c8 --- /dev/null +++ b/dom/base/test/chrome/nochrome_bug765993.js^headers^ @@ -0,0 +1 @@ +X-SourceMap: foo.js.map diff --git a/dom/base/test/chrome/registerElement_ep.js b/dom/base/test/chrome/registerElement_ep.js new file mode 100644 index 0000000000..de32ba51c6 --- /dev/null +++ b/dom/base/test/chrome/registerElement_ep.js @@ -0,0 +1,8 @@ +var proto = Object.create(HTMLElement.prototype); +proto.magicNumber = 42; +proto.createdCallback = function() { + finishTest(this.magicNumber === 42); +}; +document.registerElement("x-foo", { prototype: proto }); + +document.createElement("x-foo"); diff --git a/dom/base/test/chrome/test_bug1063837.xul b/dom/base/test/chrome/test_bug1063837.xul new file mode 100644 index 0000000000..6104295b4d --- /dev/null +++ b/dom/base/test/chrome/test_bug1063837.xul @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=206691 +--> +<window title="Mozilla Bug 1063837" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1063837" + target="_blank">Mozilla Bug 1063837</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 1063837 **/ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + var xhr = new XMLHttpRequest(); + xhr.open("GET", location, false); + xhr.onload = function() { + ok(xhr.responseXML, "We should have response content!"); + var principal = xhr.responseXML.nodePrincipal; + ok(principal.URI.schemeIs("moz-nullprincipal"), "The response document should have a null principal"); + SimpleTest.finish(); + } + xhr.send(); + }); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug1098074_throw_from_ReceiveMessage.xul b/dom/base/test/chrome/test_bug1098074_throw_from_ReceiveMessage.xul new file mode 100644 index 0000000000..ea154ae9c4 --- /dev/null +++ b/dom/base/test/chrome/test_bug1098074_throw_from_ReceiveMessage.xul @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1098074 +--> +<window title="Mozilla Bug 1098074" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 1098074 **/ + SimpleTest.waitForExplicitFinish(); + SimpleTest.expectUncaughtException(); + + // Tell the test to expect exactly one console error with the given parameters, + // with SimpleTest.finish as a continuation function. + SimpleTest.monitorConsole(SimpleTest.finish, [{errorMessage: new RegExp('acopia')}]); + + var Cc = Components.classes; + var Ci = Components.interfaces; + var globalMM = Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager); + globalMM.addMessageListener("flimfniffle", function onMessage(msg) { + globalMM.removeMessageListener("flimfniffle", onMessage); + is(msg.data, "teufeltor", "correct message"); + + // Cleanup the monitor after we throw. + SimpleTest.executeSoon(SimpleTest.endMonitorConsole); + + throw "acopia"; + }); + + function start() { + globalMM.loadFrameScript("data:,sendAsyncMessage('flimfniffle', 'teufeltor')", true); + } + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1098074" + target="_blank">Mozilla Bug 1098074</a> + </body> +</window> diff --git a/dom/base/test/chrome/test_bug1139964.xul b/dom/base/test/chrome/test_bug1139964.xul new file mode 100644 index 0000000000..f0a7cefd7f --- /dev/null +++ b/dom/base/test/chrome/test_bug1139964.xul @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1139964 +--> +<window title="Mozilla Bug 1139964" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1139964" + target="_blank">Mozilla Bug 1139964</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 1139964 **/ + SimpleTest.waitForExplicitFinish(); + + function done() { + SimpleTest.finish(); + } + + addLoadEvent(function() { + window.open("file_bug1139964.xul", "", "chrome"); + }); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug120684.xul b/dom/base/test/chrome/test_bug120684.xul new file mode 100644 index 0000000000..bc2fc8d958 --- /dev/null +++ b/dom/base/test/chrome/test_bug120684.xul @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=120684 +--> +<window title="Mozilla Bug 120684" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=120684" + target="_blank">Mozilla Bug 120684</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 120684 **/ + + var list = new ChromeNodeList(); + is(list.length, 0, "Length should be initially 0."); + + ok(list instanceof NodeList, "ChromeNodeList object should be an instance of NodeList."); + + try { + list.append(document); + ok(false, "should have throw!"); + } catch(ex) { + ok(true, "ChromeNodeList supports only nsIContent objects for now."); + } + + try { + list.remove(document); + ok(false, "should have throw!"); + } catch(ex) { + ok(true, "ChromeNodeList supports only nsIContent objects for now."); + } + is(list.length, 0, "Length should be 0."); + + list.append(document.documentElement); + is(list.length, 1, "Length should be 1."); + is(list[0], document.documentElement); + is(list[1], undefined); + + // Removing element which isn't in the list shouldn't do anything. + list.remove(document.createElement("foo")); + is(list.length, 1, "Length should be 1."); + is(list[0], document.documentElement); + + list.remove(document.documentElement); + is(list.length, 0, "Length should be 0."); + is(list[0], undefined); + + var e1 = document.createElement("foo"); + var e2 = document.createElement("foo"); + var e3 = document.createElement("foo"); + + list.append(e1); + list.append(e2); + list.append(e3); + + is(list[0], e1); + is(list[1], e2); + is(list[2], e3); + is(list.length, 3); + + list.remove(e2); + is(list[0], e1); + is(list[1], e3); + is(list[2], undefined); + is(list.length, 2); + + // A leak test. + list.expando = list; + + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug1209621.xul b/dom/base/test/chrome/test_bug1209621.xul new file mode 100644 index 0000000000..4bca58d986 --- /dev/null +++ b/dom/base/test/chrome/test_bug1209621.xul @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1209621 +--> +<window title="Mozilla Bug 1209621" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1209621" + target="_blank">Mozilla Bug 1209621</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 1209621 **/ + + SimpleTest.waitForExplicitFinish(); + + function done() { + SimpleTest.finish(); + } + + addLoadEvent(function() { + window.open("file_bug1209621.xul", "", "chrome"); + }); + + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug1339722.html b/dom/base/test/chrome/test_bug1339722.html new file mode 100644 index 0000000000..261055dd8c --- /dev/null +++ b/dom/base/test/chrome/test_bug1339722.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1339722 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1339722</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://global/skin"/> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** + * Test for Bug 1339722 + * 1. Wait for "http-on-useragent-request" for the iframe load. + * 2. In the observer, access it's window proxy to trigger DOMWindowCreated. + * 3. In the event handler, delete the iframe so that the frameloader would be + * destoryed in the middle of ReallyStartLoading. + * 4. Verify that it doesn't crash. + **/ + + const {interfaces: Ci, utils: Cu} = Components; + Cu.import("resource://gre/modules/Services.jsm"); + + const TOPIC = 'http-on-useragent-request'; + Services.obs.addObserver({ + observe(subject, topic, data) { + info('Got ' + topic); + Services.obs.removeObserver(this, TOPIC); + + // Query window proxy so it triggers DOMWindowCreated. + let channel = subject.QueryInterface(Ci.nsIHttpChannel); + let win = channel.notificationCallbacks.getInterface(Ci.mozIDOMWindowProxy); + } + }, TOPIC, false); + + let docShell = SpecialPowers.wrap(window) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDocShell); + docShell.chromeEventHandler.addEventListener('DOMWindowCreated', function handler(e) { + docShell.chromeEventHandler.removeEventListener('DOMWindowCreated', handler); + let iframe = document.getElementById('testFrame'); + is(e.target, iframe.contentDocument, 'verify event target'); + + // Remove the iframe to cause frameloader destroy. + iframe.remove(); + setTimeout($ => { + ok(!document.getElementById('testFrame'), 'verify iframe removed'); + SimpleTest.finish(); + }, 0); + }); + + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1339722">Mozilla Bug 1339722</a> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"> + <div id="frameContainer"> + <iframe id="testFrame" src="http://www.example.com"></iframe> + </div> +</pre> +</body> +</html> diff --git a/dom/base/test/chrome/test_bug206691.xul b/dom/base/test/chrome/test_bug206691.xul new file mode 100644 index 0000000000..f6496e2dfa --- /dev/null +++ b/dom/base/test/chrome/test_bug206691.xul @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=206691 +--> +<window title="Mozilla Bug 206691" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=206691" + target="_blank">Mozilla Bug 206691</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 206691 **/ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + var xhr = new XMLHttpRequest(); + xhr.open("GET", location, false); + xhr.send(); + ok(xhr.responseText, "We should have response content!"); + SimpleTest.finish(); + }); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug289714.xul b/dom/base/test/chrome/test_bug289714.xul new file mode 100644 index 0000000000..6d0804784f --- /dev/null +++ b/dom/base/test/chrome/test_bug289714.xul @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=289714 +--> +<window title="Mozilla Bug 289714" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=289714" + target="_blank">Mozilla Bug 289714</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + /** Test for Bug 289714 **/ + + SimpleTest.waitForExplicitFinish(); + + let xhr = new XMLHttpRequest(); + xhr.responseType = "document"; + xhr.open("GET", "data:text/xml,<xml"); + ok(xhr.channel !== undefined, "System XHRs should be privileged"); + xhr.onload = () => { + ok(xhr.responseXML !== null, "System XHRs should yield <parsererrors>"); + SimpleTest.finish(); + }; + xhr.send(); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug339494.xul b/dom/base/test/chrome/test_bug339494.xul new file mode 100644 index 0000000000..a81838450b --- /dev/null +++ b/dom/base/test/chrome/test_bug339494.xul @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=339494 +--> +<window title="Mozilla Bug 339494" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=339494">Mozilla Bug 339494</a> +<p id="display"></p> +<div id="content" style="display: none"> + <xul:hbox id="d"/> + <xul:hbox id="s"/> +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> + +/** Test for Bug 339494 **/ + + var d = document.getElementById("d"); + + d.setAttribute("hhh", "testvalue"); + + document.addEventListener("DOMAttrModified", removeItAgain, false); + d.removeAttribute("hhh"); + document.removeEventListener("DOMAttrModified", removeItAgain, false); + + function removeItAgain() + { + ok(!d.hasAttribute("hhh"), "Value check 1", + "There should be no value"); + isnot(d.getAttribute("hhh"), "testvalue", "Value check 2"); + document.removeEventListener("DOMAttrModified", removeItAgain, false); + d.removeAttribute("hhh"); + ok(true, "Reachability", "We shouldn't have crashed"); + } + + var s = document.getElementById("s"); + + s.setAttribute("ggg", "testvalue"); + + document.addEventListener("DOMAttrModified", compareVal, false); + s.setAttribute("ggg", "othervalue"); + document.removeEventListener("DOMAttrModified", compareVal, false); + + function compareVal() + { + ok(s.hasAttribute("ggg"), "Value check 3", + "There should be a value"); + isnot(s.getAttribute("ggg"), "testvalue", "Value check 4"); + is(s.getAttribute("ggg"), "othervalue", "Value check 5"); + } + +</script> + +</window> diff --git a/dom/base/test/chrome/test_bug357450.xul b/dom/base/test/chrome/test_bug357450.xul new file mode 100644 index 0000000000..7723364ecc --- /dev/null +++ b/dom/base/test/chrome/test_bug357450.xul @@ -0,0 +1,56 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> + +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=357450 +--> + +<window title="Mozilla Bug 357450" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <!-- This file is shared with non-chrome tests --> + <script type="text/javascript" src="file_bug357450.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> + +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=357450" + target="_blank">Mozilla Bug 357450</a> + +<p id="display"></p> + +<div id="content" style="display: block"> + <a class="classtest" name="nametest">hmm</a> + <b class="foo">hmm</b> + <b id="test1" class="test1">hmm</b> + <b id="test2" class="test2">hmm</b> + <b id="int-class" class="1">hmm</b> + <div id="example"> + <p id="p1" class="aaa bbb"/> + <p id="p2" class="aaa ccc"/> + <p id="p3" class="bbb ccc"/> + </div> +</div> +<pre id="test"> +</pre> +</body> + +<svg xmlns="http://www.w3.org/2000/svg" + height="100" width="100" style="float:left"> + + <path d="M38,38c0-12,24-15,23-2c0,9-16,13-16,23v7h11v-4c0-9,17-12,17-27c-2-22-45-22-45,3zM45,70h11v11h-11z" fill="#371"/> + + <circle cx="50" cy="50" r="45" class="classtest" + fill="none" stroke="#371" stroke-width="10"/> + +</svg> + +<xul:label class="classtest" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + hmm +</xul:label> + + +</window> diff --git a/dom/base/test/chrome/test_bug380418.html b/dom/base/test/chrome/test_bug380418.html new file mode 100644 index 0000000000..6fb524e76b --- /dev/null +++ b/dom/base/test/chrome/test_bug380418.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=380418 --> +<head> + <title>Test for Bug 380418</title> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=380418">Mozilla Bug 380418</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var xhrPath = "http://mochi.test:8888" + + window.location.pathname.substring("/content".length); + + var request = new XMLHttpRequest(); + request.open("GET", xhrPath, false); + request.send(null); + + // Try reading headers in privileged context + is(request.getResponseHeader("Set-Cookie"), "test", "Reading Set-Cookie response header in privileged context"); + is(request.getResponseHeader("Set-Cookie2"), "test2", "Reading Set-Cookie2 response header in privileged context"); + is(request.getResponseHeader("X-Dummy"), "test", "Reading X-Dummy response header in privileged context"); + + ok(/\bSet-Cookie:/i.test(request.getAllResponseHeaders()), "Looking for Set-Cookie in all response headers in privileged context"); + ok(/\bSet-Cookie2:/i.test(request.getAllResponseHeaders()), "Looking for Set-Cookie2 in all response headers in privileged context"); + ok(/\bX-Dummy:/i.test(request.getAllResponseHeaders()), "Looking for X-Dummy in all response headers in privileged context"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/chrome/test_bug380418.html^headers^ b/dom/base/test/chrome/test_bug380418.html^headers^ new file mode 100644 index 0000000000..5f8d4969c0 --- /dev/null +++ b/dom/base/test/chrome/test_bug380418.html^headers^ @@ -0,0 +1,4 @@ +Set-Cookie: test +Set-Cookie2: test2 +X-Dummy: test +Cache-Control: max-age=0 diff --git a/dom/base/test/chrome/test_bug383430.html b/dom/base/test/chrome/test_bug383430.html new file mode 100644 index 0000000000..cfb8595ac5 --- /dev/null +++ b/dom/base/test/chrome/test_bug383430.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=383430 +--> +<head> + <title>Test for Bug 383430</title> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=383430">Mozilla Bug 383430</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 383430 **/ + +var req = new XMLHttpRequest(); +req.open("GET", window.location.href); +req.send(null); + +ok(req.channel.loadGroup != null, "loadGroup is not null"); + +req = new XMLHttpRequest(); +req.mozBackgroundRequest = true; +req.open("GET", window.location.href); +req.send(null); + +ok(req.channel.loadGroup == null, "loadGroup is null"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/chrome/test_bug418986-1.xul b/dom/base/test/chrome/test_bug418986-1.xul new file mode 100644 index 0000000000..aa0c340771 --- /dev/null +++ b/dom/base/test/chrome/test_bug418986-1.xul @@ -0,0 +1,26 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=418986-1 +--> +<window title="Mozilla Bug 418986 (Part 1)" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=418986-1" + target="_blank">Mozilla Bug 418986 (Part 1)</a> + + <script type="application/javascript;version=1.7" src="bug418986-1.js"></script> + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + window.onload = function() { + test(false); + }; + ]]></script> + </body> +</window> diff --git a/dom/base/test/chrome/test_bug421622.xul b/dom/base/test/chrome/test_bug421622.xul new file mode 100644 index 0000000000..abbb9f2d59 --- /dev/null +++ b/dom/base/test/chrome/test_bug421622.xul @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=421622 +--> +<window title="Mozilla Bug 421622" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=421622" + target="_blank">Mozilla Bug 421622</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 421622 **/ + const SJS_URL = "http://mochi.test:8888/tests/dom/base/test/chrome/bug421622-referer.sjs"; + const REFERER_URL = "http://www.mozilla.org/"; + + var req = new XMLHttpRequest(); + req.open("GET", SJS_URL, false); + req.setRequestHeader("Referer", REFERER_URL); + req.send(null); + + is(req.responseText, + "Referer: " + REFERER_URL, + "Referer header received by server does not match what was set"); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug429785.xul b/dom/base/test/chrome/test_bug429785.xul new file mode 100644 index 0000000000..5d8af4555b --- /dev/null +++ b/dom/base/test/chrome/test_bug429785.xul @@ -0,0 +1,61 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=429785 +--> +<window title="Mozilla Bug 429785" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=429785" + target="_blank">Mozilla Bug 429785</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + /** Test for Bug 429785 **/ + SimpleTest.waitForExplicitFinish(); + var errorLogged = false; + const serv = Components.classes["@mozilla.org/consoleservice;1"] + .getService(Components.interfaces.nsIConsoleService); + var listener = { + QueryInterface : function(iid) { + if (!iid.equals(Components.interfaces.nsISupports) && + !iid.equals(Components.interfaces.nsIConsoleListener)) { + throw Components.results.NS_NOINTERFACE; + } + return this; + }, + observe : function (msg) { errorLogged = true; } + }; + + function step2() { + is(errorLogged, false, "Should be no errors"); + + serv.logStringMessage("This is a test"); + + setTimeout(step3, 0); + + } + + function step3() { + is(errorLogged, true, "Should see errors when they happen"); + serv.unregisterListener(listener); + SimpleTest.finish(); + } + + serv.registerListener(listener); + + var p = new DOMParser(); + p.parseFromString("<root/>", "application/xml"); + + // nsConsoleService notifies its listeners via async proxies, so we need + // to wait to see whether there was an error reported. + setTimeout(step2, 0); + + + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug430050.xul b/dom/base/test/chrome/test_bug430050.xul new file mode 100644 index 0000000000..b5948fad0c --- /dev/null +++ b/dom/base/test/chrome/test_bug430050.xul @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=430050 +--> +<window title="Mozilla Bug 430050" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=430050" + target="_blank">Mozilla Bug 430050</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 430050 **/ + + function endTest() { + ok(document.getElementById('b').contentDocument.documentElement.textContent == + "succeeded", "Wrong URL loaded!"); + SimpleTest.finish(); + } + + function startTest() { + document.documentElement.addEventListener('DOMAttrModified', + function(evt) { + if (evt.target == evt.currentTarget) { + document.getElementById('b').setAttribute("src", + "data:text/plain,failed"); + document.getElementById('b').loadURI('data:text/plain,succeeded', + null, + 'UTF-8'); + document.getElementById('b').addEventListener("load", endTest); + } + }, true); + document.documentElement.setAttribute("foo", "bar"); + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(startTest); + + ]]></script> + <browser flex="1" id="b"/> +</window> diff --git a/dom/base/test/chrome/test_bug467123.xul b/dom/base/test/chrome/test_bug467123.xul new file mode 100644 index 0000000000..d44cbe4b98 --- /dev/null +++ b/dom/base/test/chrome/test_bug467123.xul @@ -0,0 +1,35 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=467123 +--> +<window title="Mozilla Bug 467123" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=467123" + target="_blank">Mozilla Bug 467123</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 467123 **/ + var xhr = new XMLHttpRequest(); + xhr.open("GET", "chrome://global/content/bindings/button.xml", false); + xhr.send(); + ok(xhr.responseXML, "We should have response document!"); + var e = null; + try { + var clone = xhr.responseXML.cloneNode(true); + } catch (ex) { + e = ex; + } + ok(!e, e); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug549682.xul b/dom/base/test/chrome/test_bug549682.xul new file mode 100644 index 0000000000..8c7376bb57 --- /dev/null +++ b/dom/base/test/chrome/test_bug549682.xul @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=549682 +--> +<window title="Mozilla Bug 549682" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=549682" + target="_blank">Mozilla Bug 549682</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 549682 **/ + SimpleTest.waitForExplicitFinish(); + + function done() { + SimpleTest.finish(); + } + + addLoadEvent(function() { + window.open("file_bug549682.xul", "", "chrome"); + }); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug571390.xul b/dom/base/test/chrome/test_bug571390.xul new file mode 100644 index 0000000000..aebb2cfc8e --- /dev/null +++ b/dom/base/test/chrome/test_bug571390.xul @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=571390 +--> +<window title="Mozilla Bug 571390" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + class="foo bar"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=571390" + target="_blank">Mozilla Bug 571390</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 571390 **/ + + is(document.documentElement.classList.length, 2, "Should have 2 classes."); + ok(document.documentElement.classList.contains("foo"), "Should contain 'foo' class."); + ok(document.documentElement.classList.contains("bar"), "Should contain 'bar' class."); + ok(!document.documentElement.classList.contains("foobar"), "Shouldn't contain 'foobar' class."); + + document.documentElement.classList.add("foobar"); + is(document.documentElement.classList.length, 3, "Should have 3 classes."); + ok(document.documentElement.classList.contains("foo"), "Should contain 'foo' class."); + ok(document.documentElement.classList.contains("bar"), "Should contain 'bar' class."); + ok(document.documentElement.classList.contains("foobar"), "Should contain 'foobar' class."); + + document.documentElement.classList.remove("foobar"); + is(document.documentElement.classList.length, 2, "Should have 2 classes."); + ok(document.documentElement.classList.contains("foo"), "Should contain 'foo' class."); + ok(document.documentElement.classList.contains("bar"), "Should contain 'bar' class."); + ok(!document.documentElement.classList.contains("foobar"), "Shouldn't contain 'foobar' class."); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug616841.xul b/dom/base/test/chrome/test_bug616841.xul new file mode 100644 index 0000000000..9b04eb3b16 --- /dev/null +++ b/dom/base/test/chrome/test_bug616841.xul @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=616841 +--> +<window title="Mozilla Bug 616841" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=616841" + target="_blank">Mozilla Bug 616841</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + function done() { + SimpleTest.finish(); + } + + addLoadEvent(function() { + window.open("file_bug616841.xul", "", "chrome"); + }); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug635835.xul b/dom/base/test/chrome/test_bug635835.xul new file mode 100644 index 0000000000..e06541fb4c --- /dev/null +++ b/dom/base/test/chrome/test_bug635835.xul @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=635835 +--> +<window title="Mozilla Bug 635835" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=635835" + target="_blank">Mozilla Bug 635835</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ +SimpleTest.waitForExplicitFinish(); +const SHOW_ALL = Components.interfaces.nsIDOMNodeFilter.SHOW_ALL; + +addLoadEvent(function() { + var walker = document.createTreeWalker(document, SHOW_ALL, null); + try { + walker.currentNode = {}; + walker.nextNode(); + } + catch (e) { + // do nothing - this is a crash test + } + ok(true, "Crash test passed"); + SimpleTest.finish(); +}); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug682305.html b/dom/base/test/chrome/test_bug682305.html new file mode 100644 index 0000000000..64f36c907f --- /dev/null +++ b/dom/base/test/chrome/test_bug682305.html @@ -0,0 +1,175 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=682305 +--> +<head> + <title>XMLHttpRequest send and channel implemented in JS</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=682305">Mozilla Bug 682305</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> +SimpleTest.waitForExplicitFinish(); + +/* + * Register a custom nsIProtocolHandler service + * in order to be able to implement *and use* an + * nsIChannel component written in Javascript. + */ + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cr = Components.results; +var Cu = Components.utils; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +var SimpleURI = Cc["@mozilla.org/network/simple-uri;1"]; +var ios = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService); +var contentSecManager = Cc["@mozilla.org/contentsecuritymanager;1"] + .getService(Ci.nsIContentSecurityManager); + +var PROTOCOL_SCHEME = "jsproto"; + + +function CustomChannel(uri, loadInfo) { + this.URI = this.originalURI = uri; + this.loadInfo = loadInfo; +} +CustomChannel.prototype = { + URI: null, + originalURI: null, + loadInfo: null, + contentCharset: "utf-8", + contentLength: 0, + contentType: "text/plain", + owner: Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal), + securityInfo: null, + notificationCallbacks: null, + loadFlags: 0, + loadGroup: null, + name: null, + status: Cr.NS_OK, + asyncOpen: function(listener, context) { + let stream = this.open(); + try { + listener.onStartRequest(this, context); + } catch(e) {} + try { + listener.onDataAvailable(this, context, stream, 0, stream.available()); + } catch(e) {} + try { + listener.onStopRequest(this, context, Cr.NS_OK); + } catch(e) {} + }, + asyncOpen2: function(listener) { + // throws an error if security checks fail + var outListener = contentSecManager.performSecurityCheck(this, listener); + return this.asyncOpen(outListener, null); + }, + open: function() { + let data = "bar"; + let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); + stream.setData(data, data.length); + return stream; + }, + open2: function() { + // throws an error if security checks fail + contentSecManager.performSecurityCheck(this, null); + return this.open(); + }, + isPending: function() { + return false; + }, + cancel: function() { + throw Cr.NS_ERROR_NOT_IMPLEMENTED; + }, + suspend: function() { + throw Cr.NS_ERROR_NOT_IMPLEMENTED; + }, + resume: function() { + throw Cr.NS_ERROR_NOT_IMPLEMENTED; + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest]) +}; + + +function CustomProtocol() {} +CustomProtocol.prototype = { + get scheme() { + return PROTOCOL_SCHEME; + }, + get protocolFlags() { + return (Ci.nsIProtocolHandler.URI_NORELATIVE | + Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE | + Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD); + }, + get defaultPort() { + return -1; + }, + allowPort: function allowPort() { + return false; + }, + newURI: function newURI(spec, charset, baseURI) { + var uri = SimpleURI.createInstance(Ci.nsIURI) + uri.spec = spec; + return uri.QueryInterface(Ci.nsIURI); + }, + newChannel2: function newChannel2(URI, loadInfo) { + return new CustomChannel(URI, loadInfo); + }, + newChannel: function newChannel(URI) { + return newChannel2(URI); + }, + QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, + Ci.nsISupportsWeakReference, + Ci.nsIProtocolHandler]) +}; + +var gFactory = { + register: function() { + var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + + var classID = Components.ID("{ed064287-1e76-49ba-a28d-dc74394a8334}"); + var description = PROTOCOL_SCHEME + ": protocol"; + var contractID = "@mozilla.org/network/protocol;1?name=" + PROTOCOL_SCHEME; + var factory = XPCOMUtils._getFactory(CustomProtocol); + + registrar.registerFactory(classID, description, contractID, factory); + + this.unregister = function() { + registrar.unregisterFactory(classID, factory); + delete this.unregister; + }; + } +}; + +// Register the custom procotol handler +gFactory.register(); + +// Then, checks if XHR works with it +var xhr = new XMLHttpRequest(); +xhr.open("GET", PROTOCOL_SCHEME + ":foo", true); +xhr.onload = function () { + is(xhr.responseText, "bar", "protocol doesn't work"); + gFactory.unregister(); + SimpleTest.finish(); +} +try { + xhr.send(null); +} catch(e) { + ok(false, e); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/chrome/test_bug683852.xul b/dom/base/test/chrome/test_bug683852.xul new file mode 100644 index 0000000000..cebc8f3583 --- /dev/null +++ b/dom/base/test/chrome/test_bug683852.xul @@ -0,0 +1,69 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=683852 +--> +<window title="Mozilla Bug 683852" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + <button value="testbutton" id="testbutton"/> + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=683852" + target="_blank" id="link">Mozilla Bug 683852</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 683852 **/ + SimpleTest.waitForExplicitFinish(); + + function startTest() { + is(document.contains(document), true, "Document should contain itself!"); + + var tb = document.getElementById("testbutton"); + is(document.contains(tb), true, "Document should contain element in it!"); + is(tb.contains(tb), true, "Element should contain itself.") + var anon = document.getAnonymousElementByAttribute(tb, "anonid", "button-box"); + is(document.contains(anon), false, "Document should not contain anonymous element in it!"); + is(tb.contains(anon), false, "Element should not contain anonymous element in it!"); + is(anon.contains(anon), true, "Anonymous element should contain itself.") + is(document.documentElement.contains(tb), true, "Element should contain element in it!"); + is(document.contains(document.createElement("foo")), false, "Document shouldn't contain element which is't in the document"); + is(document.contains(document.createTextNode("foo")), false, "Document shouldn't contain text node which is't in the document"); + + var link = document.getElementById("link"); + is(document.contains(link.firstChild), true, + "Document should contain a text node in it."); + is(link.contains(link.firstChild), true, + "Element should contain a text node in it."); + is(link.firstChild.contains(link), false, "text node shouldn't contain its parent."); + + is(document.contains(null), false, "Document shouldn't contain null."); + + var pi = document.createProcessingInstruction("adf", "asd"); + is(pi.contains(document), false, "Processing instruction shouldn't contain document"); + document.documentElement.appendChild(pi); + document.contains(pi, true, "Document should contain processing instruction"); + + var df = document.createRange().createContextualFragment("<div>foo</div>"); + is(df.contains(df.firstChild), true, "Document fragment should contain its child"); + is(df.contains(df.firstChild.firstChild), true, + "Document fragment should contain its descendant"); + is(df.contains(df), true, "Document fragment should contain itself."); + + var d = document.implementation.createHTMLDocument(""); + is(document.contains(d), false, + "Document shouldn't contain another document."); + is(document.contains(d.createElement("div")), false, + "Document shouldn't contain an element from another document."); + + SimpleTest.finish(); + } + + addLoadEvent(startTest); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug752226-3.xul b/dom/base/test/chrome/test_bug752226-3.xul new file mode 100644 index 0000000000..ed3d5c60cb --- /dev/null +++ b/dom/base/test/chrome/test_bug752226-3.xul @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=752226 +--> +<window title="Mozilla Bug 752226" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=752226" + target="_blank">Mozilla Bug 752226</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 752226 **/ + try { + new File(null); + } catch (e) {} + ok(true, "Didn't crash"); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug752226-4.xul b/dom/base/test/chrome/test_bug752226-4.xul new file mode 100644 index 0000000000..d2335f9b8d --- /dev/null +++ b/dom/base/test/chrome/test_bug752226-4.xul @@ -0,0 +1,28 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=752226 +--> +<window title="Mozilla Bug 752226" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=752226" + target="_blank">Mozilla Bug 752226</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 752226 **/ + try { + new Components.utils.Sandbox("about:blank", null); + } catch (e) {} + ok(true, "Didn't crash"); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug765993.html b/dom/base/test/chrome/test_bug765993.html new file mode 100644 index 0000000000..b297c89065 --- /dev/null +++ b/dom/base/test/chrome/test_bug765993.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=765993 +--> +<head> + <title>Test for Bug 765993</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=765993">Mozilla Bug 765993</a> +<style type="text/css"> +#link1 a { -moz-user-select:none; } +</style> +<div id="link1"><a href="http://www.mozilla.org/">link1</a></div> +<div id="link2"><a href="http://www.mozilla.org/">link2</a></div> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 765993 **/ + +Components.utils.import("resource://gre/modules/jsdebugger.jsm"); +addDebuggerToGlobal(this); + +window.onload = function () { + SimpleTest.waitForExplicitFinish(); + + var iframe = document.createElement("iframe"); + iframe.src = "http://mochi.test:8888/tests/dom/base/test/chrome/nochrome_bug765993.html"; + iframe.onload = function () { + var script = iframe.contentWindow.document.createElement("script"); + script.src = "http://mochi.test:8888/tests/dom/base/test/chrome/nochrome_bug765993.js"; + script.onload = function () { + var dbg = new Debugger(iframe.contentWindow); + ok(dbg, "Should be able to create debugger"); + + var scripts = dbg.findScripts({ + url: "http://mochi.test:8888/tests/dom/base/test/chrome/nochrome_bug765993.js" + }); + ok(scripts.length > 0, "Should be able to find script"); + + is(scripts[0].source.sourceMapURL, "foo.js.map"); + SimpleTest.finish(); + } + + iframe.contentWindow.document.body.appendChild(script); + }; + + document.body.appendChild(iframe); +}; + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/chrome/test_bug780199.xul b/dom/base/test/chrome/test_bug780199.xul new file mode 100644 index 0000000000..649538becd --- /dev/null +++ b/dom/base/test/chrome/test_bug780199.xul @@ -0,0 +1,51 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=780199 +--> +<window title="Mozilla Bug 780199" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="test()"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=780199" + target="_blank">Mozilla Bug 780199</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 780199 **/ + + SimpleTest.waitForExplicitFinish(); + + var b; + + function callback(r) { + is(r[0].type, "attributes"); + is(r[0].oldValue, b.getAttribute("src")); + setTimeout(continueTest, 500); + } + + function continueTest() { + // Check that a new page wasn't loaded. + is(b.contentDocument.documentElement.textContent, "testvalue"); + SimpleTest.finish(); + } + + function test() { + b = document.getElementById("b"); + var m = new MutationObserver(callback); + m.observe(b, { attributes: true, attributeOldValue: true }); + b.contentDocument.documentElement.textContent = "testvalue"; + b.setAttribute("src", b.getAttribute("src")); + } + + ]]> + </script> + <browser id="b" src="data:text/plain,initial"/> +</window> diff --git a/dom/base/test/chrome/test_bug780529.xul b/dom/base/test/chrome/test_bug780529.xul new file mode 100644 index 0000000000..f28ed4b78e --- /dev/null +++ b/dom/base/test/chrome/test_bug780529.xul @@ -0,0 +1,40 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=780529 +--> +<window title="Mozilla Bug 780529" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=780529" + target="_blank">Mozilla Bug 780529</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 780529 **/ +var req = new XMLHttpRequest(); +req.open("GET", "", true); +// Have to call send() to get the XHR hooked up as the notification callbacks +req.send(); +var callbacks = req.channel.notificationCallbacks; +var sink = callbacks.getInterface(Components.interfaces.nsIChannelEventSink); +ok(sink instanceof Components.interfaces.nsIChannelEventSink, + "Should be a channel event sink") +ok("asyncOnChannelRedirect" in sink, + "Should have the right methods for an event sink"); + +is(callbacks.getInterface(Components.interfaces.nsIXMLHttpRequest), req, + "Should have the right object"); +sinkReq = sink.QueryInterface(Components.interfaces.nsIInterfaceRequestor); +isnot(sinkReq, callbacks, "Sink should not be the XHR object"); +is(sinkReq.getInterface(Components.interfaces.nsIXMLHttpRequest), req, + "Should have the XHR object now"); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug800386.xul b/dom/base/test/chrome/test_bug800386.xul new file mode 100644 index 0000000000..369e6ed813 --- /dev/null +++ b/dom/base/test/chrome/test_bug800386.xul @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=800386 +--> +<window title="Mozilla Bug 800386" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=800386" + target="_blank">Mozilla Bug 800386</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 800386 **/ + Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + + SimpleTest.waitForExplicitFinish(); + + var triedForwarding = false; + var forwardFailed = false; + + var xhr = new XMLHttpRequest; + var xhr2 = new XMLHttpRequest; + + var eventSink = xhr.getInterface(Components.interfaces.nsIProgressEventSink); + isnot(eventSink, null, "Should get event sink directly!"); + + // Now jump through some hoops to get us a getInterface call from C++ + + var requestor = { + getInterface: function(aIID) { + if (aIID.equals(Components.interfaces.nsIProgressEventSink)) { + triedForwarding = true; + try { + return xhr2.getInterface(aIID); + } catch (e) { + forwardFailed = true; + } + } + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + + QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports, + Components.interfaces.nsIInterfaceRequestor]) + }; + + // HTTP URI so that we get progress callbacks + xhr.open("GET", "http://mochi.test:8888/", false); + xhr.channel.notificationCallbacks = requestor; + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + ok(triedForwarding, + "Should have had an attempt to treat us as a progress event sink"); + ok(!forwardFailed, + "Should have been able to forward getInterface on to the XHR"); + SimpleTest.finish(); + } + } + xhr.send(); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug814638.xul b/dom/base/test/chrome/test_bug814638.xul new file mode 100644 index 0000000000..f507099c98 --- /dev/null +++ b/dom/base/test/chrome/test_bug814638.xul @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=814638 +--> +<window title="Mozilla Bug 814638" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=814638" + target="_blank" id="link">Mozilla Bug 814638</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 814638 **/ + + SimpleTest.waitForExplicitFinish(); + + function startTest() { + let hostURL = "chrome://mochitests/content/chrome/dom/base/test/chrome/host_bug814638.xul"; + let host1 = window.open(hostURL, "_blank", "chrome"); + let host2 = window.open(hostURL, "_blank", "chrome"); + + let isHost1Loaded = isHost2Loaded = false + host1.onload = function() { + isHost1Loaded = true; + if (isHost2Loaded) swapFrames(); + } + host2.onload = function() { + isHost2Loaded = true; + if (isHost1Loaded) swapFrames(); + } + + function swapFrames() { + let iframe1 = host1.document.querySelector("iframe"); + let iframe2 = host2.document.querySelector("iframe"); + iframe2.QueryInterface(Components.interfaces.nsIFrameLoaderOwner); + iframe2.swapFrameLoaders(iframe1); + setTimeout(function() { + iframe2.contentWindow.receivedKeyEvent = receivedKeyEvent; + let innerIframe2 = iframe2.contentDocument.querySelector("iframe"); + let e = innerIframe2.contentDocument.createEvent("KeyboardEvent"); + e.initKeyEvent("keypress", true, true, null, true, false, false, false, 0, "t".charCodeAt(0)); + innerIframe2.contentDocument.documentElement.dispatchEvent(e); + host1.close(); + host2.close(); + }, 0); + } + } + + function receivedKeyEvent() { + ok(true, "Received key event"); + SimpleTest.finish(); + } + + addLoadEvent(startTest); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_bug816340.xul b/dom/base/test/chrome/test_bug816340.xul new file mode 100644 index 0000000000..c6ad12b429 --- /dev/null +++ b/dom/base/test/chrome/test_bug816340.xul @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=816340 +--> +<window title="Mozilla Bug 816340" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=816340" + target="_blank">Mozilla Bug 816340</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + function done() { + SimpleTest.finish(); + } + + addLoadEvent(function() { + window.open("file_bug816340.xul", "", "chrome"); + }); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug884693.xul b/dom/base/test/chrome/test_bug884693.xul new file mode 100644 index 0000000000..6a2be9d733 --- /dev/null +++ b/dom/base/test/chrome/test_bug884693.xul @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=884693 +--> +<window title="Mozilla Bug 884693" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=884693" + target="_blank">Mozilla Bug 884693</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + const SERVER_URL = "http://mochi.test:8888/tests/dom/base/test/chrome/bug884693.sjs"; + const INVALID_XML = "InvalidXML"; + + var { classes: Cc, interfaces: Ci } = Components; + + let consoleService = Cc["@mozilla.org/consoleservice;1"]. + getService(Ci.nsIConsoleService) + + function runTest(status, statusText, body, expectedResponse, expectedMessages) + { + return new Promise((resolve, reject) => { + consoleService.reset(); + + let xhr = new XMLHttpRequest(); + + xhr.onload = () => { + is(xhr.responseText, expectedResponse, "Correct responseText returned"); + + let messages = consoleService.getMessageArray() || []; + is(messages.length, expectedMessages.length, "Got expected message count"); + messages = messages.map(m => m.message).join(","); + for(let message of expectedMessages) { + ok(messages.indexOf(message) >= 0, "Got expected message: " + message); + } + + resolve(); + }; + + xhr.onerror = e => { + reject(e); + }; + + xhr.open("GET", `${SERVER_URL}?${status}&${statusText}&${body}`); + xhr.send(); + }); + } + + SimpleTest.waitForExplicitFinish(); + runTest(204, "No content", "", "", []). + then(() => { return runTest(204, "No content", INVALID_XML, "", []); }). + then(() => { return runTest(304, "Not modified", "", "", []); }). + then(() => { return runTest(304, "Not modified", INVALID_XML, "", []); }). + then(() => { return runTest(200, "OK", "", "", ["no root element found"]); }). + then(() => { return runTest(200, "OK", INVALID_XML, INVALID_XML, ["syntax error"]); }). + then(SimpleTest.finish); + + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_bug914381.html b/dom/base/test/chrome/test_bug914381.html new file mode 100644 index 0000000000..aa463ca9ea --- /dev/null +++ b/dom/base/test/chrome/test_bug914381.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=650776 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 914381</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=914381">Mozilla Bug 914381</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> +const Cc = Components.classes; +const Ci = Components.interfaces; + +function createFileWithData(fileData) { + var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); + var testFile = dirSvc.get("ProfD", Ci.nsIFile); + testFile.append("testBug914381"); + + var outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); + outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate + 0666, 0); + outStream.write(fileData, fileData.length); + outStream.close(); + + return testFile; +} + +/** Test for Bug 914381. File's created in JS using an nsIFile should allow mozGetFullPathInternal calls to succeed **/ +var file = createFileWithData("Test bug 914381"); +var f = File.createFromNsIFile(file); +is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js"); +is(f.mozFullPath, file.path, "mozFullPath returns path if created with nsIFile"); + +f = File.createFromFileName(file.path); +is(f.mozFullPathInternal, undefined, "mozFullPathInternal is undefined from js"); +is(f.mozFullPath, "", "mozFullPath returns blank if created with a string"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/chrome/test_bug990812.xul b/dom/base/test/chrome/test_bug990812.xul new file mode 100644 index 0000000000..4be1734291 --- /dev/null +++ b/dom/base/test/chrome/test_bug990812.xul @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=990812 +--> +<window title="Mozilla Bug 990812" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=990812" + target="_blank">Mozilla Bug 990812</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + var tests = [ + "file_bug990812-1.xul", + "file_bug990812-2.xul", + "file_bug990812-3.xul", + "file_bug990812-4.xul", + "file_bug990812-5.xul", + ]; + + function next() { + if (tests.length > 0) { + var file = tests.shift(); + info("-- running " + file); + window.open(file, "", "chrome"); + } else { + SimpleTest.finish(); + } + } + + addLoadEvent(next); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_cpows.xul b/dom/base/test/chrome/test_cpows.xul new file mode 100644 index 0000000000..acbbebb96f --- /dev/null +++ b/dom/base/test/chrome/test_cpows.xul @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window title="Test CPOWs" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + SimpleTest.waitForExplicitFinish(); + + const PREF_UNSAFE_FORBIDDEN = "dom.ipc.cpows.forbid-unsafe-from-browser"; + SpecialPowers.setBoolPref(PREF_UNSAFE_FORBIDDEN, false); + SimpleTest.registerCleanupFunction(() => { + SpecialPowers.clearUserPref(PREF_UNSAFE_FORBIDDEN); + }); + + function done() { + SimpleTest.finish(); + } + + addLoadEvent(function() { + window.open("cpows_parent.xul", "", "chrome"); + }); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_domparsing.xul b/dom/base/test/chrome/test_domparsing.xul new file mode 100644 index 0000000000..c2a10710d0 --- /dev/null +++ b/dom/base/test/chrome/test_domparsing.xul @@ -0,0 +1,144 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> +<window title="Test for the Mozilla extesion of the DOM Parsing and Serialization API" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=816410" + target="_blank">Mozilla Bug 816410</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript;version=1.7"><![CDATA[ +"use strict"; +/** Test for Bug 816410 **/ + +var Cc = Components.classes; +var Ci = Components.interfaces; + +function throws(a, type, message) { + for (let fn of Array.isArray(a) ? a : [a]) { + try { + fn(); + ok(false, message); + } catch (e) { + if (type) { + is(e.name, type, message); + } else { + ok(true, message); + } + } + } +} + +// DOMParser constructor should not throw for null arguments +new DOMParser(undefined); +new DOMParser(null); + +throws([ + function() { new DOMParser(false); }, + function() { new DOMParser(0); }, + function() { new DOMParser(""); }, + function() { new DOMParser({}); }, +], "TypeError", "DOMParser constructor should throw for extra arguments"); + +{ + let parser = new DOMParser(); + throws(function() { + parser.init(); + }, "NS_ERROR_UNEXPECTED", "init method should throw when DOMParser is created by constructor"); +} + +// XMLSerializer constructor should not throw for extra arguments +new XMLSerializer(undefined); +new XMLSerializer(null); +new XMLSerializer(false); +new XMLSerializer(0); +new XMLSerializer(""); +new XMLSerializer({}); + +runTest(new DOMParser(), new XMLSerializer()); + +{ + let parser = Cc["@mozilla.org/xmlextras/domparser;1"] + .createInstance(Ci.nsIDOMParser); + parser.init(); + throws(function() { + parser.init(); + }, "NS_ERROR_UNEXPECTED", "init method should throw when called twice"); +} + +runTest(Cc["@mozilla.org/xmlextras/domparser;1"] + .createInstance(Ci.nsIDOMParser), + Cc["@mozilla.org/xmlextras/xmlserializer;1"] + .createInstance(Ci.nsIDOMSerializer)); + +function runTest(parser, serializer) { + is(typeof parser.parseFromString, "function", "parseFromString should exist"); + is(typeof parser.parseFromBuffer, "function", "parseFromBuffer should exist"); + is(typeof parser.parseFromStream, "function", "parseFromStream should exist"); + is(typeof parser.init, "function", "init should exist"); + + is(typeof serializer.serializeToString, "function", "serializeToString should exist"); + is(typeof serializer.serializeToStream, "function", "serializeToStream should exist"); + + let tests = [ + {input: "<html></html>", type: "text/html", + expected: '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body></body></html>'}, + {input: "<xml></xml>", type: "text/xml", expected: "<xml/>"}, + {input: "<xml></xml>", type: "application/xml", expected: "<xml/>"}, + {input: "<html></html>", type: "application/xhtml+xml", expected: "<html/>"}, + {input: "<svg></svg>", type: "image/svg+xml", expected: "<svg/>"}, + ]; + for (let t of tests) { + is(serializer.serializeToString(parser.parseFromString(t.input, t.type)), t.expected, + "parseFromString test for " + t.type); + + let ostream = { + write: function(buf, count) { this.data += buf; return count; } + }; + for (let charset of [null, "UTF-8"]) { + ostream.data = ""; + serializer.serializeToStream(parser.parseFromString(t.input, t.type), ostream, charset); + is(ostream.data, t.expected, + "serializeToStream test for " + t.type + ", charset=" + charset); + } + + if (t.type === "text/html") { + // parseFromBuffer and parseFromStream don't support "text/html". + continue; + } + + let array = Array.map(t.input, function(c) { return c.charCodeAt(c); }); + let inputs = [ + {array: array, name: "parseFromBuffer (array)"}, + {array: new Uint8Array(array), name: "parseFromBuffer (Uint8Array)"}, + ]; + for (let input of inputs) { + let a = input.array; + is(serializer.serializeToString(parser.parseFromBuffer(a, a.length, t.type)), t.expected, + input.name + " test for " + t.type); + throws(function() { + parser.parseFromBuffer(a, a.length + 1, t.type); + }, "NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY", + input.name + " should throw if bufLen parameter is greater than actual length" + ); + } + + let istream = Cc["@mozilla.org/io/string-input-stream;1"]. + createInstance(Ci.nsIStringInputStream); + for (let charset of [null, "UTF-8"]) { + istream.setData(t.input, -1); + is(serializer.serializeToString(parser.parseFromStream(istream, charset, t.input.length, t.type)), + t.expected, "parseFromStream test for " + t.type + ", charset=" + charset); + } + } + throws(function() { + parser.parseFromString("<xml></xml>", "foo/bar"); + }, "TypeError", "parseFromString should throw for the unknown type"); +} + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_fileconstructor.xul b/dom/base/test/chrome/test_fileconstructor.xul new file mode 100644 index 0000000000..2399b6ef86 --- /dev/null +++ b/dom/base/test/chrome/test_fileconstructor.xul @@ -0,0 +1,72 @@ +<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet
+ href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=607114.xul
+-->
+<window title="Mozilla Bug 607114"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+<body xmlns="http://www.w3.org/1999/xhtml">
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=607114">
+ Mozilla Bug 607114</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+
+<script class="testbody" type="application/javascript">
+<![CDATA[
+
+/** Test for Bug 607114 **/
+
+var file = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+
+// man I wish this were simpler ...
+file.append("chrome");
+file.append("dom");
+file.append("base");
+file.append("test");
+file.append("chrome");
+file.append("fileconstructor_file.png");
+
+doTest(File.createFromFileName(file.path));
+doTest(File.createFromNsIFile(file));
+function doTest(domfile) {
+ ok(domfile instanceof File, "File() should return a File");
+ is(domfile.type, "image/png", "File should be a PNG");
+ is(domfile.size, 95, "File has size 95 (and more importantly we can read it)");
+}
+
+try {
+ var nonexistentfile = File.createFromFileName("i/sure/hope/this/does/not/exist/anywhere.txt");
+ ok(false, "This should never be reached!");
+} catch (e) {
+ ok(true, "Attempt to construct a non-existent file should fail.");
+}
+
+try {
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+ var dirfile = File.createFromNsIFile(dir);
+ ok(false, "This should never be reached!");
+} catch (e) {
+ ok(true, "Attempt to construct a file from a directory should fail.");
+}
+]]>
+</script>
+
+</window>
diff --git a/dom/base/test/chrome/test_fileconstructor_tempfile.xul b/dom/base/test/chrome/test_fileconstructor_tempfile.xul new file mode 100644 index 0000000000..e2ff3a0d29 --- /dev/null +++ b/dom/base/test/chrome/test_fileconstructor_tempfile.xul @@ -0,0 +1,93 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet + href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=982874 + +Tests building a DOMFile with the "temporary" option and checks that +the underlying file is removed when the DOMFile is gc'ed. +--> +<window title="Mozilla Bug 982874" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=982874"> + Mozilla Bug 982874</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +/** Test for Bug 982874 **/ +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; + +SimpleTest.waitForExplicitFinish(); + +function cleanup(tmp) { + // Force cycle and garbage collection and check that we removed the file. + for (let i = 0; i < 10; i++) { + Cu.forceCC(); + Cu.forceGC(); + } + if (tmp.exists()) { + ok(false, "Failed to remove temporary file!"); + } else { + ok(true, "Temporary file removed when gc-ing the DOMFile"); + } + SimpleTest.finish(); +} + +try { + // Create a file in $TMPDIR/mozilla-temp-files + let tmp = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties) + .get("TmpD", Ci.nsIFile); + tmp.append("mozilla-temp-files"); + tmp.append("test.txt"); + tmp.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600); + + // Add some content to the file. + let fileData = "I'm a temporary file!"; + let outStream = Cc["@mozilla.org/network/file-output-stream;1"] + .createInstance(Ci.nsIFileOutputStream); + outStream.init(tmp, 0x02 | 0x08 | 0x20, // write, create, truncate + 0666, 0); + outStream.write(fileData, fileData.length); + outStream.close(); + + // Create a scoped DOMFile so the gc will happily get rid of it. + { + let dirfile = File.createFromNsIFile(tmp, { temporary: true }); + ok(true, "Temporary File() created"); + let reader = new FileReader(); + reader.readAsArrayBuffer(dirfile); + reader.onload = function(event) { + let buffer = event.target.result; + ok(buffer.byteLength > 0, + "Blob size should be > 0 : " + buffer.byteLength); + cleanup(tmp); + } + } +} catch (e) { + ok(false, "Unable to create the File() object : " + e); + SimpleTest.finish(); +} +]]> +</script> + +</window> diff --git a/dom/base/test/chrome/test_groupedSHistory.xul b/dom/base/test/chrome/test_groupedSHistory.xul new file mode 100644 index 0000000000..23cd4c6adb --- /dev/null +++ b/dom/base/test/chrome/test_groupedSHistory.xul @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1276553 +--> +<window title="Mozilla Bug 1276553" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="loadTest();"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1276553" + target="_blank">Mozilla Bug 1276553</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for GroupedSHistory **/ + SimpleTest.waitForExplicitFinish(); + function loadTest() { + window.open("window_groupedSHistory.xul", "", "width=360,height=240,chrome"); + } + + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_nsITextInputProcessor.xul b/dom/base/test/chrome/test_nsITextInputProcessor.xul new file mode 100644 index 0000000000..23ad3e249d --- /dev/null +++ b/dom/base/test/chrome/test_nsITextInputProcessor.xul @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window title="Testing nsITextInputProcessor behavior" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + +<body xmlns="http://www.w3.org/1999/xhtml"> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +SimpleTest.waitForExplicitFinish(); +window.open("window_nsITextInputProcessor.xul", "_blank", + "chrome,width=600,height=600"); + +]]> +</script> +</window> diff --git a/dom/base/test/chrome/test_range_getClientRectsAndTexts.html b/dom/base/test/chrome/test_range_getClientRectsAndTexts.html new file mode 100644 index 0000000000..5d8dc5a6e5 --- /dev/null +++ b/dom/base/test/chrome/test_range_getClientRectsAndTexts.html @@ -0,0 +1,60 @@ +<html> +<head> +<meta charset="utf-8"> +<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +<script> +'use strict'; + +SimpleTest.waitForExplicitFinish(); + +function runTests() +{ + let range = document.createRange(); + + let attempts = [ + {startNode: "one", start:0, endNode:"one", end:0, textList:[], message:"Empty rect"}, + {startNode: "one", start:2, endNode:"one", end:6, textList:["l on"], message:"Single line"}, + {startNode: "implicit", start:6, endNode:"implicit", end:12, textList:["it\nbre"], message:"Implicit break"}, + {startNode: "two.a", start:1, endNode:"two.b", end:2, textList:["wo", "", "li"], message:"Two lines"}, + {startNode: "embed.a", start:7, endNode:"embed.b", end:2, textList:["th ", "simple nested", " ", "te"], message:"Simple nested"}, + {startNode: "deep.a", start:2, endNode:"deep.b", end:2, textList:["ne with ", "complex, more deeply nested", " ", "te"], message:"Complex nested"}, + {startNode: "image.a", start:7, endNode:"image.b", end:2, textList:["th inline ", "", " ", "im"], message:"Inline image"}, + ]; + + for (let attempt of attempts) { + range.setStart(document.getElementById(attempt.startNode).childNodes[0], attempt.start); + range.setEnd(document.getElementById(attempt.endNode).childNodes[0], attempt.end); + + let result = range.getClientRectsAndTexts(); + + is(result.textList.length, attempt.textList.length, attempt.message + " range has expected number of texts."); + let i = 0; + for (let text of result.textList) { + is(text, attempt.textList[i], attempt.message + " matched text index " + i + "."); + i++; + } + } + + SimpleTest.finish(); +} +</script> +</head> +<body onLoad="runTests()"> + +<div id="one">All on one line</div> + +<div id="implicit">Implicit +break in one line</div> + +<div id="two.a">Two<br/ +><span id="two.b">lines</span></div> + +<div id="embed.a">Line with <span>simple nested</span> <span id="embed.b">text</span></div> + +<div id="deep.a">Line with <span>complex, <span>more <span>deeply <span>nested</span></span></span></span> <span id="deep.b">text</span></div> + +<div id="image.a">Line with inline <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAG0lEQVR42mP8z0A%2BYKJA76jmUc2jmkc1U0EzACKcASfOgGoMAAAAAElFTkSuQmCC" width="20" height="20"/> <span id="image.b">image</span></div> + +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/chrome/test_registerElement_content.xul b/dom/base/test/chrome/test_registerElement_content.xul new file mode 100644 index 0000000000..9a918f2d77 --- /dev/null +++ b/dom/base/test/chrome/test_registerElement_content.xul @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1130028 +--> +<window title="Mozilla Bug 1130028" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1130028" + target="_blank">Mozilla Bug 1130028</a> + <iframe onload="startTests()" id="frame" src="http://example.com/chrome/dom/base/test/chrome/frame_registerElement_content.html"></iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + /** Test for Bug 1130028 **/ + SimpleTest.waitForExplicitFinish(); + + var createdCallbackCount = 0; + + // Callback should be called once by element created in chrome, + // and once by element created in content. + function createdCallbackCalled() { + createdCallbackCount++; + ok(true, "Created callback called, should be called twice in test."); + is(this.magicNumber, 42, "Callback should be able to see the custom prototype."); + if (createdCallbackCount == 2) { + SimpleTest.finish(); + } + } + + function startTests() { + var frame = $("frame"); + + var c = frame.contentDocument.registerElement("x-foo"); + var elem = new c(); + is(elem.tagName, "X-FOO", "Constructor should create an x-foo element."); + + var proto = Object.create(frame.contentWindow.HTMLElement.prototype); + proto.magicNumber = 42; + proto.createdCallback = createdCallbackCalled; + frame.contentDocument.registerElement("x-bar", { prototype: proto }); + + frame.contentDocument.createElement("x-bar"); + } + + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_registerElement_ep.xul b/dom/base/test/chrome/test_registerElement_ep.xul new file mode 100644 index 0000000000..6f17452685 --- /dev/null +++ b/dom/base/test/chrome/test_registerElement_ep.xul @@ -0,0 +1,44 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1130028 +--> +<window title="Mozilla Bug 1130028" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1130028" + target="_blank">Mozilla Bug 1130028</a> + <iframe onload="startTests()" id="frame" src="http://example.com/chrome/dom/base/test/chrome/frame_registerElement_content.html"></iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + + Components.utils.import("resource://gre/modules/Services.jsm"); + + /** Test for Bug 1130028 **/ + SimpleTest.waitForExplicitFinish(); + + function finishTest(canSeePrototype) { + ok(true, "createdCallback called when reigsterElement was called with an extended principal."); + ok(canSeePrototype, "createdCallback should be able to see custom prototype."); + SimpleTest.finish(); + } + + function startTests() { + var frame = $("frame"); + + // Create a sandbox with an extended principal then run a script that registers a custom element in the sandbox. + var sandbox = Components.utils.Sandbox([frame.contentWindow], { sandboxPrototype: frame.contentWindow }); + sandbox.finishTest = finishTest; + Services.scriptloader.loadSubScript("chrome://mochitests/content/chrome/dom/base/test/chrome/registerElement_ep.js", sandbox); + } + + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_swapFrameLoaders.xul b/dom/base/test/chrome/test_swapFrameLoaders.xul new file mode 100644 index 0000000000..2f69d390f7 --- /dev/null +++ b/dom/base/test/chrome/test_swapFrameLoaders.xul @@ -0,0 +1,25 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1242644 +Test swapFrameLoaders with different frame types and remoteness +--> +<window title="Mozilla Bug 1242644" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1242644" + target="_blank">Mozilla Bug 1242644</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + SimpleTest.waitForExplicitFinish(); + + window.open("window_swapFrameLoaders.xul", "bug1242644", + "chrome,width=600,height=600"); + ]]></script> +</window> diff --git a/dom/base/test/chrome/test_title.xul b/dom/base/test/chrome/test_title.xul new file mode 100644 index 0000000000..6fa145bc60 --- /dev/null +++ b/dom/base/test/chrome/test_title.xul @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=481777 +--> +<window title="Mozilla Bug 481777" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=481777" + target="_blank">Mozilla Bug 481777</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 481777 **/ + + SimpleTest.waitForExplicitFinish(); + window.open("title_window.xul", "bug481777", + "chrome,width=100,height=100"); + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/test_windowroot.xul b/dom/base/test/chrome/test_windowroot.xul new file mode 100644 index 0000000000..c9ff7f0b50 --- /dev/null +++ b/dom/base/test/chrome/test_windowroot.xul @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window title="Test window.windowRoot" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + </body> + + <!-- test code goes here --> + <script type="application/javascript"><![CDATA[ + var root = window.windowRoot; + ok(root instanceof WindowRoot, "windowRoot should be a WindowRoot"); + ]]></script> +</window> diff --git a/dom/base/test/chrome/title_window.xul b/dom/base/test/chrome/title_window.xul new file mode 100644 index 0000000000..5db180f8bf --- /dev/null +++ b/dom/base/test/chrome/title_window.xul @@ -0,0 +1,198 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<window title="Mozilla Bug 481777 subwindow" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="runTests()"> + + <iframe type="content" id="html1" src="data:text/html,<html><head><title id='t'>Test</title></head></html>"/> + <iframe type="content" id="html2" src="data:text/html,<html><head><title id='t'>Test</title><title>Foo</title></head></html>"/> + <iframe type="content" id="html3" src="data:text/html,<html></html>"/> + <iframe type="content" id="xhtml1" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><title id='t'>Test</title></body></html>"/> + <iframe type="content" id="xhtml2" src="data:text/xml,<title xmlns='http://www.w3.org/1999/xhtml'>Test</title>"/> + <iframe type="content" id="xhtml3" src="data:text/xml,<title xmlns='http://www.w3.org/1999/xhtml'>Te<div>bogus</div>st</title>"/> + <iframe type="content" id="xhtml4" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'/>"/> + <iframe type="content" id="xhtml5" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'><head/></html>"/> + <iframe type="content" id="xhtml6" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'><head><style/></head></html>"/> + <iframe id="xul1" src="data:application/vnd.mozilla.xul+xml,<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"/> + <iframe id="xul2" src="data:application/vnd.mozilla.xul+xml,<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"/> + <iframe type="content" id="svg1" src="data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><title id='t'>Test</title></svg>"/> + <iframe type="content" id="svg2" src="data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><title id='t'>Test</title></svg>"/> + + <script type="application/javascript"> + <![CDATA[ + var imports = [ "SimpleTest", "is", "isnot", "ok" ]; + for (var name of imports) { + window[name] = window.opener.wrappedJSObject[name]; + } + + function testStatics() { + function testStatic(id, expect, description) { + is(document.getElementById(id).contentDocument.title, expect, description); + } + + testStatic("html1", "Test", "HTML <title>"); + testStatic("html2", "Test", "choose the first HTML <title>"); + testStatic("html3", "", "No title"); + testStatic("xhtml1", "Test", "XHTML <title> in body"); + testStatic("xhtml2", "Test", "XHTML <title> as root element"); + testStatic("xhtml3", "Test", "XHTML <title> containing an element"); + testStatic("xul1", "Test", "XUL <window> title attribute"); + testStatic("svg1", "Test", "SVG <title>"); + + // This one does nothing and won't fire an event + document.getElementById("xhtml4").contentDocument.title = "Hello"; + is(document.getElementById("xhtml4").contentDocument.title, "", "Setting 'title' does nothing with no <head>"); + } + + function testDynamics() { + var inProgress = {}; + var inProgressDoc = {}; + var inProgressWin = {}; + function testDynamic(id, expect, description, op, checkDOM) { + inProgress[description] = true; + inProgressDoc[description] = true; + inProgressWin[description] = true; + var frame = document.getElementById(id); + var done = false; + + function listener(ev) { + inProgress[description] = false; + is(frame.contentDocument.title, expect, "'title': " + description); + is(frame.contentDocument, ev.target, "Unexpected target: " + description); + if (typeof(checkDOM) != "undefined") { + checkDOM(frame.contentDocument, "DOM: " + description); + } + } + + function listener2(ev) { + inProgressDoc[description] = false; + } + function listener3(ev) { + inProgressWin[description] = false; + } + frame.addEventListener("DOMTitleChanged", listener, false); + frame.contentDocument.addEventListener("DOMTitleChanged", listener2, false); + frame.contentWindow.addEventListener("DOMTitleChanged", listener3, false); + + op(frame.contentDocument); + } + + var dynamicTests = [ + [ "html1", "Hello", "Setting HTML <title> text contents", + function(doc){ + var t = doc.getElementById("t"); t.textContent = "Hello"; + } ], + [ "html2", "Foo", "Removing HTML <title>", + function(doc){ + var t = doc.getElementById("t"); t.parentNode.removeChild(t); + } ], + [ "html3", "Hello", "Appending HTML <title> element to root element", + function(doc){ + var t = doc.createElement("title"); t.textContent = "Hello"; doc.documentElement.appendChild(t); + } ], + [ "xhtml3", "Hello", "Setting 'title' clears existing <title> contents", + function(doc){ + doc.title = "Hello"; + }, + function(doc, desc) { + is(doc.documentElement.firstChild.data, "Hello", desc); + is(doc.documentElement.firstChild.nextSibling, null, desc); + } ], + [ "xhtml5", "Hello", "Setting 'title' works with a <head>", + function(doc){ + doc.title = "Hello"; + }, + function(doc, desc) { + var head = doc.documentElement.firstChild; + var title = head.firstChild; + is(title.tagName.toLowerCase(), "title", desc); + is(title.firstChild.data, "Hello", desc); + is(title.firstChild.nextSibling, null, desc); + is(title.nextSibling, null, desc); + } ], + [ "xhtml6", "Hello", "Setting 'title' appends to <head>", + function(doc){ + doc.title = "Hello"; + }, + function(doc, desc) { + var head = doc.documentElement.firstChild; + is(head.firstChild.tagName.toLowerCase(), "style", desc); + var title = head.firstChild.nextSibling; + is(title.tagName.toLowerCase(), "title", desc); + is(title.firstChild.data, "Hello", desc); + is(title.firstChild.nextSibling, null, desc); + is(title.nextSibling, null, desc); + } ], + [ "xul1", "Hello", "Setting XUL <window> title attribute", + function(doc){ + doc.documentElement.setAttribute("title", "Hello"); + } ], + [ "xul2", "Hello", "Setting 'title' in XUL", + function(doc){ + doc.title = "Hello"; + }, + function(doc, desc) { + is(doc.documentElement.getAttribute("title"), "Hello", desc); + is(doc.documentElement.firstChild, null, desc); + } ], + [ "svg1", "Hello", "Setting SVG <title> text contents", + function(doc){ + var t = doc.getElementById("t"); t.textContent = "Hello"; + } ], + [ "svg2", "", "Removing SVG <title>", + function(doc){ + var t = doc.getElementById("t"); t.parentNode.removeChild(t); + } ] ]; + + var titleWindow = window; + + function runIndividualTest(i) { + if (i == dynamicTests.length) { + // Closing the window will nuke the global properties, since this + // function is not really running on this window... or something + // like that. Thanks, executeSoon! + var tester = SimpleTest; + window.close(); + tester.finish(); + } else { + var parameters = dynamicTests[i]; + var testElementId = parameters[0]; + var testExpectedValue = parameters[1]; + var testDescription = parameters[2]; + var testOp = parameters[3]; + var testCheckDOM = parameters[4]; + + function checkTest() { + ok(!inProgress[testDescription], + testDescription + ": DOMTitleChange not fired"); + ok(inProgressDoc[testDescription], + testDescription + ": DOMTitleChange fired on content document"); + ok(inProgressWin[testDescription], + testDescription + ": DOMTitleChange fired on content window"); + // Run the next test in the context of the parent XUL window. + titleWindow.setTimeout(runIndividualTest, 0, i+1); + } + function spinEventLoopOp(doc) { + // Perform the test's operations. + testOp(doc); + // Spin the associated window's event loop to ensure we + // drain any asynchronous changes and fire associated + // events. + doc.defaultView.setTimeout(checkTest, 0); + } + + testDynamic(testElementId, testExpectedValue, testDescription, + spinEventLoopOp, testCheckDOM); + } + } + + window.setTimeout(runIndividualTest, 0, 0); + } + + function runTests() { + testStatics(); + testDynamics(); + } + ]]> + </script> +</window> diff --git a/dom/base/test/chrome/window_groupedSHistory.xul b/dom/base/test/chrome/window_groupedSHistory.xul new file mode 100644 index 0000000000..aafa991ba4 --- /dev/null +++ b/dom/base/test/chrome/window_groupedSHistory.xul @@ -0,0 +1,343 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1276553 +--> +<window title="Mozilla Bug 1276553" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="run();"> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + const {interfaces: Ci, classes: Cc, results: Cr, utils: Cu} = Components; + Cu.import("resource://testing-common/TestUtils.jsm"); + Cu.import("resource://testing-common/ContentTask.jsm"); + Cu.import("resource://testing-common/BrowserTestUtils.jsm"); + Cu.import("resource://gre/modules/Task.jsm"); + ContentTask.setTestScope(window.opener.wrappedJSObject); + + let imports = ['SimpleTest', 'SpecialPowers', 'ok', 'is', 'info']; + for (let name of imports) { + window[name] = window.opener.wrappedJSObject[name]; + } + + /** Test for Bug 1276553 **/ + function run() { + new Promise(resolve => SpecialPowers.pushPrefEnv( + {'set' : [[ 'browser.groupedhistory.enabled', true ]]}, resolve)) + .then(() => test(false)) + .then(() => test(true)) + .then(() => { + window.close(); + SimpleTest.finish(); + }); + } + + function test(remote) { + let act, bg1, bg2; + return Promise.resolve() + + // create first browser with 1 entry (which will always be the active one) + .then(() => info('TEST-INFO | test create active browser, remote=' + remote)) + .then(() => createBrowser('pen', remote)) + .then(b => act = b) + .then(() => verifyBrowser(act, 'pen' /* title */, + 0 /* index */, + 1 /* length */, + false /* canGoBack */, + false /* canGoForward */, + false /* partial */ )) + + // create background browser 1 with 1 entry + .then(() => info('TEST-INFO | test create background browser 1, remote=' + remote)) + .then(() => createBrowser('pineapple', remote)) + .then(b => bg1 = b) + .then(() => verifyBrowser(bg1, 'pineapple' /* title */, + 0 /* index */, + 1 /* length */, + false /* canGoBack */, + false /* canGoForward */, + false /* partial */ )) + + // create background browser 2 with 2 entries + .then(() => info('TEST-INFO | test create background browser 2, remote=' + remote)) + .then(() => createBrowser('apple', remote)) + .then(b => bg2 = b) + .then(() => verifyBrowser(bg2, 'apple' /* title */, + 0 /* index */, + 1 /* length */, + false /* canGoBack */, + false /* canGoForward */, + false /* partial */ )) + .then(() => loadURI(bg2, getDummyHtml('pencil'))) + .then(() => verifyBrowser(bg2, 'pencil' /* title */, + 1 /* index */, + 2 /* length */, + true /* canGoBack */, + false /* canGoForward */, + false /* partial */ )) + + // merge to 2 entries pen-pineapple + .then(() => info('TEST-INFO | test merge history, remote=' + remote)) + .then(() => mergeHistory(act, bg1)) + .then(() => verifyBrowser(act, 'pineapple' /* title */, + 0 /* index */, + 1 /* length */, + true /* canGoBack */, + false /* canGoForward */, + true /* partial */, + 1 /* offset */, + 2 /* globalLength */ )) + + // merge to 4 entries pen-pineapple-apple-pencil + .then(() => mergeHistory(act, bg2)) + .then(() => verifyBrowser(act, 'pencil' /* title */, + 1 /* index */, + 2 /* length */, + true /* canGoBack */, + false /* canGoForward */, + true /* partial */, + 2 /* offset */, + 4 /* globalLength */ )) + + // test go back + .then(() => info('TEST-INFO | test history go back, remote=' + remote)) + .then(() => wrapHistoryNavFn(act, act.goBack.bind(act))) + .then(() => verifyBrowser(act, 'apple' /* title */, + 0 /* index */, + 2 /* length */, + true /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 2 /* offset */, + 4 /* globalLength */ )) + // XXX The 2nd pageshow comes from reload as current index of the active + // partial history remains the same + .then(() => wrapHistoryNavFn(act, act.goBack.bind(act), true)) + .then(() => verifyBrowser(act, 'pineapple' /* title */, + 0 /* index */, + 1 /* length */, + true /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 1 /* offset */, + 4 /* globalLength */ )) + .then(() => wrapHistoryNavFn(act, act.goBack.bind(act), true)) + .then(() => verifyBrowser(act, 'pen' /* title */, + 0 /* index */, + 1 /* length */, + false /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 0 /* offset */, + 4 /* globalLength */ )) + + // test go forward + .then(() => info('TEST-INFO | test history go forward, remote=' + remote)) + .then(() => wrapHistoryNavFn(act, act.goForward.bind(act), true)) + .then(() => verifyBrowser(act, 'pineapple' /* title */, + 0 /* index */, + 1 /* length */, + true /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 1 /* offset */, + 4 /* globalLength */ )) + .then(() => wrapHistoryNavFn(act, act.goForward.bind(act), true)) + .then(() => verifyBrowser(act, 'apple' /* title */, + 0 /* index */, + 2 /* length */, + true /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 2 /* offset */, + 4 /* globalLength */ )) + .then(() => wrapHistoryNavFn(act, act.goForward.bind(act))) + .then(() => verifyBrowser(act, 'pencil' /* title */, + 1 /* index */, + 2 /* length */, + true /* canGoBack */, + false /* canGoForward */, + true /* partial */, + 2 /* offset */, + 4 /* globalLength */ )) + + // test goto index + .then(() => info('TEST-INFO | test history goto index, remote=' + remote)) + .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 0), true)) + .then(() => verifyBrowser(act, 'pen' /* title */, + 0 /* index */, + 1 /* length */, + false /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 0 /* offset */, + 4 /* globalLength */ )) + // expect 2 pageshow since we're also changing mIndex of the partial history + .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 2), true, 2)) + .then(() => verifyBrowser(act, 'apple' /* title */, + 0 /* index */, + 2 /* length */, + true /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 2 /* offset */, + 4 /* globalLength */ )) + .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 1), true)) + .then(() => verifyBrowser(act, 'pineapple' /* title */, + 0 /* index */, + 1 /* length */, + true /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 1 /* offset */, + 4 /* globalLength */ )) + // expect 2 pageshow since we're also changing mIndex of the partial history + .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 3), true, 2)) + .then(() => verifyBrowser(act, 'pencil' /* title */, + 1 /* index */, + 2 /* length */, + true /* canGoBack */, + false /* canGoForward */, + true /* partial */, + 2 /* offset */, + 4 /* globalLength */ )) + + // test history change to 3 entries pen-pineapple-banana + .then(() => info('TEST-INFO | test history change, remote=' + remote)) + .then(() => wrapHistoryNavFn(act, act.gotoIndex.bind(act, 1), true)) + .then(() => verifyBrowser(act, 'pineapple' /* title */, + 0 /* index */, + 1 /* length */, + true /* canGoBack */, + true /* canGoForward */, + true /* partial */, + 1 /* offset */, + 4 /* globalLength */ )) + .then(() => loadURI(act, getDummyHtml('banana'))) + .then(() => verifyBrowser(act, 'banana' /* title */, + 1 /* index */, + 2 /* length */, + true /* canGoBack */, + false /* canGoForward */, + true /* partial */, + 1 /* offset */, + 3 /* globalLength */ )) + } + + function getDummyHtml(title) { + return 'data:text/html;charset=UTF-8,' + + '<html><head><title>' + title + '</title></head></html>' + } + + function createBrowser(title, remote) { + let browser = document.createElement('browser'); + browser.setAttribute('type', 'content'); + browser.setAttribute('remote', remote); + browser.setAttribute('src', getDummyHtml(title)); + document.getElementById('stack').appendChild(browser); + return BrowserTestUtils.browserLoaded(browser) + .then(() => { + browser.messageManager.loadFrameScript('data:,' + + 'addEventListener("pageshow", () => sendAsyncMessage("test:pageshow", null), false);' + + 'addEventListener("pagehide", () => sendAsyncMessage("test:pagehide", null), false);', + true); + }) + .then(() => { + // a trick to ensure webProgress object is created for e10s case + ok(browser.webProgress, 'check browser.webProgress exists'); + return browser; + }); + } + + function loadURI(browser, uri) { + let promise = BrowserTestUtils.browserLoaded(browser, false, uri); + browser.loadURI(uri); + return promise; + } + + function mergeHistory(b1, b2) { + let promises = []; + let pagehide1, pagehide2; + + // For swapping there should be a pagehide followed by a pageshow. + promises.push(BrowserTestUtils.waitForMessage(b1.messageManager, 'test:pagehide', msg => pagehide1 = true)); + promises.push(BrowserTestUtils.waitForMessage(b2.messageManager, 'test:pagehide', msg => pagehide2 = true)); + promises.push(BrowserTestUtils.waitForMessage(b1.messageManager, 'test:pageshow', msg => pagehide1)); + promises.push(BrowserTestUtils.waitForMessage(b2.messageManager, 'test:pageshow', msg => pagehide2)); + + // For swapping remote browsers, we'll also receive Content:LocationChange + if (b1.isRemoteBrowser) { + promises.push(BrowserTestUtils.waitForMessage(b1.messageManager, 'Content:LocationChange')); + } + + promises.push(Promise.resolve().then(() => { + let f1 = b1.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader; + let f2 = b2.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader; + f1.appendPartialSessionHistoryAndSwap(f2); + })); + + return Promise.all(promises); + } + + function wrapHistoryNavFn(browser, navFn, expectSwap = false, expectPageshowCount = 1) { + let promises = []; + let pagehide = false; + let pageshowCount = 0; + + if (expectSwap) { + // For swapping there should be a pagehide followed by a pageshow. + promises.push(BrowserTestUtils.waitForMessage(browser.messageManager, + 'test:pagehide', msg => pagehide = true)); + + // For swapping remote browsers, we'll also receive Content:LocationChange + if (browser.isRemoteBrowser) { + promises.push(BrowserTestUtils.waitForMessage(browser.messageManager, + 'Content:LocationChange')); + } + } + promises.push(BrowserTestUtils.waitForMessage(browser.messageManager, + 'test:pageshow', msg => { + // Only count events after pagehide for swapping case. + if (!expectSwap || pagehide) { + return !--expectPageshowCount; + } + return false; + })); + promises.push(Task.spawn(navFn)); + + return Promise.all(promises); + } + + function verifyBrowser(browser, title, index, length, canGoBack, canGoForward, + partial, offset = 0, globalLength = length) { + is(browser.canGoBack, canGoBack, 'check browser.canGoBack'); + is(browser.canGoForward, canGoForward, 'check browser.canGoForward'); + if (partial) { + let frameLoader = browser.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader; + is(frameLoader.groupedSessionHistory.count, globalLength, 'check groupedSHistory.count'); + } + + return ContentTask.spawn(browser, + { title, index, length, canGoBack, canGoForward, partial, offset, globalLength }, + ({ title, index, length, canGoBack, canGoForward, partial, offset, globalLength }) => { + let webNav = docShell.QueryInterface(Ci.nsIWebNavigation); + let shistory = webNav.sessionHistory; + is(content.document.title, title, 'check title'); + is(webNav.canGoBack, canGoBack, 'check webNav.canGoBack'); + is(webNav.canGoForward, canGoForward, 'check webNav.canGoForward'); + is(shistory.index, index, 'check shistory.index'); + is(shistory.count, length, 'check shistory.count'); + is(shistory.isPartial, partial, 'check shistory.isPartial'); + is(shistory.globalIndexOffset, offset, 'check shistory.globalIndexOffset'); + is(shistory.globalCount, globalLength, 'check shistory.globalCount'); + }); + } + + ]]> + </script> + <stack id="stack" flex="1" /> +</window> diff --git a/dom/base/test/chrome/window_nsITextInputProcessor.xul b/dom/base/test/chrome/window_nsITextInputProcessor.xul new file mode 100644 index 0000000000..ce6bfe3db2 --- /dev/null +++ b/dom/base/test/chrome/window_nsITextInputProcessor.xul @@ -0,0 +1,4027 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" + type="text/css"?> +<window title="Testing nsITextInputProcessor behavior" + xmlns:html="http://www.w3.org/1999/xhtml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onunload="onunload();"> +<script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> +<body xmlns="http://www.w3.org/1999/xhtml"> +<p id="display"> +<input id="input" type="text"/><br/> +<iframe id="iframe" width="300" height="150" + src="data:text/html,<textarea id='textarea' cols='20' rows='4'></textarea>"></iframe><br/> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> + +<script class="testbody" type="application/javascript"> +<![CDATA[ + +var SpecialPowers = window.opener.wrappedJSObject.SpecialPowers; +var SimpleTest = window.opener.wrappedJSObject.SimpleTest; + +SimpleTest.waitForFocus(runTests, window); + +function ok(aCondition, aMessage) +{ + SimpleTest.ok(aCondition, aMessage); +} + +function is(aLeft, aRight, aMessage) +{ + SimpleTest.is(aLeft, aRight, aMessage); +} + +function isnot(aLeft, aRight, aMessage) +{ + SimpleTest.isnot(aLeft, aRight, aMessage); +} + +function todo_is(aLeft, aRight, aMessage) +{ + SimpleTest.todo_is(aLeft, aRight, aMessage); +} + +function finish() +{ + window.close(); +} + +function onunload() +{ + SimpleTest.finish(); +} + +var iframe = document.getElementById("iframe"); +var childWindow = iframe.contentWindow; +var textareaInFrame; +var input = document.getElementById("input"); +var otherWindow = window.opener; +var otherDocument = otherWindow.document; +var inputInChildWindow = otherDocument.getElementById("input"); + +function createTIP() +{ + return Components.classes["@mozilla.org/text-input-processor;1"]. + createInstance(Components.interfaces.nsITextInputProcessor); +} + +function runBeginInputTransactionMethodTests() +{ + var description = "runBeginInputTransactionMethodTests: "; + input.value = ""; + input.focus(); + + var simpleCallback = function (aTIP, aNotification) + { + switch (aNotification.type) { + case "request-to-commit": + aTIP.commitComposition(); + break; + case "request-to-cancel": + aTIP.cancelComposition(); + break; + } + return true; + }; + + var TIP1 = createTIP(); + var TIP2 = createTIP(); + isnot(TIP1, TIP2, + description + "TIP instances should be different"); + + // beginInputTransaction() and beginInputTransactionForTests() can take ownership if there is no composition. + ok(TIP1.beginInputTransaction(window, simpleCallback), + description + "TIP1.beginInputTransaction(window) should succeed because there is no composition"); + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests(window) should succeed because there is no composition"); + ok(TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2.beginInputTransaction(window) should succeed because there is no composition"); + ok(TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests(window) should succeed because there is no composition"); + + // Start composition with TIP1, then, other TIPs cannot take ownership during a composition. + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition"); + var composingStr = "foo"; + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + ok(TIP1.flushPendingComposition(), + description + "TIP1.flushPendingComposition() should return true becuase it should be valid composition"); + is(input.value, composingStr, + description + "The input element should have composing string"); + + // Composing nsITextInputProcessor instance shouldn't allow initialize it again. + try { + TIP1.beginInputTransaction(window, simpleCallback); + ok(false, + "TIP1.beginInputTransaction(window) should cause throwing an exception because it's composing with different purpose"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(window) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing for tests"); + } + try { + TIP1.beginInputTransactionForTests(otherWindow); + ok(false, + "TIP1.beginInputTransactionForTests(otherWindow) should cause throwing an exception because it's composing on different window"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow) should cause throwing an exception including NS_ERROR_ALREADY_INITIALIZED because it's composing on this window"); + } + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests(window) should succeed because TextEventDispatcher was initialized with same purpose"); + ok(TIP1.beginInputTransactionForTests(childWindow), + description + "TIP1.beginInputTransactionForTests(childWindow) should succeed because TextEventDispatcher was initialized with same purpose and is shared by window and childWindow"); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2.beginInputTransaction(window) should not succeed because there is composition synthesized by TIP1"); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests(window) should not succeed because there is composition synthesized by TIP1"); + ok(!TIP2.beginInputTransaction(childWindow, simpleCallback), + description + "TIP2.beginInputTransaction(childWindow) should not succeed because there is composition synthesized by TIP1"); + ok(!TIP2.beginInputTransactionForTests(childWindow), + description + "TIP2.beginInputTransactionForTests(childWindow) should not succeed because there is composition synthesized by TIP1"); + ok(TIP2.beginInputTransaction(otherWindow, simpleCallback), + description + "TIP2.beginInputTransaction(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window"); + ok(TIP2.beginInputTransactionForTests(otherWindow), + description + "TIP2.beginInputTransactionForTests(otherWindow) should succeed because there is composition synthesized by TIP1 but it's in other window"); + + // Let's confirm that the composing string is NOT committed by above tests. + TIP1.commitComposition(); + is(input.value, composingStr, + description + "TIP1.commitString() without specifying commit string should be committed with the last composing string"); + + ok(TIP1.beginInputTransaction(window, simpleCallback), + description + "TIP1.beginInputTransaction() should succeed because there is no composition #2"); + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition #2"); + ok(TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests() should succeed because the composition was already committed #2"); + + // Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during startComposition(). + var events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from compositionstart event handler during TIP1.startComposition();"); + }, false); + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.startComposition(); + is(events.length, 1, + description + "compositionstart event should be fired by TIP1.startComposition()"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during flushPendingComposition(). + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from compositionstart event handler during a call of TIP1.flushPendingComposition();"); + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from compositionupdate event handler during a call of TIP1.flushPendingComposition();"); + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from text event handler during a call of TIP1.flushPendingComposition();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.flushPendingComposition();"); + }, false); + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + is(events.length, 4, + description + "compositionstart, compositionupdate, text and input events should be fired by TIP1.flushPendingComposition()"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "input", + description + "events[3] should be input"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during commitComposition(). + events = []; + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from text event handler during a call of TIP1.commitComposition();"); + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from compositionend event handler during a call of TIP1.commitComposition();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.commitComposition();"); + }, false); + TIP1.commitComposition(); + is(events.length, 3, + description + "text, compositionend and input events should be fired by TIP1.commitComposition()"); + is(events[0].type, "text", + description + "events[0] should be text"); + is(events[1].type, "compositionend", + description + "events[1] should be compositionend"); + is(events[2].type, "input", + description + "events[2] should be input"); + + // Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during commitCompositionWith("bar"). + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from compositionstart event handler during TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction during compositionupdate event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction during text event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction during compositionend event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction during input event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.commitCompositionWith("bar"); + is(events.length, 5, + description + "compositionstart, compositionupdate, text, compositionend and input events should be fired by TIP1.commitCompositionWith(\"bar\")"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "compositionend", + description + "events[3] should be compositionend"); + is(events[4].type, "input", + description + "events[4] should be input"); + + // Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during cancelComposition(). + events = []; + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from compositionupdate event handler during a call of TIP1.cancelComposition();"); + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from text event handler during a call of TIP1.cancelComposition();"); + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from compositionend event handler during a call of TIP1.cancelComposition();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.cancelComposition();"); + }, false); + TIP1.cancelComposition(); + is(events.length, 4, + description + "compositionupdate, text, compositionend and input events should be fired by TIP1.cancelComposition()"); + is(events[0].type, "compositionupdate", + description + "events[0] should be compositionupdate"); + is(events[1].type, "text", + description + "events[1] should be text"); + is(events[2].type, "compositionend", + description + "events[2] should be compositionend"); + is(events[3].type, "input", + description + "events[3] should be input"); + + // Let's check if beginInputTransaction() fails to steal the rights of TextEventDispatcher during keydown() and keyup(). + events = []; + TIP1.beginInputTransaction(window, simpleCallback); + input.addEventListener("keydown", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from keydown event handler during a call of TIP1.keydown();"); + }, false); + input.addEventListener("keypress", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from keypress event handler during a call of TIP1.keydown();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from input event handler during a call of TIP1.keydown();"); + }, false); + input.addEventListener("keyup", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransaction(window, simpleCallback), + description + "TIP2 shouldn't be able to begin input transaction from keyup event handler during a call of TIP1.keyup();"); + }, false); + var keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + TIP1.keydown(keyA); + TIP1.keyup(keyA); + is(events.length, 4, + description + "keydown, keypress, input, keyup events should be fired by TIP1.keydown() and TIP1.keyup()"); + is(events[0].type, "keydown", + description + "events[0] should be keydown"); + is(events[1].type, "keypress", + description + "events[1] should be keypress"); + is(events[2].type, "input", + description + "events[2] should be input"); + is(events[3].type, "keyup", + description + "events[3] should be keyup"); + + // Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during startComposition(). + var events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from compositionstart event handler during TIP1.startComposition();"); + }, false); + TIP1.beginInputTransactionForTests(window); + TIP1.startComposition(); + is(events.length, 1, + description + "compositionstart event should be fired by TIP1.startComposition()"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during flushPendingComposition(). + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from compositionstart event handler during a call of TIP1.flushPendingComposition();"); + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from compositionupdate event handler during a call of TIP1.flushPendingComposition();"); + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from text event handler during a call of TIP1.flushPendingComposition();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.flushPendingComposition();"); + }, false); + TIP1.beginInputTransactionForTests(window); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + is(events.length, 4, + description + "compositionstart, compositionupdate, text and input events should be fired by TIP1.flushPendingComposition()"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "input", + description + "events[3] should be input"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during commitComposition(). + events = []; + TIP1.beginInputTransactionForTests(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from text event handler during a call of TIP1.commitComposition();"); + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from compositionend event handler during a call of TIP1.commitComposition();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.commitComposition();"); + }, false); + TIP1.commitComposition(); + is(events.length, 3, + description + "text, compositionend and input events should be fired by TIP1.commitComposition()"); + is(events[0].type, "text", + description + "events[0] should be text"); + is(events[1].type, "compositionend", + description + "events[1] should be compositionend"); + is(events[2].type, "input", + description + "events[2] should be input"); + + // Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during commitCompositionWith("bar"). + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from compositionstart event handler during TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests during compositionupdate event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests during text event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests during compositionend event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests during input event handler TIP1.commitCompositionWith(\"bar\");"); + }, false); + TIP1.beginInputTransactionForTests(window); + TIP1.commitCompositionWith("bar"); + is(events.length, 5, + description + "compositionstart, compositionupdate, text, compositionend and input events should be fired by TIP1.commitCompositionWith(\"bar\")"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "compositionend", + description + "events[3] should be compositionend"); + is(events[4].type, "input", + description + "events[4] should be input"); + + // Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during cancelComposition(). + events = []; + TIP1.beginInputTransactionForTests(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from compositionupdate event handler during a call of TIP1.cancelComposition();"); + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from text event handler during a call of TIP1.cancelComposition();"); + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from compositionend event handler during a call of TIP1.cancelComposition();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.cancelComposition();"); + }, false); + TIP1.cancelComposition(); + is(events.length, 4, + description + "compositionupdate, text, compositionend and input events should be fired by TIP1.cancelComposition()"); + is(events[0].type, "compositionupdate", + description + "events[0] should be compositionupdate"); + is(events[1].type, "text", + description + "events[1] should be text"); + is(events[2].type, "compositionend", + description + "events[2] should be compositionend"); + is(events[3].type, "input", + description + "events[3] should be input"); + + // Let's check if beginInputTransactionForTests() fails to steal the rights of TextEventDispatcher during keydown() and keyup(). + events = []; + TIP1.beginInputTransactionForTests(window); + input.addEventListener("keydown", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests for tests from keydown event handler during a call of TIP1.keydown();"); + }, false); + input.addEventListener("keypress", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from keypress event handler during a call of TIP1.keydown();"); + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from input event handler during a call of TIP1.keydown();"); + }, false); + input.addEventListener("keyup", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + ok(!TIP2.beginInputTransactionForTests(window), + description + "TIP2 shouldn't be able to begin input transaction for tests from keyup event handler during a call of TIP1.keyup();"); + }, false); + var keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + TIP1.keydown(keyA); + TIP1.keyup(keyA); + is(events.length, 4, + description + "keydown, keypress, input, keyup events should be fired by TIP1.keydown() and TIP1.keyup()"); + is(events[0].type, "keydown", + description + "events[0] should be keydown"); + is(events[1].type, "keypress", + description + "events[1] should be keypress"); + is(events[2].type, "input", + description + "events[2] should be input"); + is(events[3].type, "keyup", + description + "events[3] should be keyup"); + + // Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during startComposition(). + var events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during startComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during startComposition()"); + } + }, false); + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.startComposition(); + is(events.length, 1, + description + "compositionstart event should be fired by TIP1.startComposition()"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during flushPendingComposition(). + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + is(events.length, 4, + description + "compositionstart, compositionupdate, text and input events should be fired by TIP1.flushPendingComposition()"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "input", + description + "events[3] should be input"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during commitComposition(). + events = []; + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during commitComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()"); + } + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during commitComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during commitComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()"); + } + }, false); + TIP1.commitComposition(); + is(events.length, 3, + description + "text, compositionend and input events should be fired by TIP1.commitComposition()"); + is(events[0].type, "text", + description + "events[0] should be text"); + is(events[1].type, "compositionend", + description + "events[1] should be compositionend"); + is(events[2].type, "input", + description + "events[2] should be input"); + + // Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during commitCompositionWith("bar");. + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.commitCompositionWith("bar"); + is(events.length, 5, + description + "compositionstart, compositionupdate, text, compositionend and input events should be fired by TIP1.commitCompositionWith(\"bar\")"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "compositionend", + description + "events[3] should be compositionend"); + is(events[4].type, "input", + description + "events[4] should be input"); + + // Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during cancelComposition();. + events = []; + TIP1.beginInputTransaction(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + TIP1.cancelComposition(); + is(events.length, 4, + description + "compositionupdate, text, compositionend and input events should be fired by TIP1.cancelComposition()"); + is(events[0].type, "compositionupdate", + description + "events[0] should be compositionupdate"); + is(events[1].type, "text", + description + "events[1] should be text"); + is(events[2].type, "compositionend", + description + "events[2] should be compositionend"); + is(events[3].type, "input", + description + "events[3] should be input"); + + // Let's check if beginInputTransaction() with another window fails to begin new input transaction with different TextEventDispatcher during keydown() and keyup();. + events = []; + TIP1.beginInputTransaction(window, simpleCallback); + input.addEventListener("keydown", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keydown\" should throw an exception during keydown()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keydown\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()"); + } + }, false); + input.addEventListener("keypress", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keypress\" should throw an exception during keydown()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keypress\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should throw an exception during keydown()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()"); + } + }, false); + input.addEventListener("keyup", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransaction(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keyup\" should throw an exception during keyup()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransaction(otherWindow, simpleCallback) called from \"keyup\" should cause NS_ERROR_ALREADY_INITIALIZED during keyup()"); + } + }, false); + var keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + TIP1.keydown(keyA); + TIP1.keyup(keyA); + is(events.length, 4, + description + "keydown, keypress, input, keyup events should be fired by TIP1.keydown() and TIP1.keyup()"); + is(events[0].type, "keydown", + description + "events[0] should be keydown"); + is(events[1].type, "keypress", + description + "events[1] should be keypress"); + is(events[2].type, "input", + description + "events[2] should be input"); + is(events[3].type, "keyup", + description + "events[3] should be keyup"); + + // Let's check if beginInputTransactionForTests() with another window fails to begin new input transaction with different TextEventDispatcher during startComposition(). + var events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during startComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during startComposition()"); + } + }, false); + TIP1.beginInputTransactionForTests(window, simpleCallback); + TIP1.startComposition(); + is(events.length, 1, + description + "compositionstart event should be fired by TIP1.startComposition()"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransactionForTests() with another window fails to begin new input transaction with different TextEventDispatcher during flushPendingComposition(). + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should throw an exception during flushPendingComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during flushPendingComposition()"); + } + }, false); + TIP1.beginInputTransactionForTests(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + is(events.length, 4, + description + "compositionstart, compositionupdate, text and input events should be fired by TIP1.flushPendingComposition()"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "input", + description + "events[3] should be input"); + TIP1.cancelComposition(); + + // Let's check if beginInputTransactionForTests() with another window fails to begin new input transaction with different TextEventDispatcher during commitComposition(). + events = []; + TIP1.beginInputTransactionForTests(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should throw an exception during commitComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()"); + } + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during commitComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should throw an exception during commitComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during commitComposition()"); + } + }, false); + TIP1.commitComposition(); + is(events.length, 3, + description + "text, compositionend and input events should be fired by TIP1.commitComposition()"); + is(events[0].type, "text", + description + "events[0] should be text"); + is(events[1].type, "compositionend", + description + "events[1] should be compositionend"); + is(events[2].type, "input", + description + "events[2] should be input"); + + // Let's check if beginInputTransactionForTests() with another window fails to begin new input transaction with different TextEventDispatcher during commitCompositionWith("bar");. + events = []; + input.addEventListener("compositionstart", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionstart\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionstart\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should throw an exception during commitCompositionWith(\"bar\")"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during commitCompositionWith(\"bar\")"); + } + }, false); + TIP1.beginInputTransactionForTests(window, simpleCallback); + TIP1.commitCompositionWith("bar"); + is(events.length, 5, + description + "compositionstart, compositionupdate, text, compositionend and input events should be fired by TIP1.commitCompositionWith(\"bar\")"); + is(events[0].type, "compositionstart", + description + "events[0] should be compositionstart"); + is(events[1].type, "compositionupdate", + description + "events[1] should be compositionupdate"); + is(events[2].type, "text", + description + "events[2] should be text"); + is(events[3].type, "compositionend", + description + "events[3] should be compositionend"); + is(events[4].type, "input", + description + "events[4] should be input"); + + // Let's check if beginInputTransactionForTests() with another window fails to begin new input transaction with different TextEventDispatcher during cancelComposition();. + events = []; + TIP1.beginInputTransactionForTests(window, simpleCallback); + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition(); + input.addEventListener("compositionupdate", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionupdate\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionupdate\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + input.addEventListener("text", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"text\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + input.addEventListener("compositionend", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionend\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"compositionend\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should throw an exception during cancelComposition()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during cancelComposition()"); + } + }, false); + TIP1.cancelComposition(); + is(events.length, 4, + description + "compositionupdate, text, compositionend and input events should be fired by TIP1.cancelComposition()"); + is(events[0].type, "compositionupdate", + description + "events[0] should be compositionupdate"); + is(events[1].type, "text", + description + "events[1] should be text"); + is(events[2].type, "compositionend", + description + "events[2] should be compositionend"); + is(events[3].type, "input", + description + "events[3] should be input"); + + // Let's check if beginInputTransactionForTests() with another window fails to begin new input transaction with different TextEventDispatcher during keydown() and keyup();. + events = []; + TIP1.beginInputTransactionForTests(window, simpleCallback); + input.addEventListener("keydown", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"keydown\" should throw an exception during keydown()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"keydown\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()"); + } + }, false); + input.addEventListener("keypress", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"keypress\" should throw an exception during keydown()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"keypress\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()"); + } + }, false); + input.addEventListener("input", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should throw an exception during keydown()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"input\" should cause NS_ERROR_ALREADY_INITIALIZED during keydown()"); + } + }, false); + input.addEventListener("keyup", function (aEvent) { + events.push(aEvent); + input.removeEventListener(aEvent.type, arguments.callee, false); + try { + TIP1.beginInputTransactionForTests(otherWindow, simpleCallback); + ok(false, + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"keyup\" should throw an exception during keyup()"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ALREADY_INITIALIZED"), + description + "TIP1.beginInputTransactionForTests(otherWindow, simpleCallback) called from \"keyup\" should cause NS_ERROR_ALREADY_INITIALIZED during keyup()"); + } + }, false); + var keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + TIP1.keydown(keyA); + TIP1.keyup(keyA); + is(events.length, 4, + description + "keydown, keypress, input, keyup events should be fired by TIP1.keydown() and TIP1.keyup()"); + is(events[0].type, "keydown", + description + "events[0] should be keydown"); + is(events[1].type, "keypress", + description + "events[1] should be keypress"); + is(events[2].type, "input", + description + "events[2] should be input"); + is(events[3].type, "keyup", + description + "events[3] should be keyup"); + + // Let's check if startComposition() throws an exception after ownership is stolen. + input.value = ""; + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition"); + ok(TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests() should succeed because there is no composition"); + try { + TIP1.startComposition(); + ok(false, + description + "TIP1.startComposition() should cause throwing an exception because TIP2 took the ownership"); + TIP1.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_NOT_INITIALIZED"), + description + "TIP1.startComposition() should cause throwing an exception including NS_ERROR_NOT_INITIALIZED"); + } finally { + is(input.value, "", + description + "The input element should not have commit string"); + } + + // Let's check if flushPendingComposition() throws an exception after ownership is stolen. + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition"); + ok(TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests() should succeed because there is no composition"); + input.value = ""; + try { + TIP1.setPendingCompositionString(composingStr); + TIP1.appendClauseToPendingComposition(composingStr.length, TIP1.ATTR_RAW_CLAUSE); + TIP1.flushPendingComposition() + ok(false, + description + "TIP1.flushPendingComposition() should cause throwing an exception because TIP2 took the ownership"); + TIP1.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_NOT_INITIALIZED"), + description + "TIP1.flushPendingComposition() should cause throwing an exception including NS_ERROR_NOT_INITIALIZED"); + } finally { + is(input.value, "", + description + "The input element should not have commit string"); + } + + // Let's check if commitCompositionWith("bar") throws an exception after ownership is stolen. + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition"); + ok(TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests() should succeed because there is no composition"); + input.value = ""; + try { + TIP1.commitCompositionWith("bar"); + ok(false, + description + "TIP1.commitCompositionWith(\"bar\") should cause throwing an exception because TIP2 took the ownership"); + } catch (e) { + ok(e.message.includes("NS_ERROR_NOT_INITIALIZED"), + description + "TIP1.commitCompositionWith(\"bar\") should cause throwing an exception including NS_ERROR_NOT_INITIALIZED"); + } finally { + is(input.value, "", + description + "The input element should not have commit string"); + } + + // Let's check if keydown() throws an exception after ownership is stolen. + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition"); + ok(TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests() should succeed because there is no composition"); + input.value = ""; + try { + var keyF = new KeyboardEvent("", { key: "f", code: "KeyF", keyCode: KeyboardEvent.DOM_VK_F }); + TIP1.keydown(keyF); + ok(false, + description + "TIP1.keydown(keyF) should cause throwing an exception because TIP2 took the ownership"); + } catch (e) { + ok(e.message.includes("NS_ERROR_NOT_INITIALIZED"), + description + "TIP1.keydown(keyF) should cause throwing an exception including NS_ERROR_NOT_INITIALIZED"); + } finally { + is(input.value, "", + description + "The input element should not be modified"); + } + + // Let's check if keyup() throws an exception after ownership is stolen. + ok(TIP1.beginInputTransactionForTests(window), + description + "TIP1.beginInputTransactionForTests() should succeed because there is no composition"); + ok(TIP2.beginInputTransactionForTests(window), + description + "TIP2.beginInputTransactionForTests() should succeed because there is no composition"); + input.value = ""; + try { + var keyF = new KeyboardEvent("", { key: "f", code: "KeyF", keyCode: KeyboardEvent.DOM_VK_F }); + TIP1.keyup(keyF); + ok(false, + description + "TIP1.keyup(keyF) should cause throwing an exception because TIP2 took the ownership"); + } catch (e) { + ok(e.message.includes("NS_ERROR_NOT_INITIALIZED"), + description + "TIP1.keyup(keyF) should cause throwing an exception including NS_ERROR_NOT_INITIALIZED"); + } finally { + is(input.value, "", + description + "The input element should not be modified"); + } + + // aCallback of nsITextInputProcessor.beginInputTransaction() must not be omitted. + try { + TIP1.beginInputTransaction(window); + ok(false, + description + "TIP1.beginInputTransaction(window) should be failed since aCallback is omitted"); + } catch (e) { + ok(e.message.includes("Not enough arguments"), + description + "TIP1.beginInputTransaction(window) should cause throwing an exception including \"Not enough arguments\" since aCallback is omitted"); + } + + // aCallback of nsITextInputProcessor.beginInputTransaction() must not be undefined. + try { + TIP1.beginInputTransaction(window, undefined); + ok(false, + description + "TIP1.beginInputTransaction(window, undefined) should be failed since aCallback is undefined"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "TIP1.beginInputTransaction(window, undefined) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE since aCallback is undefined"); + } + + // aCallback of nsITextInputProcessor.beginInputTransaction() must not be null. + try { + TIP1.beginInputTransaction(window, null); + ok(false, + description + "TIP1.beginInputTransaction(window, null) should be failed since aCallback is null"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "TIP1.beginInputTransaction(window, null) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE since aCallback is null"); + } +} + +function runReleaseTests() +{ + var description = "runReleaseTests(): "; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed"); + + input.value = ""; + input.focus(); + + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + is(input.value, "foo", + description + "the input should have composition string"); + + // Release the TIP + TIP = null; + // Needs to run GC forcibly for testing this. + SpecialPowers.gc(); + + is(input.value, "", + description + "the input should be empty because the composition should be canceled"); + + TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed #2"); +} + +function runCompositionTests() +{ + var description = "runCompositionTests(): "; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed"); + + var events; + + function reset() + { + events = []; + } + + function handler(aEvent) + { + events.push({ "type": aEvent.type, "data": aEvent.data }); + } + + window.addEventListener("compositionstart", handler, false); + window.addEventListener("compositionupdate", handler, false); + window.addEventListener("compositionend", handler, false); + + input.value = ""; + input.focus(); + + // nsITextInputProcessor.startComposition() + reset(); + TIP.startComposition(); + is(events.length, 1, + description + "startComposition() should cause only compositionstart"); + is(events[0].type, "compositionstart", + description + "startComposition() should cause only compositionstart"); + is(input.value, "", + description + "startComposition() shouldn't modify the focused editor"); + + // Setting composition string "foo" as a raw clause + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + + reset(); + TIP.flushPendingComposition(); + is(events.length, 1, + description + "flushPendingComposition() after startComposition() should cause compositionupdate"); + is(events[0].type, "compositionupdate", + description + "flushPendingComposition() after startComposition() should cause compositionupdate"); + is(events[0].data, "foo", + description + "compositionupdate caused by flushPendingComposition() should have new composition string in its data"); + is(input.value, "foo", + description + "modifying composition string should cause modifying the focused editor"); + + // Changing the raw clause to a selected clause + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_SELECTED_CLAUSE); + + reset(); + TIP.flushPendingComposition(); + is(events.length, 0, + description + "flushPendingComposition() changing only clause information shouldn't cause compositionupdate"); + is(input.value, "foo", + description + "modifying composition clause shouldn't cause modifying the focused editor"); + + // Separating the selected clause to two clauses + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(2, TIP.ATTR_SELECTED_CLAUSE); + TIP.appendClauseToPendingComposition(1, TIP.ATTR_CONVERTED_CLAUSE); + TIP.setCaretInPendingComposition(2); + + reset(); + TIP.flushPendingComposition(); + is(events.length, 0, + description + "flushPendingComposition() separating a clause information shouldn't cause compositionupdate"); + is(input.value, "foo", + description + "separating composition clause shouldn't cause modifying the focused editor"); + + // Modifying the composition string + TIP.setPendingCompositionString("FOo"); + TIP.appendClauseToPendingComposition(2, TIP.ATTR_SELECTED_CLAUSE); + TIP.appendClauseToPendingComposition(1, TIP.ATTR_CONVERTED_CLAUSE); + TIP.setCaretInPendingComposition(2); + + reset(); + TIP.flushPendingComposition(); + is(events.length, 1, + description + "flushPendingComposition() causing modifying composition string should cause compositionupdate"); + is(events[0].type, "compositionupdate", + description + "flushPendingComposition() causing modifying composition string should cause compositionupdate"); + is(events[0].data, "FOo", + description + "compositionupdate caused by flushPendingComposition() should have new composition string in its data"); + is(input.value, "FOo", + description + "modifying composition clause shouldn't cause modifying the focused editor"); + + // Committing the composition string + reset(); + TIP.commitComposition(); + is(events.length, 1, + description + "commitComposition() should cause compositionend but shoudn't cause compositionupdate"); + is(events[0].type, "compositionend", + description + "commitComposition() should cause compositionend"); + is(events[0].data, "FOo", + description + "compositionend caused by commitComposition() should have the committed string in its data"); + is(input.value, "FOo", + description + "commitComposition() shouldn't cause modifying the focused editor"); + + // Starting new composition without a call of startComposition() + TIP.setPendingCompositionString("bar"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + + reset(); + TIP.flushPendingComposition(); + is(events.length, 2, + description + "flushPendingComposition() without a call of startComposition() should cause both compositionstart and compositionupdate"); + is(events[0].type, "compositionstart", + description + "flushPendingComposition() without a call of startComposition() should cause compositionstart"); + is(events[1].type, "compositionupdate", + description + "flushPendingComposition() without a call of startComposition() should cause compositionupdate after compositionstart"); + is(events[1].data, "bar", + description + "compositionupdate caused by flushPendingComposition() without a call of startComposition() should have the composition string in its data"); + is(input.value, "FOobar", + description + "new composition string should cause appending composition string to the focused editor"); + + // Canceling the composition + reset(); + TIP.cancelComposition(); + is(events.length, 2, + description + "cancelComposition() should cause both compositionupdate and compositionend"); + is(events[0].type, "compositionupdate", + description + "cancelComposition() should cause compositionupdate"); + is(events[0].data, "", + description + "compositionupdate caused by cancelComposition() should have empty string in its data"); + is(events[1].type, "compositionend", + description + "cancelComposition() should cause compositionend after compositionupdate"); + is(events[1].data, "", + description + "compositionend caused by cancelComposition() should have empty string in its data"); + is(input.value, "FOo", + description + "canceled composition string should be removed from the focused editor"); + + // Starting composition explicitly and canceling it + reset(); + TIP.startComposition(); + TIP.cancelComposition(); + is(events.length, 2, + description + "canceling composition immediately after startComposition() should cause compositionstart and compositionend"); + is(events[0].type, "compositionstart", + description + "canceling composition immediately after startComposition() should cause compositionstart first"); + is(events[1].type, "compositionend", + description + "canceling composition immediately after startComposition() should cause compositionend after compositionstart"); + is(events[1].data, "", + description + "compositionend caused by canceling composition should have empty string in its data"); + is(input.value, "FOo", + description + "canceling composition shouldn't modify the focused editor"); + + // Create composition for next test. + TIP.setPendingCompositionString("bar"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + is(input.value, "FOobar", + description + "The focused editor should have new composition string \"bar\""); + + // Allow to set empty composition string + reset(); + TIP.flushPendingComposition(); + is(events.length, 1, + description + "making composition string empty should cause only compositionupdate"); + is(events[0].type, "compositionupdate", + description + "making composition string empty should cause compositionupdate"); + is(events[0].data, "", + description + "compositionupdate caused by making composition string empty should have empty string in its data"); + + // Allow to insert new composition string without compositionend/compositionstart + TIP.setPendingCompositionString("buzz"); + TIP.appendClauseToPendingComposition(4, TIP.ATTR_RAW_CLAUSE); + + reset(); + TIP.flushPendingComposition(); + is(events.length, 1, + description + "modifying composition string from empty string should cause only compositionupdate"); + is(events[0].type, "compositionupdate", + description + "modifying composition string from empty string should cause compositionupdate"); + is(events[0].data, "buzz", + description + "compositionupdate caused by modifying composition string from empty string should have new composition string in its data"); + is(input.value, "FOobuzz", + description + "new composition string should be appended to the focused editor"); + + // Committing with different string + reset(); + TIP.commitCompositionWith("bar"); + is(events.length, 2, + description + "committing with different string should cause compositionupdate and compositionend"); + is(events[0].type, "compositionupdate", + description + "committing with different string should cause compositionupdate first"); + is(events[0].data, "bar", + description + "compositionupdate caused by committing with different string should have the committing string in its data"); + is(events[1].type, "compositionend", + description + "committing with different string should cause compositionend after compositionupdate"); + is(events[1].data, "bar", + description + "compositionend caused by committing with different string should have the committing string in its data"); + is(input.value, "FOobar", + description + "new committed string should be appended to the focused editor"); + + // Appending new composition string + TIP.setPendingCompositionString("buzz"); + TIP.appendClauseToPendingComposition(4, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + is(input.value, "FOobarbuzz", + description + "new composition string should be appended to the focused editor"); + + // Committing with same string + reset(); + TIP.commitCompositionWith("buzz"); + is(events.length, 1, + description + "committing with same string should cause only compositionend"); + is(events[0].type, "compositionend", + description + "committing with same string should cause compositionend"); + is(events[0].data, "buzz", + description + "compositionend caused by committing with same string should have the committing string in its data"); + is(input.value, "FOobarbuzz", + description + "new committed string should be appended to the focused editor"); + + // Inserting commit string directly + reset(); + TIP.commitCompositionWith("boo!"); + is(events.length, 3, + description + "committing text directly should cause compositionstart, compositionupdate and compositionend"); + is(events[0].type, "compositionstart", + description + "committing text directly should cause compositionstart first"); + is(events[1].type, "compositionupdate", + description + "committing text directly should cause compositionupdate after compositionstart"); + is(events[1].data, "boo!", + description + "compositionupdate caused by committing text directly should have the committing text in its data"); + is(events[2].type, "compositionend", + description + "committing text directly should cause compositionend after compositionupdate"); + is(events[2].data, "boo!", + description + "compositionend caused by committing text directly should have the committing text in its data"); + is(input.value, "FOobarbuzzboo!", + description + "committing text directly should append the committing text to the focused editor"); + + window.removeEventListener("compositionstart", handler, false); + window.removeEventListener("compositionupdate", handler, false); + window.removeEventListener("compositionend", handler, false); +} + +function runCompositionWithKeyEventTests() +{ + var description = "runCompositionWithKeyEventTests(): "; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed"); + + var events; + + function reset() + { + events = []; + } + + function handler(aEvent) + { + events.push(aEvent); + } + + window.addEventListener("compositionstart", handler, false); + window.addEventListener("compositionupdate", handler, false); + window.addEventListener("compositionend", handler, false); + window.addEventListener("keydown", handler, false); + window.addEventListener("keypress", handler, false); + window.addEventListener("keyup", handler, false); + + input.value = ""; + input.focus(); + + var printableKeyEvent = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + var enterKeyEvent = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + var escKeyEvent = new KeyboardEvent("", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }); + var convertKeyEvent = new KeyboardEvent("", { key: "Convert", code: "Convert", keyCode: KeyboardEvent.DOM_VK_CONVERT }); + var backspaceKeyEvent = new KeyboardEvent("", { key: "Backspace", code: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE }); + + SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false); + + // nsITextInputProcessor.startComposition() + reset(); + TIP.startComposition(printableKeyEvent); + is(events.length, 2, + description + "startComposition(printableKeyEvent) should cause keydown and compositionstart"); + is(events[0].type, "keydown", + description + "startComposition(printableKeyEvent) should cause keydown"); + is(events[1].type, "compositionstart", + description + "startComposition(printableKeyEvent) should cause compositionstart"); + is(input.value, "", + description + "startComposition(printableKeyEvent) shouldn't modify the focused editor"); + + // Setting composition string "foo" as a raw clause + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + + reset(); + TIP.flushPendingComposition(printableKeyEvent); + is(events.length, 1, + description + "flushPendingComposition(KeyupInternal) after startComposition() should cause compositionupdate"); + is(events[0].type, "compositionupdate", + description + "flushPendingComposition(KeyupInternal) after startComposition() should cause compositionupdate"); + is(events[0].data, "foo", + description + "compositionupdate caused by flushPendingComposition(KeyupInternal) should have new composition string in its data"); + is(input.value, "foo", + description + "modifying composition string should cause modifying the focused editor"); + + // Changing the raw clause to a selected clause + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_SELECTED_CLAUSE); + + reset(); + TIP.flushPendingComposition(convertKeyEvent); + is(events.length, 0, + description + "flushPendingComposition(convertKeyEvent) changing only clause information shouldn't cause compositionupdate"); + is(input.value, "foo", + description + "modifying composition clause shouldn't cause modifying the focused editor"); + + // Separating the selected clause to two clauses + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(2, TIP.ATTR_SELECTED_CLAUSE); + TIP.appendClauseToPendingComposition(1, TIP.ATTR_CONVERTED_CLAUSE); + TIP.setCaretInPendingComposition(2); + + reset(); + TIP.flushPendingComposition(convertKeyEvent); + is(events.length, 0, + description + "flushPendingComposition(convertKeyEvent) separating a clause information shouldn't cause compositionupdate"); + is(input.value, "foo", + description + "separating composition clause shouldn't cause modifying the focused editor"); + + // Modifying the composition string + TIP.setPendingCompositionString("FOo"); + TIP.appendClauseToPendingComposition(2, TIP.ATTR_SELECTED_CLAUSE); + TIP.appendClauseToPendingComposition(1, TIP.ATTR_CONVERTED_CLAUSE); + TIP.setCaretInPendingComposition(2); + + reset(); + TIP.flushPendingComposition(convertKeyEvent); + is(events.length, 1, + description + "flushPendingComposition(convertKeyEvent) causing modifying composition string should cause compositionupdate"); + is(events[0].type, "compositionupdate", + description + "flushPendingComposition(convertKeyEvent) causing modifying composition string should cause compositionupdate"); + is(events[0].data, "FOo", + description + "compositionupdate caused by flushPendingComposition(convertKeyEvent) should have new composition string in its data"); + is(input.value, "FOo", + description + "modifying composition clause shouldn't cause modifying the focused editor"); + + // Committing the composition string + reset(); + TIP.commitComposition(enterKeyEvent); + is(events.length, 2, + description + "commitComposition(enterKeyEvent) should cause compositionend and keyup but shoudn't cause compositionupdate"); + is(events[0].type, "compositionend", + description + "commitComposition(enterKeyEvent) should cause compositionend"); + is(events[0].data, "FOo", + description + "compositionend caused by commitComposition(enterKeyEvent) should have the committed string in its data"); + is(events[1].type, "keyup", + description + "commitComposition(enterKeyEvent) should cause keyup"); + is(input.value, "FOo", + description + "commitComposition(enterKeyEvent) shouldn't cause modifying the focused editor"); + + // Starting new composition without a call of startComposition() + TIP.setPendingCompositionString("bar"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + + reset(); + TIP.flushPendingComposition(printableKeyEvent); + is(events.length, 3, + description + "flushPendingComposition(printableKeyEvent) without a call of startComposition() should cause both compositionstart and compositionupdate"); + is(events[0].type, "keydown", + description + "flushPendingComposition(printableKeyEvent) without a call of startComposition() should cause keydown"); + is(events[1].type, "compositionstart", + description + "flushPendingComposition(printableKeyEvent) without a call of startComposition() should cause compositionstart"); + is(events[2].type, "compositionupdate", + description + "flushPendingComposition(printableKeyEvent) without a call of startComposition() should cause compositionupdate after compositionstart"); + is(events[2].data, "bar", + description + "compositionupdate caused by flushPendingComposition(printableKeyEvent) without a call of startComposition() should have the composition string in its data"); + is(input.value, "FOobar", + description + "new composition string should cause appending composition string to the focused editor"); + + // Canceling the composition + reset(); + TIP.cancelComposition(escKeyEvent); + is(events.length, 3, + description + "cancelComposition(escKeyEvent) should cause both compositionupdate and compositionend"); + is(events[0].type, "compositionupdate", + description + "cancelComposition(escKeyEvent) should cause compositionupdate"); + is(events[0].data, "", + description + "compositionupdate caused by cancelComposition(escKeyEvent) should have empty string in its data"); + is(events[1].type, "compositionend", + description + "cancelComposition(escKeyEvent) should cause compositionend after compositionupdate"); + is(events[1].data, "", + description + "compositionend caused by cancelComposition(escKeyEvent) should have empty string in its data"); + is(events[2].type, "keyup", + description + "cancelComposition(escKeyEvent) should cause keyup after compositionend"); + is(input.value, "FOo", + description + "canceled composition string should be removed from the focused editor"); + + // Starting composition explicitly and canceling it + reset(); + TIP.startComposition(printableKeyEvent); + TIP.cancelComposition(escKeyEvent); + is(events.length, 4, + description + "canceling composition immediately after startComposition() should cause keydown, compositionstart, compositionend and keyup"); + is(events[0].type, "keydown", + description + "canceling composition immediately after startComposition() should cause keydown first"); + is(events[1].type, "compositionstart", + description + "canceling composition immediately after startComposition() should cause compositionstart after keydown"); + is(events[2].type, "compositionend", + description + "canceling composition immediately after startComposition() should cause compositionend after compositionstart"); + is(events[2].data, "", + description + "compositionend caused by canceling composition should have empty string in its data"); + is(events[3].type, "keyup", + description + "canceling composition immediately after startComposition() should cause keyup after compositionend"); + is(input.value, "FOo", + description + "canceling composition shouldn't modify the focused editor"); + + // Create composition for next test. + TIP.setPendingCompositionString("bar"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + is(input.value, "FOobar", + description + "The focused editor should have new composition string \"bar\""); + + // Allow to set empty composition string + reset(); + TIP.flushPendingComposition(backspaceKeyEvent); + is(events.length, 1, + description + "making composition string empty should cause only compositionupdate"); + is(events[0].type, "compositionupdate", + description + "making composition string empty should cause compositionupdate"); + is(events[0].data, "", + description + "compositionupdate caused by making composition string empty should have empty string in its data"); + + // Allow to insert new composition string without compositionend/compositionstart + TIP.setPendingCompositionString("buzz"); + TIP.appendClauseToPendingComposition(4, TIP.ATTR_RAW_CLAUSE); + + reset(); + TIP.flushPendingComposition(printableKeyEvent); + is(events.length, 1, + description + "modifying composition string from empty string should cause only compositionupdate"); + is(events[0].type, "compositionupdate", + description + "modifying composition string from empty string should cause compositionupdate"); + is(events[0].data, "buzz", + description + "compositionupdate caused by modifying composition string from empty string should have new composition string in its data"); + is(input.value, "FOobuzz", + description + "new composition string should be appended to the focused editor"); + + // Committing with different string + reset(); + TIP.commitCompositionWith("bar", printableKeyEvent); + is(events.length, 3, + description + "committing with different string should cause compositionupdate and compositionend"); + is(events[0].type, "compositionupdate", + description + "committing with different string should cause compositionupdate first"); + is(events[0].data, "bar", + description + "compositionupdate caused by committing with different string should have the committing string in its data"); + is(events[1].type, "compositionend", + description + "committing with different string should cause compositionend after compositionupdate"); + is(events[1].data, "bar", + description + "compositionend caused by committing with different string should have the committing string in its data"); + is(events[2].type, "keyup", + description + "committing with different string should cause keyup after compositionend"); + is(input.value, "FOobar", + description + "new committed string should be appended to the focused editor"); + + // Appending new composition string + TIP.setPendingCompositionString("buzz"); + TIP.appendClauseToPendingComposition(4, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + is(input.value, "FOobarbuzz", + description + "new composition string should be appended to the focused editor"); + + // Committing with same string + reset(); + TIP.commitCompositionWith("buzz", enterKeyEvent); + is(events.length, 2, + description + "committing with same string should cause only compositionend"); + is(events[0].type, "compositionend", + description + "committing with same string should cause compositionend"); + is(events[0].data, "buzz", + description + "compositionend caused by committing with same string should have the committing string in its data"); + is(events[1].type, "keyup", + description + "committing with same string should cause keyup after compositionend"); + is(input.value, "FOobarbuzz", + description + "new committed string should be appended to the focused editor"); + + // Inserting commit string directly + reset(); + TIP.commitCompositionWith("boo!", printableKeyEvent); + is(events.length, 5, + description + "committing text directly should cause compositionstart, compositionupdate and compositionend"); + is(events[0].type, "keydown", + description + "committing text directly should cause keydown first"); + is(events[1].type, "compositionstart", + description + "committing text directly should cause compositionstart after keydown"); + is(events[2].type, "compositionupdate", + description + "committing text directly should cause compositionupdate after compositionstart"); + is(events[2].data, "boo!", + description + "compositionupdate caused by committing text directly should have the committing text in its data"); + is(events[3].type, "compositionend", + description + "committing text directly should cause compositionend after compositionupdate"); + is(events[3].data, "boo!", + description + "compositionend caused by committing text directly should have the committing text in its data"); + is(events[4].type, "keyup", + description + "committing text directly should cause keyup after compositionend"); + is(input.value, "FOobarbuzzboo!", + description + "committing text directly should append the committing text to the focused editor"); + + SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true); + + // Even if "dom.keyboardevent.dispatch_during_composition" is true, keypress event shouldn't be fired during composition + reset(); + TIP.startComposition(printableKeyEvent); + is(events.length, 3, + description + "TIP.startComposition(printableKeyEvent) should cause keydown, compositionstart and keyup (keypress event shouldn't be fired during composition)"); + is(events[0].type, "keydown", + description + "TIP.startComposition(printableKeyEvent) should cause keydown (keypress event shouldn't be fired during composition)"); + is(events[1].type, "compositionstart", + description + "TIP.startComposition(printableKeyEvent) should cause compositionstart (keypress event shouldn't be fired during composition)"); + is(events[2].type, "keyup", + description + "TIP.startComposition(printableKeyEvent) should cause keyup (keypress event shouldn't be fired during composition)"); + + // TIP.flushPendingComposition(printableKeyEvent) should cause keydown and keyup events if "dom.keyboardevent.dispatch_during_composition" is true + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + + reset(); + TIP.flushPendingComposition(printableKeyEvent); + is(events.length, 3, + description + "TIP.flushPendingComposition(printableKeyEvent) should cause keydown, compositionupdate and keyup (keypress event shouldn't be fired during composition)"); + is(events[0].type, "keydown", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause keydown (keypress event shouldn't be fired during composition)"); + is(events[1].type, "compositionupdate", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause compositionupdate (keypress event shouldn't be fired during composition)"); + is(events[2].type, "keyup", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause keyup (keypress event shouldn't be fired during composition)"); + + // TIP.commitComposition(enterKeyEvent) should cause keydown and keyup events if "dom.keyboardevent.dispatch_during_composition" is true + reset(); + TIP.commitComposition(enterKeyEvent); + is(events.length, 3, + description + "TIP.commitComposition(enterKeyEvent) should cause keydown, compositionend and keyup (keypress event shouldn't be fired during composition)"); + is(events[0].type, "keydown", + description + "TIP.commitComposition(enterKeyEvent) should cause keydown (keypress event shouldn't be fired during composition)"); + is(events[1].type, "compositionend", + description + "TIP.commitComposition(enterKeyEvent) should cause compositionend (keypress event shouldn't be fired during composition)"); + is(events[2].type, "keyup", + description + "TIP.commitComposition(enterKeyEvent) should cause keyup (keypress event shouldn't be fired during composition)"); + + // TIP.cancelComposition(escKeyEvent) should cause keydown and keyup events if "dom.keyboardevent.dispatch_during_composition" is true + TIP.startComposition(); + reset(); + TIP.cancelComposition(escKeyEvent); + is(events.length, 3, + description + "TIP.cancelComposition(escKeyEvent) should cause keydown, compositionend and keyup (keypress event shouldn't be fired during composition)"); + is(events[0].type, "keydown", + description + "TIP.cancelComposition(escKeyEvent) should cause keydown (keypress event shouldn't be fired during composition)"); + is(events[1].type, "compositionend", + description + "TIP.cancelComposition(escKeyEvent) should cause compositionend (keypress event shouldn't be fired during composition)"); + is(events[2].type, "keyup", + description + "TIP.cancelComposition(escKeyEvent) should cause keyup (keypress event shouldn't be fired during composition)"); + + var printableKeydownEvent = new KeyboardEvent("keydown", { key: "b", code: "KeyB", keyCode: KeyboardEvent.DOM_VK_B }); + var enterKeydownEvent = new KeyboardEvent("keydown", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + var escKeydownEvent = new KeyboardEvent("keydown", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }); + + // TIP.startComposition(printableKeydownEvent) shouldn't cause keyup event even if "dom.keyboardevent.dispatch_during_composition" is true + reset(); + TIP.startComposition(printableKeydownEvent); + is(events.length, 2, + description + "TIP.startComposition(printableKeydownEvent) should cause keydown and compositionstart (keyup event shouldn't be fired)"); + is(events[0].type, "keydown", + description + "TIP.startComposition(printableKeydownEvent) should cause keydown (keyup event shouldn't be fired)"); + is(events[1].type, "compositionstart", + description + "TIP.startComposition(printableKeydownEvent) should cause compositionstart (keyup event shouldn't be fired)"); + + // TIP.flushPendingComposition(printableKeydownEvent) shouldn't cause keyup event even if "dom.keyboardevent.dispatch_during_composition" is true + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + + reset(); + TIP.flushPendingComposition(printableKeydownEvent); + is(events.length, 2, + description + "TIP.flushPendingComposition(printableKeydownEvent) should cause keydown and compositionupdate (keyup event shouldn't be fired)"); + is(events[0].type, "keydown", + description + "TIP.flushPendingComposition(printableKeydownEvent) should cause keydown (keyup event shouldn't be fired)"); + is(events[1].type, "compositionupdate", + description + "TIP.flushPendingComposition(printableKeydownEvent) should cause compositionupdate (keyup event shouldn't be fired)"); + + // TIP.commitComposition(enterKeydownEvent) shouldn't cause keyup event even if "dom.keyboardevent.dispatch_during_composition" is true + reset(); + TIP.commitComposition(enterKeydownEvent); + is(events.length, 2, + description + "TIP.commitComposition(enterKeydownEvent) should cause keydown and compositionend (keyup event shouldn't be fired)"); + is(events[0].type, "keydown", + description + "TIP.commitComposition(enterKeydownEvent) should cause keydown (keyup event shouldn't be fired)"); + is(events[1].type, "compositionend", + description + "TIP.commitComposition(enterKeydownEvent) should cause compositionend (keyup event shouldn't be fired)"); + + // TIP.cancelComposition(escKeydownEvent) shouldn't cause keyup event even if "dom.keyboardevent.dispatch_during_composition" is true + TIP.startComposition(); + reset(); + TIP.cancelComposition(escKeydownEvent); + is(events.length, 2, + description + "TIP.cancelComposition(escKeydownEvent) should cause keydown and compositionend (keyup event shouldn't be fired)"); + is(events[0].type, "keydown", + description + "TIP.cancelComposition(escKeydownEvent) should cause keydown (keyup event shouldn't be fired)"); + is(events[1].type, "compositionend", + description + "TIP.cancelComposition(escKeydownEvent) should cause compositionend (keyup event shouldn't be fired)"); + + SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition"); + + window.removeEventListener("compositionstart", handler, false); + window.removeEventListener("compositionupdate", handler, false); + window.removeEventListener("compositionend", handler, false); + window.removeEventListener("keydown", handler, false); + window.removeEventListener("keypress", handler, false); + window.removeEventListener("keyup", handler, false); +} + +function runConsumingKeydownBeforeCompositionTests() +{ + var description = "runConsumingKeydownBeforeCompositionTests(): "; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed"); + + var events; + + function reset() + { + events = []; + } + + function handler(aEvent) + { + events.push(aEvent); + if (aEvent.type == "keydown") { + aEvent.preventDefault(); + } + } + + window.addEventListener("compositionstart", handler, false); + window.addEventListener("compositionupdate", handler, false); + window.addEventListener("compositionend", handler, false); + window.addEventListener("keydown", handler, false); + window.addEventListener("keypress", handler, false); + window.addEventListener("keyup", handler, false); + + input.value = ""; + input.focus(); + + var printableKeyEvent = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + var enterKeyEvent = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + var escKeyEvent = new KeyboardEvent("", { key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }); + + SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false); + + // If keydown before compositionstart is consumed, composition shouldn't be started. + reset(); + ok(!TIP.startComposition(printableKeyEvent), + description + "TIP.startComposition(printableKeyEvent) should return false because it's keydown is consumed"); + is(events.length, 2, + description + "TIP.startComposition(printableKeyEvent) should cause only keydown and keyup events"); + is(events[0].type, "keydown", + description + "TIP.startComposition(printableKeyEvent) should cause keydown event first"); + is(events[1].type, "keyup", + description + "TIP.startComposition(printableKeyEvent) should cause keyup event after keydown"); + ok(!TIP.hasComposition, + description + "TIP.startComposition(printableKeyEvent) shouldn't cause composition"); + is(input.value, "", + description + "TIP.startComposition(printableKeyEvent) shouldn't cause inserting text"); + + // If keydown before compositionstart caused by flushPendingComposition(printableKeyEvent) is consumed, composition shouldn't be started. + reset(); + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + ok(!TIP.flushPendingComposition(printableKeyEvent), + description + "TIP.flushPendingComposition(printableKeyEvent) should return false because it's keydown is consumed"); + is(events.length, 2, + description + "TIP.flushPendingComposition(printableKeyEvent) should cause only keydown and keyup events"); + is(events[0].type, "keydown", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause keydown event first"); + is(events[1].type, "keyup", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause keyup event after keydown"); + ok(!TIP.hasComposition, + description + "TIP.flushPendingComposition(printableKeyEvent) shouldn't cause composition"); + is(input.value, "", + description + "TIP.flushPendingComposition(printableKeyEvent) shouldn't cause inserting text"); + + // If keydown before compositionstart is consumed, composition shouldn't be started. + reset(); + ok(!TIP.commitCompositionWith("foo", printableKeyEvent), + description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) should return false because it's keydown is consumed"); + is(events.length, 2, + description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) should cause only keydown and keyup events"); + is(events[0].type, "keydown", + description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) should cause keydown event first"); + is(events[1].type, "keyup", + description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) should cause keyup event after keydown"); + ok(!TIP.hasComposition, + description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) shouldn't cause composition"); + is(input.value, "", + description + "TIP.commitCompositionWith(\"foo\", printableKeyEvent) shouldn't cause inserting text"); + + SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true); + + // If composition is already started, TIP.flushPendingComposition(printableKeyEvent) shouldn't be canceled. + TIP.startComposition(); + ok(TIP.hasComposition, + description + "Before TIP.flushPendingComposition(printableKeyEvent), composition should've been created"); + reset(); + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + ok(TIP.flushPendingComposition(printableKeyEvent), + description + "TIP.flushPendingComposition(printableKeyEvent) should return true even if preceding keydown is consumed because there was a composition already"); + is(events.length, 3, + description + "TIP.flushPendingComposition(printableKeyEvent) should cause only keydown and keyup events"); + is(events[0].type, "keydown", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause keydown event first"); + is(events[1].type, "compositionupdate", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause compositionupdate event after keydown"); + is(events[2].type, "keyup", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause keyup event after compositionupdate"); + ok(TIP.hasComposition, + description + "TIP.flushPendingComposition(printableKeyEvent) shouldn't cause canceling composition"); + is(input.value, "foo", + description + "TIP.flushPendingComposition(printableKeyEvent) should cause inserting text even if preceding keydown is consumed because there was a composition already"); + + // If composition is already started, TIP.commitComposition(enterKeyEvent) shouldn't be canceled. + reset(); + TIP.commitComposition(enterKeyEvent); + is(events.length, 3, + description + "TIP.commitComposition(enterKeyEvent) should cause keydown, compositionend and keyup events"); + is(events[0].type, "keydown", + description + "TIP.commitComposition(enterKeyEvent) should cause keydown event first"); + is(events[1].type, "compositionend", + description + "TIP.commitComposition(enterKeyEvent) should cause compositionend event after keydown"); + is(events[2].type, "keyup", + description + "TIP.commitComposition(enterKeyEvent) should cause keyup event after compositionend"); + ok(!TIP.hasComposition, + description + "TIP.commitComposition(enterKeyEvent) should cause committing composition even if preceding keydown is consumed because there was a composition already"); + is(input.value, "foo", + description + "TIP.commitComposition(enterKeyEvent) should commit composition even if preceding keydown is consumed because there was a composition already"); + + // cancelComposition() should work even if preceding keydown event is consumed. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + ok(TIP.hasComposition, + description + "Before TIP.cancelComposition(escKeyEvent), composition should've been created"); + is(input.value, "foo", + description + "Before TIP.cancelComposition(escKeyEvent) should have composition string"); + reset(); + TIP.cancelComposition(escKeyEvent); + is(events.length, 4, + description + "TIP.cancelComposition(escKeyEvent) should cause keydown, compositionupdate, compositionend and keyup events even if preceding keydown is consumed because there was a composition already"); + is(events[0].type, "keydown", + description + "TIP.cancelComposition(escKeyEvent) should cause keydown event first"); + is(events[1].type, "compositionupdate", + description + "TIP.cancelComposition(escKeyEvent) should cause compositionupdate event after keydown"); + is(events[2].type, "compositionend", + description + "TIP.cancelComposition(escKeyEvent) should cause compositionend event after compositionupdate"); + is(events[3].type, "keyup", + description + "TIP.cancelComposition(escKeyEvent) should cause keyup event after compositionend"); + ok(!TIP.hasComposition, + description + "TIP.cancelComposition(escKeyEvent) should cause canceling composition even if preceding keydown is consumed because there was a composition already"); + is(input.value, "", + description + "TIP.cancelComposition(escKeyEvent) should cancel composition even if preceding keydown is consumed because there was a composition already"); + + SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition"); + + window.removeEventListener("compositionstart", handler, false); + window.removeEventListener("compositionupdate", handler, false); + window.removeEventListener("compositionend", handler, false); + window.removeEventListener("keydown", handler, false); + window.removeEventListener("keypress", handler, false); + window.removeEventListener("keyup", handler, false); +} + +function runKeyTests() +{ + var description = "runKeyTests(): "; + const kModifiers = + [ "Alt", "AltGraph", "CapsLock", "Control", "Fn", "FnLock", "Meta", "NumLock", + "ScrollLock", "Shift", "Symbol", "SymbolLock", "OS" ]; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed"); + + var events; + var doPreventDefaults; + + function reset() + { + events = []; + doPreventDefaults = []; + } + + function handler(aEvent) + { + events.push(aEvent); + if (doPreventDefaults.indexOf(aEvent.type) >= 0) { + aEvent.preventDefault(); + } + } + + function checkKeyAttrs(aMethodDescription, aEvent, aExpectedData) + { + var desc = description + aMethodDescription + ", type=\"" + aEvent.type + "\", key=\"" + aEvent.key + "\", code=\"" + aEvent.code + "\": "; + var defaultValues = { + key: "Unidentified", code: "", keyCode: 0, charCode: 0, + location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD, repeat: false, isComposing: false, + shiftKey: false, ctrlKey: false, altKey: false, metaKey: false, + defaultPrevented: false + }; + function expectedValue(aAttr) + { + return aExpectedData[aAttr] !== undefined ? aExpectedData[aAttr] : defaultValues[aAttr]; + } + is(aEvent.type, aExpectedData.type, + desc + " should cause keydown event"); + if (aEvent.type != aExpectedData.type) { + return; + } + is(aEvent.defaultPrevented, expectedValue("defaultPrevented"), + desc + ".defaultPrevented is wrong"); + is(aEvent.key, expectedValue("key"), + desc + ".key is wrong"); + if (SpecialPowers.getBoolPref("dom.keyboardevent.code.enabled")) { + is(aEvent.code, expectedValue("code"), + desc + ".code is wrong"); + } + is(aEvent.location, expectedValue("location"), + desc + ".location is wrong"); + is(aEvent.repeat, expectedValue("repeat"), + desc + ".repeat is wrong"); + is(aEvent.isComposing, expectedValue("isComposing"), + desc + ".isComposing is wrong"); + is(aEvent.keyCode, expectedValue("keyCode"), + desc + ".keyCode is wrong"); + is(aEvent.charCode, expectedValue("charCode"), + desc + ".charCode is wrong"); + is(aEvent.shiftKey, expectedValue("shiftKey"), + desc + ".shiftKey is wrong"); + is(aEvent.ctrlKey, expectedValue("ctrlKey"), + desc + ".ctrlKey is wrong"); + is(aEvent.altKey, expectedValue("altKey"), + desc + ".altKey is wrong"); + is(aEvent.metaKey, expectedValue("metaKey"), + desc + ".metaKey is wrong"); + for (var i = 0; i < kModifiers.length; i++) { + is(aEvent.getModifierState(kModifiers[i]), aExpectedData[kModifiers[i]] !== undefined ? aExpectedData[kModifiers[i]] : false, + desc + ".getModifierState(\"" + kModifiers[i] + "\") is wrong"); + } + } + + window.addEventListener("keydown", handler, false); + window.addEventListener("keypress", handler, false); + window.addEventListener("keyup", handler, false); + + input.value = ""; + input.focus(); + + + // Printable key test: + // Emulates pressing 'a' key. + var keyA = new KeyboardEvent("", { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + + reset(); + var doDefaultKeydown = TIP.keydown(keyA); + + is(doDefaultKeydown, TIP.KEYPRESS_IS_CONSUMED, + description + "TIP.keydown(keyA) should return 0x02 because the keypress event should be consumed by the input element"); + is(events.length, 2, + description + "TIP.keydown(keyA) should cause keydown and keypress event"); + checkKeyAttrs("TIP.keydown(keyA)", events[0], + { type: "keydown", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0 }); + checkKeyAttrs("TIP.keydown(keyA)", events[1], + { type: "keypress", key: "a", code: "KeyA", keyCode: 0, charCode: "a".charCodeAt(0), defaultPrevented: true }); + is(input.value, "a", + description + "input.value should be \"a\" which is inputted by TIP.keydown(keyA)"); + + // Emulates releasing 'a' key. + reset(); + var doDefaultKeyup = TIP.keyup(keyA); + ok(doDefaultKeyup, + description + "TIP.keyup(keyA) should return true"); + is(events.length, 1, + description + "TIP.keyup(keyA) should cause keyup event"); + checkKeyAttrs("TIP.keyup(keyA)", events[0], + { type: "keyup", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0 }); + is(input.value, "a", + description + "input.value should stay \"a\" which was inputted by TIP.keydown(keyA)"); + + + // Non-printable key test: + // Emulates pressing Enter key. + var keyEnter = new KeyboardEvent("", { key: "Enter", code: "Enter" }); + + reset(); + doDefaultKeydown = TIP.keydown(keyEnter); + + is(doDefaultKeydown, 0, + description + "TIP.keydown(keyEnter) should return 0"); + is(events.length, 2, + description + "TIP.keydown(keyEnter) should cause keydown and keypress event"); + checkKeyAttrs("TIP.keydown(keyEnter)", events[0], + { type: "keydown", key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + checkKeyAttrs("TIP.keydown(keyEnter)", events[1], + { type: "keypress", key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + is(input.value, "a", + description + "input.value should stay \"a\" which was inputted by TIP.keydown(keyA)"); + + // Emulates releasing Enter key. + reset(); + doDefaultKeyup = TIP.keyup(keyEnter); + ok(doDefaultKeyup, + description + "TIP.keyup(keyEnter) should return true"); + is(events.length, 1, + description + "TIP.keyup(keyEnter) should cause keyup event"); + checkKeyAttrs("TIP.keyup(keyEnter)", events[0], + { type: "keyup", key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + is(input.value, "a", + description + "input.value should stay \"a\" which was inputted by TIP.keydown(keyA)"); + + + // KEY_DEFAULT_PREVENTED should cause defaultPrevented = true and not cause keypress event + var keyB = new KeyboardEvent("", { key: "b", code: "KeyB", keyCode: KeyboardEvent.DOM_VK_B }); + + reset(); + doDefaultKeydown = TIP.keydown(keyB, TIP.KEY_DEFAULT_PREVENTED); + doDefaultKeyup = TIP.keyup(keyB, TIP.KEY_DEFAULT_PREVENTED); + + is(doDefaultKeydown, TIP.KEYDOWN_IS_CONSUMED, + description + "TIP.keydown(keyB, TIP.KEY_DEFAULT_PREVENTED) should return 0x01 because it's marked as consumed at dispatching the event"); + ok(!doDefaultKeyup, + description + "TIP.keyup(keyB, TIP.KEY_DEFAULT_PREVENTED) should return false because it's marked as consumed at dispatching the event"); + is(events.length, 2, + description + "TIP.keydown(keyB, TIP.KEY_DEFAULT_PREVENTED) and TIP.keyup(keyB, TIP.KEY_DEFAULT_PREVENTED) should cause keydown and keyup event"); + checkKeyAttrs("TIP.keydown(keyB, TIP.KEY_DEFAULT_PREVENTED) and TIP.keyup(keyB, TIP.KEY_DEFAULT_PREVENTED)", events[0], + { type: "keydown", key: "b", code: "KeyB", keyCode: KeyboardEvent.DOM_VK_B, defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyB, TIP.KEY_DEFAULT_PREVENTED) and TIP.keyup(keyB, TIP.KEY_DEFAULT_PREVENTED)", events[1], + { type: "keyup", key: "b", code: "KeyB", keyCode: KeyboardEvent.DOM_VK_B, defaultPrevented: true }); + is(input.value, "a", + description + "input.value shouldn't be modified by default prevented key events"); + + // Assume that KeyX causes inputting text "abc" + input.value = ""; + var keyABC = new KeyboardEvent("", { key: "abc", code: "KeyX", keyCode: KeyboardEvent.DOM_VK_A }); + + reset(); + doDefaultKeydown = TIP.keydown(keyABC); + doDefaultKeyup = TIP.keyup(keyABC); + + is(doDefaultKeydown, TIP.KEYPRESS_IS_CONSUMED, + description + "TIP.keydown(keyABC) should return false because the keypress events should be consumed by the input element"); + ok(doDefaultKeyup, + description + "TIP.keyup(keyABC) should return true"); + is(events.length, 5, + description + "TIP.keydown(keyABC) and TIP.keyup(keyABC) should cause keydown, keypress, keypress, keypress and keyup event"); + checkKeyAttrs("TIP.keydown(keyABC) and TIP.keyup(keyABC)", events[0], + { type: "keydown", key: "abc", code: "KeyX", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, defaultPrevented: false }); + checkKeyAttrs("TIP.keydown(keyABC) and TIP.keyup(keyABC)", events[1], + { type: "keypress", key: "abc".charAt(0), code: "KeyX", keyCode: 0, charCode: "abc".charCodeAt(0), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyABC) and TIP.keyup(keyABC)", events[2], + { type: "keypress", key: "abc".charAt(1), code: "KeyX", keyCode: 0, charCode: "abc".charCodeAt(1), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyABC) and TIP.keyup(keyABC)", events[3], + { type: "keypress", key: "abc".charAt(2), code: "KeyX", keyCode: 0, charCode: "abc".charCodeAt(2), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyABC) and TIP.keyup(keyABC)", events[4], + { type: "keyup", key: "abc", code: "KeyX", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, defaultPrevented: false }); + is(input.value, "abc", + description + "input.value should be \"abc\""); + + // If KEY_FORCE_PRINTABLE_KEY is specified, registered key names can be a printable key which inputs the specified value. + input.value = ""; + var keyEnterPrintable = new KeyboardEvent("", { key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + + reset(); + doDefaultKeydown = TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY); + doDefaultKeyup = TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY); + + is(doDefaultKeydown, TIP.KEYPRESS_IS_CONSUMED, + description + "TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) should return 0x02 because the keypress events should be consumed by the input element"); + ok(doDefaultKeyup, + description + "TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) should return true"); + is(events.length, 7, + description + "TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) should cause keydown, keypress, keypress, keypress, keypress, keypress and keyup event"); + checkKeyAttrs("TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)", events[0], + { type: "keydown", key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN, charCode: 0, defaultPrevented: false }); + checkKeyAttrs("TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)", events[1], + { type: "keypress", key: "Enter".charAt(0), code: "Enter", keyCode: 0, charCode: "Enter".charCodeAt(0), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)", events[2], + { type: "keypress", key: "Enter".charAt(1), code: "Enter", keyCode: 0, charCode: "Enter".charCodeAt(1), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)", events[3], + { type: "keypress", key: "Enter".charAt(2), code: "Enter", keyCode: 0, charCode: "Enter".charCodeAt(2), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)", events[4], + { type: "keypress", key: "Enter".charAt(3), code: "Enter", keyCode: 0, charCode: "Enter".charCodeAt(3), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)", events[5], + { type: "keypress", key: "Enter".charAt(4), code: "Enter", keyCode: 0, charCode: "Enter".charCodeAt(4), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY) and TIP.keyup(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)", events[6], + { type: "keyup", key: "Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN, charCode: 0, defaultPrevented: false }); + is(input.value, "Enter", + description + "input.value should be \"Enter\""); + + // modifiers should be ignored. + var keyWithModifiers = new KeyboardEvent("", { key: "Escape", code: "Escape", shiftKey: true, ctrlKey: true, altKey: true, metaKey: true }); + + reset(); + doDefaultKeydown = TIP.keydown(keyWithModifiers); + doDefaultKeyup = TIP.keyup(keyWithModifiers); + + is(doDefaultKeydown, 0, + description + "TIP.keydown(keyWithModifiers) should return 0"); + ok(doDefaultKeyup, + description + "TIP.keyup(keyWithModifiers) should return true"); + is(events.length, 3, + description + "TIP.keydown(keyWithModifiers) and TIP.keyup(keyWithModifiers) should cause keydown, keypress and keyup event"); + checkKeyAttrs("TIP.keydown(keyWithModifiers) and TIP.keyup(keyWithModifiers)", events[0], + { type: "keydown", key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }); + checkKeyAttrs("TIP.keydown(keyWithModifiers) and TIP.keyup(keyWithModifiers)", events[1], + { type: "keypress", key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }); + checkKeyAttrs("TIP.keydown(keyWithModifiers) and TIP.keyup(keyWithModifiers)", events[2], + { type: "keyup", key: "Escape", code: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }); + is(input.value, "Enter", + description + "input.value should stay \"Enter\" which was inputted by TIP.keydown(keyEnterPrintable, TIP.KEY_FORCE_PRINTABLE_KEY)"); + + // Call preventDefault() at keydown + input.value = ""; + reset(); + doPreventDefaults = [ "keydown" ]; + doDefaultKeydown = TIP.keydown(keyA); + doDefaultKeyup = TIP.keyup(keyA); + + is(doDefaultKeydown, TIP.KEYDOWN_IS_CONSUMED, + description + "TIP.keydown(keyA) should return 0x01 because keydown event's preventDefault should be called"); + ok(doDefaultKeyup, + description + "TIP.keyup(keyA) should return true"); + is(events.length, 2, + description + "TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keydown should cause keydown and keyup event"); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keydown", events[0], + { type: "keydown", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keydown", events[1], + { type: "keyup", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, defaultPrevented: false }); + is(input.value, "", + description + "input.value shouldn't be modified by TIP.keyup(keyA) if the keydown event is consumed"); + + // Call preventDefault() at keypress + reset(); + doPreventDefaults = [ "keypress" ]; + doDefaultKeydown = TIP.keydown(keyA); + doDefaultKeyup = TIP.keyup(keyA); + + is(doDefaultKeydown, TIP.KEYPRESS_IS_CONSUMED, + description + "TIP.keydown(keyA) should return 0x02 because keypress event's preventDefault should be called"); + ok(doDefaultKeyup, + description + "TIP.keyup(keyA) should return true"); + is(events.length, 3, + description + "TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keypress should cause keydown, keypress and keyup event"); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keypress", events[0], + { type: "keydown", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, defaultPrevented: false }); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keypress", events[1], + { type: "keypress", key: "a", code: "KeyA", keyCode: 0, charCode: "a".charCodeAt(0), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keypress", events[2], + { type: "keyup", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, defaultPrevented: false }); + is(input.value, "", + description + "input.value shouldn't be modified by TIP.keyup(keyA) if the keypress event is consumed"); + + // Call preventDefault() at keyup + input.value = ""; + reset(); + doPreventDefaults = [ "keyup" ]; + doDefaultKeydown = TIP.keydown(keyA); + doDefaultKeyup = TIP.keyup(keyA); + + is(doDefaultKeydown, TIP.KEYPRESS_IS_CONSUMED, + description + "TIP.keydown(keyA) should return 0x02 because the key event should be consumed by the input element"); + ok(!doDefaultKeyup, + description + "TIP.keyup(keyA) should return false because keyup event's preventDefault should be called"); + is(events.length, 3, + description + "TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keyup should cause keydown, keypress and keyup event"); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keyup", events[0], + { type: "keydown", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, defaultPrevented: false }); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keyup", events[1], + { type: "keypress", key: "a", code: "KeyA", keyCode: 0, charCode: "a".charCodeAt(0), defaultPrevented: true }); + checkKeyAttrs("TIP.keydown(keyA) and TIP.keyup(keyA) with preventing default of keyup", events[2], + { type: "keyup", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, defaultPrevented: true }); + is(input.value, "a", + description + "input.value should be \"a\" by TIP.keyup(keyA) even if the keyup event is consumed"); + + // key events during composition + try { + SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", false); + + ok(TIP.startComposition(), "TIP.startComposition() should start composition"); + + input.value = ""; + reset(); + TIP.keydown(keyA); + is(events.length, 0, + description + "TIP.keydown(keyA) shouldn't cause key events during composition if it's disabled by the pref"); + reset(); + TIP.keyup(keyA); + is(events.length, 0, + description + "TIP.keyup(keyA) shouldn't cause key events during composition if it's disabled by the pref"); + + SpecialPowers.setBoolPref("dom.keyboardevent.dispatch_during_composition", true); + reset(); + TIP.keydown(keyA); + is(events.length, 1, + description + "TIP.keydown(keyA) should cause keydown event even composition if it's enabled by the pref"); + checkKeyAttrs("TIP.keydown(keyA) during composition", events[0], + { type: "keydown", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, isComposing: true }); + reset(); + TIP.keyup(keyA); + is(events.length, 1, + description + "TIP.keyup(keyA) should cause keyup event even composition if it's enabled by the pref"); + checkKeyAttrs("TIP.keyup(keyA) during composition", events[0], + { type: "keyup", key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A, charCode: 0, isComposing: true }); + + } finally { + TIP.cancelComposition(); + SpecialPowers.clearUserPref("dom.keyboardevent.dispatch_during_composition"); + } + + // Test .location computation + const kCodeToLocation = [ + { code: "BracketLeft", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "BracketRight", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Comma", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit0", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit1", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit2", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit3", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit4", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit5", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit6", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit7", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit8", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Digit9", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Equal", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Minus", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Period", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Slash", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "AltLeft", location: KeyboardEvent.DOM_KEY_LOCATION_LEFT }, + { code: "AltRight", location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT }, + { code: "CapsLock", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "ContextMenu", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "ControlLeft", location: KeyboardEvent.DOM_KEY_LOCATION_LEFT }, + { code: "ControlRight", location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT }, + { code: "Enter", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "OSLeft", location: KeyboardEvent.DOM_KEY_LOCATION_LEFT }, + { code: "OSRight", location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT }, + { code: "ShiftLeft", location: KeyboardEvent.DOM_KEY_LOCATION_LEFT }, + { code: "ShiftRight", location: KeyboardEvent.DOM_KEY_LOCATION_RIGHT }, + { code: "Space", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Tab", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "ArrowDown", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "ArrowLeft", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "ArrowRight", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "ArrowUp", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "NumLock", location: KeyboardEvent.DOM_KEY_LOCATION_STANDARD }, + { code: "Numpad0", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad1", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad2", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad3", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad4", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad5", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad6", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad7", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad8", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "Numpad9", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadAdd", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadBackspace", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadClear", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadClearEntry", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadComma", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadDecimal", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadDivide", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadEnter", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadEqual", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadMemoryAdd", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadMemoryClear", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadMemoryRecall", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadMemoryStore", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadMemorySubtract", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadMultiply", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadParenLeft", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadParenRight", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + { code: "NumpadSubtract", location: KeyboardEvent.DOM_KEY_LOCATION_NUMPAD }, + ]; + for (var i = 0; i < kCodeToLocation.length; i++) { + var keyEvent = new KeyboardEvent("", { code: kCodeToLocation[i].code }); + reset(); + doPreventDefaults = [ "keypress" ]; + // If the location isn't initialized or initialized with 0, it should be computed from the code value. + TIP.keydown(keyEvent); + TIP.keyup(keyEvent); + var longDesc = description + "testing computation of .location of \"" + kCodeToLocation[i].code + "\", "; + is(events.length, 3, + longDesc + "keydown, keypress and keyup events should be fired"); + for (var j = 0; j < events.length; j++) { + is(events[j].location, kCodeToLocation[i].location, + longDesc + " type=\"" + events[j].type + "\", location value is wrong"); + } + // However, if KEY_KEEP_KEY_LOCATION_STANDARD is specified, .location value should be kept as DOM_KEY_LOCATION_STANDARD (0). + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(keyEvent, TIP.KEY_KEEP_KEY_LOCATION_STANDARD); + TIP.keyup(keyEvent, TIP.KEY_KEEP_KEY_LOCATION_STANDARD); + var longDesc = description + "testing if .location is forcibly set to DOM_KEY_LOCATION_STANDARD, "; + is(events.length, 3, + longDesc + "keydown, keypress and keyup events should be fired"); + for (var j = 0; j < events.length; j++) { + is(events[j].location, KeyboardEvent.DOM_KEY_LOCATION_STANDARD, + longDesc + " type=\"" + events[j].type + "\", location value is not 0"); + } + // If .location is initialized with non-zero value, the value shouldn't be computed again. + var keyEventWithLocation = new KeyboardEvent("", { code: kCodeToLocation[i].code, location: 0xFF }); + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(keyEventWithLocation); + TIP.keyup(keyEventWithLocation); + longDesc = description + "testing if .location is not computed for \"" + kCodeToLocation[i].location + "\", "; + is(events.length, 3, + longDesc + "keydown, keypress and keyup events should be fired"); + for (var j = 0; j < events.length; j++) { + is(events[j].location, 0xFF, + longDesc + " type=\"" + events[j].type + "\", location shouldn't be computed if it's initialized with non-zero value"); + } + } + + // Test .keyCode value computation + const kKeyToKeyCode = [ + { key: "Cancel", keyCode: KeyboardEvent.DOM_VK_CANCEL }, + { key: "Help", keyCode: KeyboardEvent.DOM_VK_HELP }, + { key: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE }, + { key: "Tab", keyCode: KeyboardEvent.DOM_VK_TAB }, + { key: "Clear", keyCode: KeyboardEvent.DOM_VK_CLEAR }, + { key: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }, + { key: "Shift", keyCode: KeyboardEvent.DOM_VK_SHIFT, isModifier: true }, + { key: "Control", keyCode: KeyboardEvent.DOM_VK_CONTROL, isModifier: true }, + { key: "Alt", keyCode: KeyboardEvent.DOM_VK_ALT, isModifier: true }, + { key: "Pause", keyCode: KeyboardEvent.DOM_VK_PAUSE }, + { key: "CapsLock", keyCode: KeyboardEvent.DOM_VK_CAPS_LOCK, isModifier: true, isLockableModifier: true }, + { key: "Hiragana", keyCode: KeyboardEvent.DOM_VK_KANA }, + { key: "Katakana", keyCode: KeyboardEvent.DOM_VK_KANA }, + { key: "HiraganaKatakana", keyCode: KeyboardEvent.DOM_VK_KANA }, + { key: "KanaMode", keyCode: KeyboardEvent.DOM_VK_KANA }, + { key: "HangulMode", keyCode: KeyboardEvent.DOM_VK_HANGUL }, + { key: "Eisu", keyCode: KeyboardEvent.DOM_VK_EISU }, + { key: "JunjaMode", keyCode: KeyboardEvent.DOM_VK_JUNJA }, + { key: "FinalMode", keyCode: KeyboardEvent.DOM_VK_FINAL }, + { key: "HanjaMode", keyCode: KeyboardEvent.DOM_VK_HANJA }, + { key: "KanjiMode", keyCode: KeyboardEvent.DOM_VK_KANJI }, + { key: "Escape", keyCode: KeyboardEvent.DOM_VK_ESCAPE }, + { key: "Convert", keyCode: KeyboardEvent.DOM_VK_CONVERT }, + { key: "NonConvert", keyCode: KeyboardEvent.DOM_VK_NONCONVERT }, + { key: "Accept", keyCode: KeyboardEvent.DOM_VK_ACCEPT }, + { key: "ModeChange", keyCode: KeyboardEvent.DOM_VK_MODECHANGE }, + { key: "PageUp", keyCode: KeyboardEvent.DOM_VK_PAGE_UP }, + { key: "PageDown", keyCode: KeyboardEvent.DOM_VK_PAGE_DOWN }, + { key: "End", keyCode: KeyboardEvent.DOM_VK_END }, + { key: "Home", keyCode: KeyboardEvent.DOM_VK_HOME }, + { key: "ArrowLeft", keyCode: KeyboardEvent.DOM_VK_LEFT }, + { key: "ArrowUp", keyCode: KeyboardEvent.DOM_VK_UP }, + { key: "ArrowRight", keyCode: KeyboardEvent.DOM_VK_RIGHT }, + { key: "ArrowDown", keyCode: KeyboardEvent.DOM_VK_DOWN }, + { key: "Select", keyCode: KeyboardEvent.DOM_VK_SELECT }, + { key: "Print", keyCode: KeyboardEvent.DOM_VK_PRINT }, + { key: "Execute", keyCode: KeyboardEvent.DOM_VK_EXECUTE }, + { key: "PrintScreen", keyCode: KeyboardEvent.DOM_VK_PRINTSCREEN }, + { key: "Insert", keyCode: KeyboardEvent.DOM_VK_INSERT }, + { key: "Delete", keyCode: KeyboardEvent.DOM_VK_DELETE }, + { key: "OS", keyCode: KeyboardEvent.DOM_VK_WIN, isModifier: true }, + { key: "ContextMenu", keyCode: KeyboardEvent.DOM_VK_CONTEXT_MENU }, + { key: "F1", keyCode: KeyboardEvent.DOM_VK_F1 }, + { key: "F2", keyCode: KeyboardEvent.DOM_VK_F2 }, + { key: "F3", keyCode: KeyboardEvent.DOM_VK_F3 }, + { key: "F4", keyCode: KeyboardEvent.DOM_VK_F4 }, + { key: "F5", keyCode: KeyboardEvent.DOM_VK_F5 }, + { key: "F6", keyCode: KeyboardEvent.DOM_VK_F6 }, + { key: "F7", keyCode: KeyboardEvent.DOM_VK_F7 }, + { key: "F8", keyCode: KeyboardEvent.DOM_VK_F8 }, + { key: "F9", keyCode: KeyboardEvent.DOM_VK_F9 }, + { key: "F10", keyCode: KeyboardEvent.DOM_VK_F10 }, + { key: "F11", keyCode: KeyboardEvent.DOM_VK_F11 }, + { key: "F12", keyCode: KeyboardEvent.DOM_VK_F12 }, + { key: "F13", keyCode: KeyboardEvent.DOM_VK_F13 }, + { key: "F14", keyCode: KeyboardEvent.DOM_VK_F14 }, + { key: "F15", keyCode: KeyboardEvent.DOM_VK_F15 }, + { key: "F16", keyCode: KeyboardEvent.DOM_VK_F16 }, + { key: "F17", keyCode: KeyboardEvent.DOM_VK_F17 }, + { key: "F18", keyCode: KeyboardEvent.DOM_VK_F18 }, + { key: "F19", keyCode: KeyboardEvent.DOM_VK_F19 }, + { key: "F20", keyCode: KeyboardEvent.DOM_VK_F20 }, + { key: "F21", keyCode: KeyboardEvent.DOM_VK_F21 }, + { key: "F22", keyCode: KeyboardEvent.DOM_VK_F22 }, + { key: "F23", keyCode: KeyboardEvent.DOM_VK_F23 }, + { key: "F24", keyCode: KeyboardEvent.DOM_VK_F24 }, + { key: "NumLock", keyCode: KeyboardEvent.DOM_VK_NUM_LOCK, isModifier: true, isLockableModifier: true }, + { key: "ScrollLock", keyCode: KeyboardEvent.DOM_VK_SCROLL_LOCK, isModifier: true, isLockableModifier: true }, + { key: "AudioVolumeMute", keyCode: KeyboardEvent.DOM_VK_VOLUME_MUTE }, + { key: "AudioVolumeDown", keyCode: KeyboardEvent.DOM_VK_VOLUME_DOWN }, + { key: "AudioVolumeUp", keyCode: KeyboardEvent.DOM_VK_VOLUME_UP }, + { key: "Meta", keyCode: KeyboardEvent.DOM_VK_META, isModifier: true }, + { key: "AltGraph", keyCode: KeyboardEvent.DOM_VK_ALTGR, isModifier: true }, + { key: "Attn", keyCode: KeyboardEvent.DOM_VK_ATTN }, + { key: "CrSel", keyCode: KeyboardEvent.DOM_VK_CRSEL }, + { key: "ExSel", keyCode: KeyboardEvent.DOM_VK_EXSEL }, + { key: "EraseEof", keyCode: KeyboardEvent.DOM_VK_EREOF }, + { key: "Play", keyCode: KeyboardEvent.DOM_VK_PLAY }, + { key: "ZoomToggle", keyCode: KeyboardEvent.DOM_VK_ZOOM }, + { key: "ZoomIn", keyCode: KeyboardEvent.DOM_VK_ZOOM }, + { key: "ZoomOut", keyCode: KeyboardEvent.DOM_VK_ZOOM }, + { key: "Unidentified", keyCode: 0 }, + { key: "a", keyCode: 0, isPrintable: true }, + { key: "A", keyCode: 0, isPrintable: true }, + { key: " ", keyCode: 0, isPrintable: true }, + { key: "", keyCode: 0, isPrintable: true }, + ]; + + for (var i = 0; i < kKeyToKeyCode.length; i++) { + var keyEvent = new KeyboardEvent("", { key: kKeyToKeyCode[i].key }); + var causeKeypress = !kKeyToKeyCode[i].isModifier; + var baseFlags = kKeyToKeyCode[i].isPrintable ? 0 : TIP.KEY_NON_PRINTABLE_KEY; + reset(); + doPreventDefaults = [ "keypress" ]; + // If the keyCode isn't initialized or initialized with 0, it should be computed from the key value only when it's a printable key. + TIP.keydown(keyEvent, baseFlags); + TIP.keyup(keyEvent, baseFlags); + var longDesc = description + "testing computation of .keyCode of \"" + kKeyToKeyCode[i].key + "\", "; + is(events.length, causeKeypress ? 3 : 2, + longDesc + "keydown" + (causeKeypress ? ", keypress" : "") + " and keyup events should be fired"); + for (var j = 0; j < events.length; j++) { + is(events[j].keyCode, events[j].type == "keypress" && kKeyToKeyCode[i].isPrintable ? 0 : kKeyToKeyCode[i].keyCode, + longDesc + " type=\"" + events[j].type + "\", keyCode value is wrong"); + } + // However, if KEY_KEEP_KEYCODE_ZERO is specified, .keyCode value should be kept as 0. + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(keyEvent, TIP.KEY_KEEP_KEYCODE_ZERO | baseFlags); + TIP.keyup(keyEvent, TIP.KEY_KEEP_KEYCODE_ZERO | baseFlags); + var longDesc = description + "testing if .keyCode is forcibly set to KEY_KEEP_KEYCODE_ZERO, "; + is(events.length, causeKeypress ? 3 : 2, + longDesc + "keydown" + (causeKeypress ? ", keypress" : "") + " and keyup events should be fired"); + for (var j = 0; j < events.length; j++) { + is(events[j].keyCode, 0, + longDesc + " type=\"" + events[j].type + "\", keyCode value is not 0"); + } + // If .keyCode is initialized with non-zero value, the value shouldn't be computed again. + var keyEventWithLocation = new KeyboardEvent("", { key: kKeyToKeyCode[i].key, keyCode: 0xFF }); + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(keyEventWithLocation, baseFlags); + TIP.keyup(keyEventWithLocation, baseFlags); + longDesc = description + "testing if .keyCode is not computed for \"" + kKeyToKeyCode[i].key + "\", "; + is(events.length, causeKeypress ? 3 : 2, + longDesc + "keydown" + (causeKeypress ? ", keypress" : "") + " and keyup events should be fired"); + for (var j = 0; j < events.length; j++) { + is(events[j].keyCode, events[j].type == "keypress" && kKeyToKeyCode[i].isPrintable ? 0 : 0xFF, + longDesc + " type=\"" + events[j].type + "\", keyCode shouldn't be computed if it's initialized with non-zero value"); + } + // Unlock lockable modifier if the key is a lockable modifier key. + if (kKeyToKeyCode[i].isLockableModifier) { + TIP.keydown(keyEvent, baseFlags); + TIP.keyup(keyEvent, baseFlags); + } + } + + // Modifier state tests + var sharedTIP = createTIP(); + ok(sharedTIP.beginInputTransactionForTests(otherWindow), + description + "sharedTIP.beginInputTransactionForTests(otherWindow) should return true"); + TIP.shareModifierStateOf(sharedTIP); + var independentTIP = createTIP(); + const kModifierKeys = [ + { key: "Alt", code: "AltLeft", isLockable: false }, + { key: "Alt", code: "AltRight", isLockable: false }, + { key: "AltGraph", code: "AltRight", isLockable: false }, + { key: "CapsLock", code: "CapsLock", isLockable: true }, + { key: "Control", code: "ControlLeft", isLockable: false }, + { key: "Control", code: "ControlRight", isLockable: false }, + { key: "Fn", code: "Fn", isLockable: false }, + { key: "FnLock", code: "", isLockable: true }, + { key: "Meta", code: "OSLeft", isLockable: false }, + { key: "Meta", code: "OSRight", isLockable: false }, + { key: "NumLock", code: "NumLock", isLockable: true }, + { key: "ScrollLock", code: "ScrollLock", isLockable: true }, + { key: "Shift", code: "ShiftLeft", isLockable: false }, + { key: "Shift", code: "ShiftRight", isLockable: false }, + { key: "Symbol", code: "", isLockable: false }, + { key: "SymbolLock", code: "", isLockable: true }, + { key: "OS", code: "OSLeft", isLockable: false }, + { key: "OS", code: "OSRight", isLockable: false }, + ]; + + function checkModifiers(aTestDesc, aEvent, aType, aKey, aCode, aModifiers) + { + var desc = description + aTestDesc + ", type=\"" + aEvent.type + "\", key=\"" + aEvent.key + "\", code=\"" + aEvent.code + "\""; + is(aEvent.type, aType, + desc + ", .type value is wrong"); + if (aEvent.type != aType) { + return; + } + is(aEvent.key, aKey, + desc + ", .key value is wrong"); + if (SpecialPowers.getBoolPref("dom.keyboardevent.code.enabled")) { + is(aEvent.code, aCode, + desc + ", .code value is wrong"); + } + is(aEvent.altKey, aModifiers.indexOf("Alt") >= 0, + desc + ", .altKey value is wrong"); + is(aEvent.ctrlKey, aModifiers.indexOf("Control") >= 0, + desc + ", .ctrlKey value is wrong"); + is(aEvent.metaKey, aModifiers.indexOf("Meta") >= 0, + desc + ", .metaKey value is wrong"); + is(aEvent.shiftKey, aModifiers.indexOf("Shift") >= 0, + desc + ", .shiftKey value is wrong"); + for (var i = 0; i < kModifiers.length; i++) { + is(aEvent.getModifierState(kModifiers[i]), aModifiers.indexOf(kModifiers[i]) >= 0, + desc + ", .getModifierState(\"" + kModifiers[i] + "\") returns wrong value"); + } + } + + function checkAllTIPModifiers(aTestDesc, aModifiers) + { + for (var i = 0; i < kModifiers.length; i++) { + is(TIP.getModifierState(kModifiers[i]), aModifiers.indexOf(kModifiers[i]) >= 0, + aTestDesc + ", TIP.getModifierState(\"" + kModifiers[i] + "\") returns wrong value"); + is(sharedTIP.getModifierState(kModifiers[i]), TIP.getModifierState(kModifiers[i]), + aTestDesc + ", sharedTIP.getModifierState(\"" + kModifiers[i] + "\") returns different value from TIP"); + is(independentTIP.getModifierState(kModifiers[i]), false, + aTestDesc + ", independentTIP.getModifierState(\"" + kModifiers[i] + "\") should return false"); + } + } + + // First, all modifiers must be false. + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(keyA); + TIP.keyup(keyA); + + is(events.length, 3, + description + "TIP.keydown(keyA) and TIP.keyup(keyA) should cause keydown, keypress and keyup"); + checkModifiers("Before dispatching modifier key events", events[0], "keydown", "a", "KeyA", []); + checkModifiers("Before dispatching modifier key events", events[1], "keypress", "a", "KeyA", []); + checkModifiers("Before dispatching modifier key events", events[2], "keyup", "a", "KeyA", []); + + // Test each modifier keydown/keyup causes activating/inactivating the modifier state. + for (var i = 0; i < kModifierKeys.length; i++) { + reset(); + doPreventDefaults = [ "keypress" ]; + var modKey = new KeyboardEvent("", { key: kModifierKeys[i].key, code: kModifierKeys[i].code }); + var testDesc = "A modifier key \"" + kModifierKeys[i].key + "\" (\"" + kModifierKeys[i].code + "\") and a printable key"; + if (!kModifierKeys[i].isLockable) { + TIP.keydown(modKey); + checkAllTIPModifiers(testDesc + ", \"" + kModifierKeys[i].key + "\" keydown", [ kModifierKeys[i].key ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ kModifierKeys[i].key ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ kModifierKeys[i].key ]); + TIP.keyup(modKey); + checkAllTIPModifiers(testDesc + ", \"" + kModifierKeys[i].key + "\" keyup", [ ]); + is(events.length, 5, + description + testDesc + " should cause 5 events"); + checkModifiers(testDesc, events[0], "keydown", kModifierKeys[i].key, kModifierKeys[i].code, [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[1], "keydown", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[2], "keypress", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[3], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[4], "keyup", kModifierKeys[i].key, kModifierKeys[i].code, [ ]); + + // KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT shouldn't cause key events of modifier keys, but should modify the modifier state. + reset(); + doPreventDefaults = [ "keypress" ]; + testDesc = "A modifier key \"" + kModifierKeys[i].key + "\" (\"" + kModifierKeys[i].code + "\") with KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT and a printable key"; + TIP.keydown(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + TIP.keydown(keyA); + TIP.keyup(keyA); + TIP.keyup(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + TIP.keydown(keyA); + TIP.keyup(keyA); + is(events.length, 6, + description + testDesc + " should cause 6 events"); + checkModifiers(testDesc, events[0], "keydown", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[1], "keypress", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[2], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[3], "keydown", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[4], "keypress", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[5], "keyup", "a", "KeyA", [ ]); + } else { + TIP.keydown(modKey); + checkAllTIPModifiers(testDesc + ", \"" + kModifierKeys[i].key + "\" first keydown", [ kModifierKeys[i].key ]); + TIP.keyup(modKey); + checkAllTIPModifiers(testDesc + ", \"" + kModifierKeys[i].key + "\" first keyup", [ kModifierKeys[i].key ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ kModifierKeys[i].key ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ kModifierKeys[i].key ]); + TIP.keydown(modKey); + checkAllTIPModifiers(testDesc + ", \"" + kModifierKeys[i].key + "\" second keydown", [ ]); + TIP.keyup(modKey); + checkAllTIPModifiers(testDesc + ", \"" + kModifierKeys[i].key + "\" second keyup", [ ]); + is(events.length, 7, + description + testDesc + " should cause 7 events"); + checkModifiers(testDesc, events[0], "keydown", kModifierKeys[i].key, kModifierKeys[i].code, [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[1], "keyup", kModifierKeys[i].key, kModifierKeys[i].code, [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[5], "keydown", kModifierKeys[i].key, kModifierKeys[i].code, [ ]); + checkModifiers(testDesc, events[6], "keyup", kModifierKeys[i].key, kModifierKeys[i].code, [ ]); + + // KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT shouldn't cause key events of modifier keys, but should modify the modifier state. + reset(); + doPreventDefaults = [ "keypress" ]; + testDesc = "A modifier key \"" + kModifierKeys[i].key + "\" (\"" + kModifierKeys[i].code + "\") with KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT and a printable key"; + TIP.keydown(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + TIP.keyup(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + TIP.keydown(keyA); + TIP.keyup(keyA); + TIP.keydown(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + TIP.keyup(modKey, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + TIP.keydown(keyA); + TIP.keyup(keyA); + is(events.length, 6, + description + testDesc + " should cause 6 events"); + checkModifiers(testDesc, events[0], "keydown", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[1], "keypress", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[2], "keyup", "a", "KeyA", [ kModifierKeys[i].key ]); + checkModifiers(testDesc, events[3], "keydown", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[4], "keypress", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[5], "keyup", "a", "KeyA", [ ]); + } + } + + // Modifier state should be inactivated only when all pressed modifiers are released + var shiftLeft = new KeyboardEvent("", { key: "Shift", code: "ShiftLeft" }); + var shiftRight = new KeyboardEvent("", { key: "Shift", code: "ShiftRight" }); + var shiftVirtual = new KeyboardEvent("", { key: "Shift", code: "" }); + var altGrVirtual = new KeyboardEvent("", { key: "AltGraph", code: "" }); + var ctrlVirtual = new KeyboardEvent("", { key: "Control", code: "" }); + + var testDesc = "ShiftLeft press -> ShiftRight press -> ShiftRight release -> ShiftLeft release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keydown", [ "Shift" ]); + TIP.keydown(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keydown", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift" ]); + TIP.keyup(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keyup", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Right-Shift keyup)", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Right-Shift keyup)", [ "Shift" ]); + TIP.keyup(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keyup", [ ]); + + is(events.length, 10, + description + testDesc + " should cause 10 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "ShiftLeft", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[5], "keyup", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[9], "keyup", "Shift", "ShiftLeft", [ ]); + + testDesc = "ShiftLeft press -> ShiftRight press -> ShiftLeft release -> ShiftRight release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keydown", [ "Shift" ]); + TIP.keydown(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keydown", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift" ]); + TIP.keyup(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keyup", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Left-Shift keyup)", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Left-Shift keyup)", [ "Shift" ]); + TIP.keyup(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keyup", [ ]); + + is(events.length, 10, + description + testDesc + " should cause 10 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "ShiftLeft", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[5], "keyup", "Shift", "ShiftLeft", [ "Shift" ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[9], "keyup", "Shift", "ShiftRight", [ ]); + + testDesc = "ShiftLeft press -> virtual Shift press -> virtual Shift release -> ShiftLeft release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keydown", [ "Shift" ]); + TIP.keydown(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keydown", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift" ]); + TIP.keyup(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keyup", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Virtual-Shift keyup)", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Virtual-Shift keyup)", [ "Shift" ]); + TIP.keyup(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keyup", [ ]); + + is(events.length, 10, + description + testDesc + " should cause 10 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "ShiftLeft", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "Shift", "", [ "Shift" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[5], "keyup", "Shift", "", [ "Shift" ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[9], "keyup", "Shift", "ShiftLeft", [ ]); + + testDesc = "virtual Shift press -> ShiftRight press -> ShiftRight release -> virtual Shift release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keydown", [ "Shift" ]); + TIP.keydown(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keydown", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift" ]); + TIP.keyup(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keyup", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Right-Shift keyup)", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Right-Shift keyup)", [ "Shift" ]); + TIP.keyup(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keyup", [ ]); + + is(events.length, 10, + description + testDesc + " should cause 10 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[5], "keyup", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[9], "keyup", "Shift", "", [ ]); + + testDesc = "ShiftLeft press -> ShiftRight press -> ShiftRight release -> ShiftRight release -> ShiftLeft release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keydown", [ "Shift" ]); + TIP.keydown(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keydown", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift" ]); + TIP.keyup(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keyup", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Virtual-Shift keyup)", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Virtual-Shift keyup)", [ "Shift" ]); + TIP.keyup(shiftRight); + checkAllTIPModifiers(testDesc + ", Right-Shift keyup again", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Virtual-Shift keyup again)", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Virtual-Shift keyup again)", [ "Shift" ]); + TIP.keyup(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keyup", [ ]); + + is(events.length, 14, + description + testDesc + " should cause 14 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "ShiftLeft", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[5], "keyup", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[9], "keyup", "Shift", "ShiftRight", [ "Shift" ]); + checkModifiers(testDesc, events[10], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[11], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[12], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[13], "keyup", "Shift", "ShiftLeft", [ ]); + + testDesc = "ShiftLeft press -> ShiftLeft press -> ShiftLeft release -> ShiftLeft release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keydown", [ "Shift" ]); + TIP.keydown(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keydown again", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift" ]); + TIP.keyup(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keyup", [ ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Left-Shift keyup)", [ ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Left-Shift keyup)", [ ]); + TIP.keyup(shiftLeft); + checkAllTIPModifiers(testDesc + ", Left-Shift keyup again", [ ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Left-Shift keyup again)", [ ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Left-Shift keyup again)", [ ]); + + is(events.length, 13, + description + testDesc + " should cause 13 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "ShiftLeft", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "Shift", "ShiftLeft", [ "Shift" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[5], "keyup", "Shift", "ShiftLeft", [ ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[9], "keyup", "Shift", "ShiftLeft", [ ]); + checkModifiers(testDesc, events[10], "keydown", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[11], "keypress", "a", "KeyA", [ ]); + checkModifiers(testDesc, events[12], "keyup", "a", "KeyA", [ ]); + + testDesc = "virtual Shift press -> virtual AltGraph press -> virtual AltGraph release -> virtual Shift release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keydown", [ "Shift" ]); + TIP.keydown(altGrVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-AltGraph keydown", [ "Shift", "AltGraph" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift", "AltGraph" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift", "AltGraph" ]); + TIP.keyup(altGrVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-AltGraph keyup", [ "Shift" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Virtual-AltGraph keyup)", [ "Shift" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Virtual-AltGraph keyup)", [ "Shift" ]); + TIP.keyup(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keyup", [ ]); + + is(events.length, 10, + description + testDesc + " should cause 10 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "AltGraph", "", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[5], "keyup", "AltGraph", "", [ "Shift" ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ "Shift" ]); + checkModifiers(testDesc, events[9], "keyup", "Shift", "", [ ]); + + testDesc = "virtual Shift press -> virtual AltGraph press -> virtual Shift release -> virtual AltGr release"; + reset(); + doPreventDefaults = [ "keypress" ]; + TIP.keydown(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keydown", [ "Shift" ]); + TIP.keydown(altGrVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-AltGraph keydown", [ "Shift", "AltGraph" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown", [ "Shift", "AltGraph" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup", [ "Shift", "AltGraph" ]); + TIP.keyup(shiftVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-Shift keyup", [ "AltGraph" ]); + TIP.keydown(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keydown (after Virtual-Shift keyup)", [ "AltGraph" ]); + TIP.keyup(keyA); + checkAllTIPModifiers(testDesc + ", \"a\" keyup (after Virtual-Shift keyup)", [ "AltGraph" ]); + TIP.keyup(altGrVirtual); + checkAllTIPModifiers(testDesc + ", Virtual-AltGraph keyup", [ ]); + + is(events.length, 10, + description + testDesc + " should cause 10 events"); + checkModifiers(testDesc, events[0], "keydown", "Shift", "", [ "Shift" ]); + checkModifiers(testDesc, events[1], "keydown", "AltGraph", "", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[2], "keydown", "a", "KeyA", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[3], "keypress", "a", "KeyA", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[4], "keyup", "a", "KeyA", [ "Shift", "AltGraph" ]); + checkModifiers(testDesc, events[5], "keyup", "Shift", "", [ "AltGraph" ]); + checkModifiers(testDesc, events[6], "keydown", "a", "KeyA", [ "AltGraph" ]); + checkModifiers(testDesc, events[7], "keypress", "a", "KeyA", [ "AltGraph" ]); + checkModifiers(testDesc, events[8], "keyup", "a", "KeyA", [ "AltGraph" ]); + checkModifiers(testDesc, events[9], "keyup", "AltGraph", "", [ ]); + + // shareModifierStateOf(null) should cause resetting the modifier state + function checkTIPModifiers(aTestDesc, aTIP, aModifiers) + { + for (var i = 0; i < kModifiers.length; i++) { + is(aTIP.getModifierState(kModifiers[i]), aModifiers.indexOf(kModifiers[i]) >= 0, + description + aTestDesc + ", aTIP.getModifierState(\"" + kModifiers[i] + "\") returns wrong value"); + } + } + TIP.keydown(shiftVirtual); + TIP.keydown(altGrVirtual); + sharedTIP.shareModifierStateOf(null); + checkTIPModifiers("sharedTIP.sharedModifierStateOf(null) shouldn't cause TIP's modifiers reset", TIP, [ "Shift", "AltGraph" ]); + checkTIPModifiers("sharedTIP.sharedModifierStateOf(null) should cause sharedTIP modifiers reset", sharedTIP, [ ]); + + // sharedTIP.shareModifierStateOf(null) should be unlinked from TIP. + TIP.keydown(ctrlVirtual); + checkTIPModifiers("TIP.keydown(ctrlVirtual) should cause TIP's modifiers set", TIP, [ "Shift", "AltGraph", "Control" ]); + checkTIPModifiers("TIP.keydown(ctrlVirtual) shouldn't cause sharedTIP modifiers set", sharedTIP, [ ]); + + // beginInputTransactionForTests() shouldn't cause modifier state reset. + ok(TIP.beginInputTransactionForTests(otherWindow), + description + "TIP.beginInputTransactionForTests(otherWindow) should return true"); + checkTIPModifiers("TIP.beginInputTransactionForTests(otherWindow) shouldn't cause TIP's modifiers set", TIP, [ "Shift", "AltGraph", "Control" ]); + TIP.keyup(shiftLeft); + TIP.keyup(altGrVirtual); + TIP.keyup(ctrlVirtual); + checkTIPModifiers("TIP should keep modifier's physical key state", TIP, [ "Shift" ]); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests(window) should return true"); + checkTIPModifiers("TIP.beginInputTransactionForTests(window) shouldn't cause TIP's modifiers set", TIP, [ "Shift" ]); + TIP.keyup(shiftVirtual); + checkTIPModifiers("TIP should keep modifier's physical key state", TIP, [ ]); + + window.removeEventListener("keydown", handler, false); + window.removeEventListener("keypress", handler, false); + window.removeEventListener("keyup", handler, false); +} + +function runErrorTests() +{ + var description = "runErrorTests(): "; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed"); + + input.value = ""; + input.focus(); + + // startComposition() should throw an exception if there is already a composition + TIP.startComposition(); + try { + TIP.startComposition(); + ok(false, + description + "startComposition() should fail if it was already called"); + } catch (e) { + ok(e.message.includes("NS_ERROR_FAILURE"), + description + "startComposition() should cause NS_ERROR_FAILURE if there is already composition"); + } finally { + TIP.cancelComposition(); + } + + // cancelComposition() should throw an exception if there is no composition + try { + TIP.cancelComposition(); + ok(false, + description + "cancelComposition() should fail if there is no composition"); + } catch (e) { + ok(e.message.includes("NS_ERROR_FAILURE"), + description + "cancelComposition() should cause NS_ERROR_FAILURE if there is no composition"); + } + + // commitComposition() without commit string should throw an exception if there is no composition + try { + TIP.commitComposition(); + ok(false, + description + "commitComposition() should fail if there is no composition"); + } catch (e) { + ok(e.message.includes("NS_ERROR_FAILURE"), + description + "commitComposition() should cause NS_ERROR_FAILURE if there is no composition"); + } + + // commitCompositionWith("") should throw an exception if there is no composition + try { + TIP.commitCompositionWith(""); + ok(false, + description + "commitCompositionWith(\"\") should fail if there is no composition"); + } catch (e) { + ok(e.message.includes("NS_ERROR_FAILURE"), + description + "commitCompositionWith(\"\") should cause NS_ERROR_FAILURE if there is no composition"); + } + + // Pending composition string should allow to flush without clause information (for compatibility) + try { + TIP.setPendingCompositionString("foo"); + TIP.flushPendingComposition(); + ok(true, + description + "flushPendingComposition() should succeed even if appendClauseToPendingComposition() has never been called"); + TIP.cancelComposition(); + } catch (e) { + ok(false, + description + "flushPendingComposition() shouldn't cause an exception even if appendClauseToPendingComposition() has never been called"); + } + + // Pending composition string must be filled by clause information + try { + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(2, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + ok(false, + description + "flushPendingComposition() should fail if appendClauseToPendingComposition() doesn't fill all composition string"); + TIP.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "flushPendingComposition() should cause NS_ERROR_ILLEGAL_VALUE if appendClauseToPendingComposition() doesn't fill all composition string"); + } + + // Pending composition string must not be shorter than appended clause length + try { + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(4, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + ok(false, + description + "flushPendingComposition() should fail if appendClauseToPendingComposition() appends longer clause information"); + TIP.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "flushPendingComposition() should cause NS_ERROR_ILLEGAL_VALUE if appendClauseToPendingComposition() appends longer clause information"); + } + + // Pending composition must not have clause information with empty string + try { + TIP.appendClauseToPendingComposition(1, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + ok(false, + description + "flushPendingComposition() should fail if there is a clause with empty string"); + TIP.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "flushPendingComposition() should cause NS_ERROR_ILLEGAL_VALUE if there is a clause with empty string"); + } + + // Appending a clause whose length is 0 should cause an exception + try { + TIP.appendClauseToPendingComposition(0, TIP.ATTR_RAW_CLAUSE); + ok(false, + description + "appendClauseToPendingComposition() should fail if the length is 0"); + TIP.flushPendingComposition(); + TIP.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "appendClauseToPendingComposition() should cause NS_ERROR_ILLEGAL_VALUE if the length is 0"); + } + + // Appending a clause whose attribute is invalid should cause an exception + try { + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, 0); + ok(false, + description + "appendClauseToPendingComposition() should fail if the attribute is invalid"); + TIP.flushPendingComposition(); + TIP.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "appendClauseToPendingComposition() should cause NS_ERROR_ILLEGAL_VALUE if the attribute is invalid"); + } + + // Setting caret position outside of composition string should cause an exception + try { + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(4); + TIP.flushPendingComposition(); + ok(false, + description + "flushPendingComposition() should fail if caret position is out of composition string"); + TIP.cancelComposition(); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "flushPendingComposition() should cause NS_ERROR_ILLEGAL_VALUE if caret position is out of composition string"); + } + + // Calling keydown() with a KeyboardEvent initialized with invalid code value should cause an exception. + input.value = ""; + try { + var keyInvalidCode = new KeyboardEvent("", { key: "f", code: "InvalidCodeValue", keyCode: KeyboardEvent.DOM_VK_F }); + TIP.keydown(keyInvalidCode); + ok(false, + description + "TIP.keydown(keyInvalidCode) should cause throwing an exception because its code value is not registered"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "TIP.keydown(keyInvalidCode) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE"); + } finally { + is(input.value, "", + description + "The input element should not be modified"); + } + + // Calling keyup() with a KeyboardEvent initialized with invalid code value should cause an exception. + input.value = ""; + try { + var keyInvalidCode = new KeyboardEvent("", { key: "f", code: "InvalidCodeValue", keyCode: KeyboardEvent.DOM_VK_F }); + TIP.keyup(keyInvalidCode); + ok(false, + description + "TIP.keyup(keyInvalidCode) should cause throwing an exception because its code value is not registered"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "TIP.keyup(keyInvalidCode) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE"); + } finally { + is(input.value, "", + description + "The input element should not be modified"); + } + + // Calling keydown(KEY_NON_PRINTABLE_KEY) with a KeyboardEvent initialized with non-key name should cause an exception. + input.value = ""; + try { + var keyInvalidKey = new KeyboardEvent("", { key: "ESCAPE", code: "Escape", keyCode: KeyboardEvent.DOM_VK_Escape}); + TIP.keydown(keyInvalidKey, TIP.KEY_NON_PRINTABLE_KEY); + ok(false, + description + "TIP.keydown(keyInvalidKey, TIP.KEY_NON_PRINTABLE_KEY) should cause throwing an exception because its key value is not registered"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keydown(keyInvalidKey, TIP.KEY_NON_PRINTABLE_KEY) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE"); + } finally { + is(input.value, "", + description + "The input element should not be modified"); + } + + // Calling keyup(KEY_NON_PRINTABLE_KEY) with a KeyboardEvent initialized with non-key name should cause an exception. + input.value = ""; + try { + var keyInvalidKey = new KeyboardEvent("", { key: "ESCAPE", code: "Escape", keyCode: KeyboardEvent.DOM_VK_Escape}); + TIP.keydown(keyInvalidKey, TIP.KEY_NON_PRINTABLE_KEY); + ok(false, + description + "TIP.keyup(keyInvalidKey, TIP.KEY_NON_PRINTABLE_KEY) should cause throwing an exception because its key value is not registered"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keyup(keyInvalidKey, TIP.KEY_NON_PRINTABLE_KEY) should cause throwing an exception including NS_ERROR_ILLEGAL_VALUE"); + } finally { + is(input.value, "", + description + "The input element should not be modified"); + } + + // KEY_KEEP_KEY_LOCATION_STANDARD flag should be used only when .location is not initialized with non-zero value. + try { + var keyEvent = new KeyboardEvent("", { code: "Enter", location: KeyboardEvent.DOM_KEY_LOCATION_LEFT }); + TIP.keydown(keyEvent, TIP.KEY_KEEP_KEY_LOCATION_STANDARD); + ok(false, + description + "keydown(KEY_KEEP_KEY_LOCATION_STANDARD) should fail if the .location of the key event is initialized with non-zero value"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keydown(KEY_KEEP_KEY_LOCATION_STANDARD) should cause NS_ERROR_ILLEGAL_VALUE if the .location of the key event is initialized with nonzero value"); + } + try { + var keyEvent = new KeyboardEvent("", { code: "Enter", location: KeyboardEvent.DOM_KEY_LOCATION_LEFT }); + TIP.keyup(keyEvent, TIP.KEY_KEEP_KEY_LOCATION_STANDARD); + ok(false, + description + "keyup(KEY_KEEP_KEY_LOCATION_STANDARD) should fail if the .location of the key event is initialized with non-zero value"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keyup(KEY_KEEP_KEY_LOCATION_STANDARD) should cause NS_ERROR_ILLEGAL_VALUE if the .location of the key event is initialized with nonzero value"); + } + + // KEY_KEEP_KEYCODE_ZERO flag should be used only when .keyCode is not initialized with non-zero value. + try { + var keyEvent = new KeyboardEvent("", { key: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + TIP.keydown(keyEvent, TIP.KEY_KEEP_KEYCODE_ZERO); + ok(false, + description + "keydown(KEY_KEEP_KEYCODE_ZERO) should fail if the .keyCode of the key event is initialized with non-zero value"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keydown(KEY_KEEP_KEYCODE_ZERO) should cause NS_ERROR_ILLEGAL_VALUE if the .keyCode of the key event is initialized with nonzero value"); + } + try { + var keyEvent = new KeyboardEvent("", { key: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }); + TIP.keyup(keyEvent, TIP.KEY_KEEP_KEYCODE_ZERO); + ok(false, + description + "keyup(KEY_KEEP_KEYCODE_ZERO) should fail if the .keyCode of the key event is initialized with non-zero value"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keyup(KEY_KEEP_KEYCODE_ZERO) should cause NS_ERROR_ILLEGAL_VALUE if the .keyCode of the key event is initialized with nonzero value"); + } + + // Specifying KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT with non-modifier key, it should cause an exception. + try { + var keyEvent = new KeyboardEvent("", { key: "a", code: "ShiftLeft" }); + TIP.keyup(keyEvent, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + ok(false, + description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should fail if the .key value isn't a modifier key"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should cause NS_ERROR_ILLEGAL_VALUE if the .key value isn't a modifier key"); + } + try { + var keyEvent = new KeyboardEvent("", { key: "Enter", code: "ShiftLeft" }); + TIP.keyup(keyEvent, TIP.KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT); + ok(false, + description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should fail if the .key value isn't a modifier key"); + } catch (e) { + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + description + "keydown(KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT) should cause NS_ERROR_ILLEGAL_VALUE if the .key value isn't a modifier key"); + } + + // The type of key events specified to composition methods should be "" or "keydown". + var kKeyEventTypes = [ + { type: "keydown", valid: true }, + { type: "keypress", valid: false }, + { type: "keyup", valid: false }, + { type: "", valid: true }, + { type: "mousedown", valid: false }, + { type: "foo", valid: false }, + ]; + for (var i = 0; i < kKeyEventTypes[i].length; i++) { + var keyEvent = + new KeyboardEvent(kKeyEventTypes[i].type, { key: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }); + var testDescription = description + "type=\"" + kKeyEventTypes[i].type + "\", "; + try { + TIP.startComposition(keyEvent); + ok(kKeyEventTypes[i].valid, + testDescription + "TIP.startComposition(keyEvent) should not accept the event type"); + TIP.cancelComposition(); + } catch (e) { + ok(!kKeyEventTypes[i].valid, + testDescription + "TIP.startComposition(keyEvent) should not throw an exception for the event type"); + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + testDescription + "TIP.startComposition(keyEvent) should cause NS_ERROR_ILLEGAL_VALUE if the key event type isn't valid"); + } + try { + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(keyEvent); + ok(kKeyEventTypes[i].valid, + testDescription + "TIP.flushPendingComposition(keyEvent) should not accept the event type"); + TIP.cancelComposition(); + } catch (e) { + ok(!kKeyEventTypes[i].valid, + testDescription + "TIP.flushPendingComposition(keyEvent) should not throw an exception for the event type"); + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + testDescription + "TIP.flushPendingComposition(keyEvent) should cause NS_ERROR_ILLEGAL_VALUE if the key event type isn't valid"); + } + try { + TIP.startComposition(); + TIP.commitComposition(keyEvent); + ok(kKeyEventTypes[i].valid, + testDescription + "TIP.commitComposition(keyEvent) should not accept the event type"); + } catch (e) { + ok(!kKeyEventTypes[i].valid, + testDescription + "TIP.commitComposition(keyEvent) should not throw an exception for the event type"); + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + testDescription + "TIP.commitComposition(keyEvent) should cause NS_ERROR_ILLEGAL_VALUE if the key event type isn't valid"); + TIP.cancelComposition(); + } + try { + TIP.commitCompositionWith("foo", keyEvent); + ok(kKeyEventTypes[i].valid, + testDescription + "TIP.commitCompositionWith(\"foo\", keyEvent) should not accept the event type"); + } catch (e) { + ok(!kKeyEventTypes[i].valid, + testDescription + "TIP.commitCompositionWith(\"foo\", keyEvent) should not throw an exception for the event type"); + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + testDescription + "TIP.commitCompositionWith(\"foo\", keyEvent) should cause NS_ERROR_ILLEGAL_VALUE if the key event type isn't valid"); + } + try { + TIP.startComposition(); + TIP.cancelComposition(keyEvent); + ok(kKeyEventTypes[i].valid, + testDescription + "TIP.cancelComposition(keyEvent) should not accept the event type"); + } catch (e) { + ok(!kKeyEventTypes[i].valid, + testDescription + "TIP.cancelComposition(keyEvent) should not throw an exception for the event type"); + ok(e.message.includes("NS_ERROR_ILLEGAL_VALUE"), + testDescription + "TIP.cancelComposition(keyEvent) should cause NS_ERROR_ILLEGAL_VALUE if the key event type isn't valid"); + TIP.cancelComposition(); + } + input.value = ""; + } +} + +function runCommitCompositionTests() +{ + var description = "runCommitCompositionTests(): "; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(window), + description + "TIP.beginInputTransactionForTests() should succeed"); + + input.focus(); + + // commitComposition() should commit the composition with the last data. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + TIP.commitComposition(); + is(input.value, "foo", + description + "commitComposition() should commit the composition with the last data"); + + // commitCompositionWith("") should commit the composition with empty string. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + TIP.commitCompositionWith(""); + is(input.value, "", + description + "commitCompositionWith(\"\") should commit the composition with empty string"); + + function doCommit(aText) + { + TIP.commitCompositionWith(aText); + } + + // doCommit() should commit the composition with the last data. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommit(); + todo_is(input.value, "foo", + description + "doCommit() should commit the composition with the last data"); + + // doCommit("") should commit the composition with empty string. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommit(""); + is(input.value, "", + description + "doCommit(\"\") should commit the composition with empty string"); + + // doCommit(null) should commit the composition with empty string. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommit(null); + is(input.value, "", + description + "doCommit(null) should commit the composition with empty string"); + + // doCommit(undefined) should commit the composition with the last data. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommit(undefined); + todo_is(input.value, "foo", + description + "doCommit(undefined) should commit the composition with the last data"); + + function doCommitWithNullCheck(aText) + { + TIP.commitCompositionWith(aText ? aText : ""); + } + + // doCommitWithNullCheck() should commit the composition with the last data. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommitWithNullCheck(); + is(input.value, "", + description + "doCommitWithNullCheck() should commit the composition with empty string"); + + // doCommitWithNullCheck("") should commit the composition with empty string. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommitWithNullCheck(""); + is(input.value, "", + description + "doCommitWithNullCheck(\"\") should commit the composition with empty string"); + + // doCommitWithNullCheck(null) should commit the composition with empty string. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommitWithNullCheck(null); + is(input.value, "", + description + "doCommitWithNullCheck(null) should commit the composition with empty string"); + + // doCommitWithNullCheck(undefined) should commit the composition with the last data. + input.value = ""; + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + doCommitWithNullCheck(undefined); + is(input.value, "", + description + "doCommitWithNullCheck(undefined) should commit the composition with empty string"); +} + +function runUnloadTests1(aNextTest) +{ + var description = "runUnloadTests1(): "; + + var TIP1 = createTIP(); + ok(TIP1.beginInputTransactionForTests(childWindow), + description + "TIP1.beginInputTransactionForTests() should succeed"); + + var oldSrc = iframe.src; + var parentWindow = window; + + iframe.addEventListener("load", function (aEvent) { + ok(true, description + "dummy page is loaded"); + iframe.removeEventListener("load", arguments.callee, true); + childWindow = iframe.contentWindow; + textareaInFrame = null; + iframe.addEventListener("load", function () { + ok(true, description + "old iframe is restored"); + // And also restore the iframe information with restored contents. + iframe.removeEventListener("load", arguments.callee, true); + childWindow = iframe.contentWindow; + textareaInFrame = iframe.contentDocument.getElementById("textarea"); + setTimeout(aNextTest, 0); + }, true); + + // The composition should be committed internally. So, another TIP should + // be able to steal the rights to using TextEventDispatcher. + var TIP2 = createTIP(); + ok(TIP2.beginInputTransactionForTests(parentWindow), + description + "TIP2.beginInputTransactionForTests() should succeed"); + + input.focus(); + input.value = ""; + + TIP2.setPendingCompositionString("foo"); + TIP2.appendClauseToPendingComposition(3, TIP2.ATTR_RAW_CLAUSE); + TIP2.setCaretInPendingComposition(3); + TIP2.flushPendingComposition(); + is(input.value, "foo", + description + "the input in the parent document should have composition string"); + + TIP2.cancelComposition(); + + // Restore the old iframe content. + iframe.src = oldSrc; + }, true); + + // Start composition in the iframe. + textareaInFrame.value = ""; + textareaInFrame.focus(); + + TIP1.setPendingCompositionString("foo"); + TIP1.appendClauseToPendingComposition(3, TIP1.ATTR_RAW_CLAUSE); + TIP1.setCaretInPendingComposition(3); + TIP1.flushPendingComposition(); + is(textareaInFrame.value, "foo", + description + "the textarea in the iframe should have composition string"); + + // Load different web page on the frame. + iframe.src = "data:text/html,<body>dummy page</body>"; +} + +function runUnloadTests2(aNextTest) +{ + var description = "runUnloadTests2(): "; + + var TIP = createTIP(); + ok(TIP.beginInputTransactionForTests(childWindow), + description + "TIP.beginInputTransactionForTests() should succeed"); + + var oldSrc = iframe.src; + var parentWindow = window; + + iframe.addEventListener("load", function (aEvent) { + ok(true, description + "dummy page is loaded"); + iframe.removeEventListener("load", arguments.callee, true); + childWindow = iframe.contentWindow; + textareaInFrame = null; + iframe.addEventListener("load", function () { + ok(true, description + "old iframe is restored"); + // And also restore the iframe information with restored contents. + iframe.removeEventListener("load", arguments.callee, true); + childWindow = iframe.contentWindow; + textareaInFrame = iframe.contentDocument.getElementById("textarea"); + setTimeout(aNextTest, 0); + }, true); + + input.focus(); + input.value = ""; + + // TIP should be still available in the same top level widget. + TIP.setPendingCompositionString("bar"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + if (input.value == "") { + // XXX TextInputProcessor or TextEventDispatcher may have a bug. + todo_is(input.value, "bar", + description + "the input in the parent document should have composition string"); + } else { + is(input.value, "bar", + description + "the input in the parent document should have composition string"); + } + + TIP.cancelComposition(); + + // Restore the old iframe content. + iframe.src = oldSrc; + }, true); + + // Start composition in the iframe. + textareaInFrame.value = ""; + textareaInFrame.focus(); + + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.setCaretInPendingComposition(3); + TIP.flushPendingComposition(); + is(textareaInFrame.value, "foo", + description + "the textarea in the iframe should have composition string"); + + // Load different web page on the frame. + iframe.src = "data:text/html,<body>dummy page</body>"; +} + +function runCallbackTests(aForTests) +{ + var description = "runCallbackTests(aForTests=" + aForTests + "): "; + + input.value = ""; + input.focus(); + input.blur(); + + var TIP = createTIP(); + var notifications = []; + function callback(aTIP, aNotification) + { + switch (aNotification.type) { + case "request-to-commit": + aTIP.commitComposition(); + break; + case "request-to-cancel": + aTIP.cancelComposition(); + break; + } + if (aTIP == TIP) { + notifications.push(aNotification); + } + return true; + } + + function dumpUnexpectedNotifications(aExpectedCount) + { + if (notifications.length <= aExpectedCount) { + return; + } + for (var i = aExpectedCount; i < notifications.length; i++) { + ok(false, + description + "Unexpected notification: " + notifications[i].type); + } + } + + if (aForTests) { + TIP.beginInputTransactionForTests(window, callback); + } else { + TIP.beginInputTransaction(window, callback); + } + + notifications = []; + input.focus(); + is(notifications.length, 1, + description + "input.focus() should cause a notification"); + is(notifications[0].type, "notify-focus", + description + "input.focus() should cause \"notify-focus\""); + dumpUnexpectedNotifications(1); + + notifications = []; + input.blur(); + is(notifications.length, 1, + description + "input.blur() should cause a notification"); + is(notifications[0].type, "notify-blur", + description + "input.blur() should cause \"notify-focus\""); + dumpUnexpectedNotifications(1); + + input.focus(); + TIP.setPendingCompositionString("foo"); + TIP.appendClauseToPendingComposition(3, TIP.ATTR_RAW_CLAUSE); + TIP.flushPendingComposition(); + notifications = []; + synthesizeMouseAtCenter(input, {}); + is(notifications.length, 1, + description + "synthesizeMouseAtCenter(input, {}) during composition should cause a notification"); + is(notifications[0].type, "request-to-commit", + description + "synthesizeMouseAtCenter(input, {}) during composition should cause \"request-to-commit\""); + dumpUnexpectedNotifications(1); + + notifications = []; + var TIP2 = createTIP(); + if (aForTests) { + TIP2.beginInputTransactionForTests(window, callback); + } else { + TIP2.beginInputTransaction(window, callback); + } + is(notifications.length, 1, + description + "Initializing another TIP should cause a notification"); + is(notifications[0].type, "notify-end-input-transaction", + description + "Initializing another TIP should cause \"notify-detached\""); + dumpUnexpectedNotifications(1); +} + +function runTests() +{ + textareaInFrame = iframe.contentDocument.getElementById("textarea"); + + runBeginInputTransactionMethodTests(); + runReleaseTests(); + runCompositionTests(); + runCompositionWithKeyEventTests(); + runConsumingKeydownBeforeCompositionTests(); + runKeyTests(); + runErrorTests(); + runCommitCompositionTests(); + runCallbackTests(false); + runCallbackTests(true); + runUnloadTests1(function () { + runUnloadTests2(function () { + finish(); + }); + }); +} + +]]> +</script> + +</window> diff --git a/dom/base/test/chrome/window_swapFrameLoaders.xul b/dom/base/test/chrome/window_swapFrameLoaders.xul new file mode 100644 index 0000000000..3deae2e63c --- /dev/null +++ b/dom/base/test/chrome/window_swapFrameLoaders.xul @@ -0,0 +1,258 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1242644 +Test swapFrameLoaders with different frame types and remoteness +--> +<window title="Mozilla Bug 1242644" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script> + + <script type="application/javascript"><![CDATA[ + ["SimpleTest", "SpecialPowers", "info", "is", "ok"].forEach(key => { + window[key] = window.opener[key]; + }) + const { interfaces: Ci } = Components; + + const NS = { + xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", + html: "http://www.w3.org/1999/xhtml", + } + + const TAG = { + xul: "browser", + html: "iframe", // mozbrowser + } + + const SCENARIOS = [ + ["xul", "xul"], + ["xul", "html"], + ["html", "xul"], + ["html", "html"], + ["xul", "xul", "remote"], + ["xul", "html", "remote"], + ["html", "xul", "remote"], + ["html", "html", "remote"], + ]; + + const HEIGHTS = [ + 200, + 400 + ]; + + function frameScript() { + addEventListener("load", function onLoad() { + sendAsyncMessage("test:load"); + }, true); + } + + // Watch for loads in new frames + window.messageManager.loadFrameScript(`data:,(${frameScript})();`, true); + + function once(target, eventName, useCapture = false) { + info("Waiting for event: '" + eventName + "' on " + target + "."); + + return new Promise(resolve => { + for (let [add, remove] of [ + ["addEventListener", "removeEventListener"], + ["addMessageListener", "removeMessageListener"], + ]) { + if ((add in target) && (remove in target)) { + target[add](eventName, function onEvent(...aArgs) { + info("Got event: '" + eventName + "' on " + target + "."); + target[remove](eventName, onEvent, useCapture); + resolve(aArgs); + }, useCapture); + break; + } + } + }); + } + + function* addFrame(type, remote, height) { + let frame = document.createElementNS(NS[type], TAG[type]); + frame.setAttribute("remote", remote); + if (remote && type == "xul") { + frame.setAttribute("style", "-moz-binding: none;"); + } + if (type == "html") { + frame.setAttribute("mozbrowser", "true"); + frame.setAttribute("noisolation", "true"); + frame.setAttribute("allowfullscreen", "true"); + } else if (type == "xul") { + frame.setAttribute("type", "content"); + } + let src = `data:text/html,<!doctype html>` + + `<body style="height:${height}px"/>`; + frame.setAttribute("src", src); + document.documentElement.appendChild(frame); + let mm = frame.frameLoader.messageManager; + yield once(mm, "test:load"); + return frame; + } + + add_task(function*() { + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv( + { "set": [["dom.mozBrowserFramesEnabled", true], + ["network.disable.ipc.security", true]] }, + resolve); + }); + }); + + add_task(function*() { + for (let scenario of SCENARIOS) { + let [ typeA, typeB, remote ] = scenario; + remote = !!remote; + let heightA = HEIGHTS[0]; + info(`Adding frame A, type ${typeA}, remote ${remote}, height ${heightA}`); + let frameA = yield addFrame(typeA, remote, heightA); + + let heightB = HEIGHTS[1]; + info(`Adding frame B, type ${typeB}, remote ${remote}, height ${heightB}`); + let frameB = yield addFrame(typeB, remote, heightB); + + let frameScriptFactory = function(name) { + return `function() { + addMessageListener("ping", function() { + sendAsyncMessage("pong", "${name}"); + }); + addMessageListener("check-browser-api", function() { + let exists = "api" in this; + sendAsyncMessage("check-browser-api", { + exists, + running: exists && !this.api._shuttingDown, + }); + }); + }`; + } + + // Load frame script into each frame + { + let mmA = frameA.frameLoader.messageManager; + let mmB = frameB.frameLoader.messageManager; + + mmA.loadFrameScript("data:,(" + frameScriptFactory("A") + ")()", false); + mmB.loadFrameScript("data:,(" + frameScriptFactory("B") + ")()", false); + } + + // Ping before swap + { + let mmA = frameA.frameLoader.messageManager; + let mmB = frameB.frameLoader.messageManager; + + let inflightA = once(mmA, "pong"); + let inflightB = once(mmB, "pong"); + + info("Ping message manager for frame A"); + mmA.sendAsyncMessage("ping"); + let [ { data: pongA } ] = yield inflightA; + is(pongA, "A", "Frame A message manager gets reply A before swap"); + + info("Ping message manager for frame B"); + mmB.sendAsyncMessage("ping"); + let [ { data: pongB } ] = yield inflightB; + is(pongB, "B", "Frame B message manager gets reply B before swap"); + } + + // Check height before swap + { + if (frameA.getContentDimensions) { + let { height } = yield frameA.getContentDimensions(); + is(height, heightA, "Frame A's content height is 200px before swap"); + } + if (frameB.getContentDimensions) { + let { height } = yield frameB.getContentDimensions(); + is(height, heightB, "Frame B's content height is 400px before swap"); + } + } + + // Ping after swap using message managers acquired before + { + let mmA = frameA.frameLoader.messageManager; + let mmB = frameB.frameLoader.messageManager; + + info("swapFrameLoaders"); + frameA.swapFrameLoaders(frameB); + + let inflightA = once(mmA, "pong"); + let inflightB = once(mmB, "pong"); + + info("Ping message manager for frame A"); + mmA.sendAsyncMessage("ping"); + let [ { data: pongA } ] = yield inflightA; + is(pongA, "B", "Frame A message manager acquired before swap gets reply B after swap"); + + info("Ping message manager for frame B"); + mmB.sendAsyncMessage("ping"); + let [ { data: pongB } ] = yield inflightB; + is(pongB, "A", "Frame B message manager acquired before swap gets reply A after swap"); + } + + // Check height after swap + { + if (frameA.getContentDimensions) { + let { height } = yield frameA.getContentDimensions(); + is(height, heightB, "Frame A's content height is 400px after swap"); + } + if (frameB.getContentDimensions) { + let { height } = yield frameB.getContentDimensions(); + is(height, heightA, "Frame B's content height is 200px after swap"); + } + } + + // Ping after swap using message managers acquired after + { + let mmA = frameA.frameLoader.messageManager; + let mmB = frameB.frameLoader.messageManager; + + let inflightA = once(mmA, "pong"); + let inflightB = once(mmB, "pong"); + + info("Ping message manager for frame A"); + mmA.sendAsyncMessage("ping"); + let [ { data: pongA } ] = yield inflightA; + is(pongA, "B", "Frame A message manager acquired after swap gets reply B after swap"); + + info("Ping message manager for frame B"); + mmB.sendAsyncMessage("ping"); + let [ { data: pongB } ] = yield inflightB; + is(pongB, "A", "Frame B message manager acquired after swap gets reply A after swap"); + } + + // Verify browser API frame scripts destroyed if swapped out of browser frame + if (frameA.hasAttribute("mozbrowser") != frameB.hasAttribute("mozbrowser")) { + let mmA = frameA.frameLoader.messageManager; + let mmB = frameB.frameLoader.messageManager; + + let inflightA = once(mmA, "check-browser-api"); + let inflightB = once(mmB, "check-browser-api"); + + info("Check browser API for frame A"); + mmA.sendAsyncMessage("check-browser-api"); + let [ { data: apiA } ] = yield inflightA; + if (frameA.hasAttribute("mozbrowser")) { + ok(apiA.exists && apiA.running, "Frame A browser API exists and is running"); + } else { + ok(apiA.exists && !apiA.running, "Frame A browser API did exist but is now destroyed"); + } + + info("Check browser API for frame B"); + mmB.sendAsyncMessage("check-browser-api"); + let [ { data: apiB } ] = yield inflightB; + if (frameB.hasAttribute("mozbrowser")) { + ok(apiB.exists && apiB.running, "Frame B browser API exists and is running"); + } else { + ok(apiB.exists && !apiB.running, "Frame B browser API did exist but is now destroyed"); + } + } else { + info("Frames have matching mozbrowser state, skipping browser API destruction check"); + } + + frameA.remove(); + frameB.remove(); + } + }); + ]]></script> +</window> diff --git a/dom/base/test/copypaste.js b/dom/base/test/copypaste.js new file mode 100644 index 0000000000..6fa3cb909e --- /dev/null +++ b/dom/base/test/copypaste.js @@ -0,0 +1,412 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +function modifySelection(s) { + var g = window.getSelection(); + var l = g.getRangeAt(0); + var d = document.createElement("p"); + d.innerHTML = s; + d.appendChild(l.cloneContents()); + + var e = document.createElement("div"); + document.body.appendChild(e); + e.appendChild(d); + var a = document.createRange(); + a.selectNode(d); + g.removeAllRanges(); + g.addRange(a); + window.setTimeout(function () { + e.parentNode.removeChild(e); + g.removeAllRanges(); + g.addRange(l); + }, 0) +} + +function getLoadContext() { + var Ci = SpecialPowers.Ci; + return SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsILoadContext); +} + +function testCopyPaste (isXHTML) { + var suppressUnicodeCheckIfHidden = !!isXHTML; + var suppressHTMLCheck = !!isXHTML; + + var webnav = SpecialPowers.wrap(window).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) + + var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell); + + var documentViewer = docShell.contentViewer + .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit); + + var clipboard = SpecialPowers.Services.clipboard; + + var textarea = SpecialPowers.wrap(document.getElementById('input')); + + function copySelectionToClipboard(suppressUnicodeCheck) { + documentViewer.copySelection(); + if (!suppressUnicodeCheck) + ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), "check text/unicode"); + if (!suppressHTMLCheck) + ok(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), "check text/html"); + } + function clear(node, suppressUnicodeCheck) { + textarea.blur(); + clipboard.emptyClipboard(1); + var sel = window.getSelection(); + sel.removeAllRanges(); + } + function copyToClipboard(node, suppressUnicodeCheck) { + clear(); + var r = document.createRange(); + r.selectNode(node); + window.getSelection().addRange(r); + copySelectionToClipboard(suppressUnicodeCheck); + } + function addRange(startNode,startIndex,endNode,endIndex) { + var sel = window.getSelection(); + var r = document.createRange(); + r.setStart(startNode,startIndex) + r.setEnd(endNode,endIndex) + sel.addRange(r); + } + function copyRangeToClipboard(startNode,startIndex,endNode,endIndex,suppressUnicodeCheck) { + clear(); + addRange(startNode,startIndex,endNode,endIndex); + copySelectionToClipboard(suppressUnicodeCheck); + } + function copyChildrenToClipboard(id) { + clear(); + window.getSelection().selectAllChildren(document.getElementById(id)); + copySelectionToClipboard(); + } + function getClipboardData(mime) { + var transferable = SpecialPowers.Cc['@mozilla.org/widget/transferable;1'] + .createInstance(SpecialPowers.Ci.nsITransferable); + transferable.init(getLoadContext()); + transferable.addDataFlavor(mime); + clipboard.getData(transferable, 1); + var data = SpecialPowers.createBlankObject(); + transferable.getTransferData(mime, data, {}) ; + return data; + } + function testHtmlClipboardValue(mime, expected) { + // For Windows, navigator.platform returns "Win32". + var expectedValue = expected; + if (navigator.platform.indexOf("Win") >= 0) { + // Windows has extra content. + var expectedValue = "<html><body>\n<!--StartFragment-->" + + expected.replace(/\n/g, '\n') + + "<!--EndFragment-->\n</body>\n</html>"; + } + testClipboardValue(mime, expectedValue); + } + function testClipboardValue(mime, expected) { + if (suppressHTMLCheck && mime == "text/html") + return null; + var data = SpecialPowers.wrap(getClipboardData(mime)); + is (data.value == null ? data.value : + data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data, + expected, + mime + " value in the clipboard"); + return data.value; + } + function testPasteText(expected) { + textarea.value=""; + textarea.focus(); + textarea.editor.paste(1); + is(textarea.value, expected, "value of the textarea after the paste"); + } + function testPasteHTML(id, expected) { + var contentEditable = $(id); + contentEditable.focus(); + synthesizeKey("v", {accelKey: true}); + is(contentEditable.innerHTML, expected, id+".innerHtml after the paste"); + } + function testSelectionToString(expected) { + is(window.getSelection().toString().replace(/\r\n/g,"\n"), expected, "Selection.toString"); + } + function testInnerHTML(id, expected) { + var value = document.getElementById(id).innerHTML; + is(value, expected, id + ".innerHTML"); + } + function testEmptyChildren(id) { + copyChildrenToClipboard(id); + testSelectionToString(""); + testClipboardValue("text/unicode", null); + testClipboardValue("text/html", null); + testPasteText(""); + } + + copyChildrenToClipboard("draggable"); + testSelectionToString("This is a draggable bit of text."); + testClipboardValue("text/unicode", + "This is a draggable bit of text."); + testHtmlClipboardValue("text/html", + "<div id=\"draggable\" title=\"title to have a long HTML line\">This is a <em>draggable</em> bit of text.</div>"); + testPasteText("This is a draggable bit of text."); + + copyChildrenToClipboard("alist"); + testSelectionToString(" bla\n\n foo\n bar\n\n"); + testClipboardValue("text/unicode", " bla\n\n foo\n bar\n\n"); + testHtmlClipboardValue("text/html", "<div id=\"alist\">\n bla\n <ul>\n <li>foo</li>\n \n <li>bar</li>\n </ul>\n </div>"); + testPasteText(" bla\n\n foo\n bar\n\n"); + + copyChildrenToClipboard("blist"); + testSelectionToString(" mozilla\n\n foo\n bar\n\n"); + testClipboardValue("text/unicode", " mozilla\n\n foo\n bar\n\n"); + testHtmlClipboardValue("text/html", "<div id=\"blist\">\n mozilla\n <ol>\n <li>foo</li>\n \n <li>bar</li>\n </ol>\n </div>"); + testPasteText(" mozilla\n\n foo\n bar\n\n"); + + copyChildrenToClipboard("clist"); + testSelectionToString(" mzla\n\n foo\n bazzinga!\n bar\n\n"); + testClipboardValue("text/unicode", " mzla\n\n foo\n bazzinga!\n bar\n\n"); + testHtmlClipboardValue("text/html", "<div id=\"clist\">\n mzla\n <ul>\n <li>foo<ul>\n <li>bazzinga!</li>\n </ul></li>\n \n <li>bar</li>\n </ul>\n </div>"); + testPasteText(" mzla\n\n foo\n bazzinga!\n bar\n\n"); + + copyChildrenToClipboard("div4"); + testSelectionToString(" Tt t t "); + testClipboardValue("text/unicode", " Tt t t "); + if (isXHTML) { + testHtmlClipboardValue("text/html", "<div id=\"div4\">\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\">t t t</textarea>\n</div>"); + testInnerHTML("div4", "\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\">t t t</textarea>\n"); + } + else { + testHtmlClipboardValue("text/html", "<div id=\"div4\">\n T<textarea>t t t</textarea>\n</div>"); + testInnerHTML("div4", "\n T<textarea>t t t</textarea>\n"); + } + testPasteText(" Tt t t "); + + copyChildrenToClipboard("div5"); + testSelectionToString(" T "); + testClipboardValue("text/unicode", " T "); + if (isXHTML) { + testHtmlClipboardValue("text/html", "<div id=\"div5\">\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\"> </textarea>\n</div>"); + testInnerHTML("div5", "\n T<textarea xmlns=\"http://www.w3.org/1999/xhtml\"> </textarea>\n"); + } + else { + testHtmlClipboardValue("text/html", "<div id=\"div5\">\n T<textarea> </textarea>\n</div>"); + testInnerHTML("div5", "\n T<textarea> </textarea>\n"); + } + testPasteText(" T "); + + copyRangeToClipboard($("div6").childNodes[0],0, $("div6").childNodes[1],1,suppressUnicodeCheckIfHidden); + testSelectionToString(""); +// START Disabled due to bug 564688 +if (false) { + testClipboardValue("text/unicode", ""); + testClipboardValue("text/html", ""); +} +// END Disabled due to bug 564688 + testInnerHTML("div6", "div6"); + + copyRangeToClipboard($("div7").childNodes[0],0, $("div7").childNodes[0],4,suppressUnicodeCheckIfHidden); + testSelectionToString(""); +// START Disabled due to bug 564688 +if (false) { + testClipboardValue("text/unicode", ""); + testClipboardValue("text/html", ""); +} +// END Disabled due to bug 564688 + testInnerHTML("div7", "div7"); + + copyRangeToClipboard($("div8").childNodes[0],0, $("div8").childNodes[0],4,suppressUnicodeCheckIfHidden); + testSelectionToString(""); +// START Disabled due to bug 564688 +if (false) { + testClipboardValue("text/unicode", ""); + testClipboardValue("text/html", ""); +} +// END Disabled due to bug 564688 + testInnerHTML("div8", "div8"); + + copyRangeToClipboard($("div9").childNodes[0],0, $("div9").childNodes[0],4,suppressUnicodeCheckIfHidden); + testSelectionToString("div9"); + testClipboardValue("text/unicode", "div9"); + testHtmlClipboardValue("text/html", "div9"); + testInnerHTML("div9", "div9"); + + copyToClipboard($("div10"), suppressUnicodeCheckIfHidden); + testSelectionToString(""); + testInnerHTML("div10", "div10"); + + copyToClipboard($("div10").firstChild, suppressUnicodeCheckIfHidden); + testSelectionToString(""); + + copyRangeToClipboard($("div10").childNodes[0],0, $("div10").childNodes[0],1,suppressUnicodeCheckIfHidden); + testSelectionToString(""); + + copyRangeToClipboard($("div10").childNodes[1],0, $("div10").childNodes[1],1,suppressUnicodeCheckIfHidden); + testSelectionToString(""); + + if (!isXHTML) { + // ============ copy/paste multi-range selection (bug 1123505) + // with text start node + var sel = window.getSelection(); + sel.removeAllRanges(); + var r = document.createRange(); + var ul = $('ul1'); + var parent = ul.parentNode; + r.setStart(parent, 0); + r.setEnd(parent.firstChild, 15); // the end of "Copy..." + sel.addRange(r); + + r = document.createRange(); + r.setStart(ul, 1); // before the space inside the UL + r.setEnd(parent, 2); // after the UL + sel.addRange(r); + copySelectionToClipboard(true); + testPasteHTML('contentEditable1', 'Copy1then Paste'); + + // with text end node + var sel = window.getSelection(); + sel.removeAllRanges(); + var r = document.createRange(); + var ul = $('ul2'); + var parent = ul.parentNode; + r.setStart(parent, 0); + r.setEnd(ul, 1); // after the space + sel.addRange(r); + + r = document.createRange(); + r.setStart(parent.childNodes[1], 0); // the start of "Copy..." + r.setEnd(parent, 2); + sel.addRange(r); + copySelectionToClipboard(true); + testPasteHTML('contentEditable2', 'Copy2then Paste'); + + // with text end node and non-empty start + var sel = window.getSelection(); + sel.removeAllRanges(); + var r = document.createRange(); + var ul = $('ul3'); + var parent = ul.parentNode; + r.setStart(parent, 0); + r.setEnd(ul, 1); // after the space + sel.addRange(r); + + r = document.createRange(); + r.setStart(parent.childNodes[1], 0); // the start of "Copy..." + r.setEnd(parent, 2); + sel.addRange(r); + copySelectionToClipboard(true); + testPasteHTML('contentEditable3', '<ul id="ul3"><li>\n<br></li></ul>Copy3then Paste'); + + // with elements of different depth + var sel = window.getSelection(); + sel.removeAllRanges(); + var r = document.createRange(); + var div1 = $('div1s'); + var parent = div1.parentNode; + r.setStart(parent, 0); + r.setEnd(document.getElementById('div1se1'), 1); // after the "inner" DIV + sel.addRange(r); + + r = document.createRange(); + r.setStart(div1.childNodes[1], 0); // the start of "after" + r.setEnd(parent, 1); + sel.addRange(r); + copySelectionToClipboard(true); + testPasteHTML('contentEditable4', '<div id="div1s"><div id="div1se1">before</div></div><div id="div1s">after</div>'); + + // with elements of different depth, and a text node at the end + var sel = window.getSelection(); + sel.removeAllRanges(); + var r = document.createRange(); + var div1 = $('div2s'); + var parent = div1.parentNode; + r.setStart(parent, 0); + r.setEnd(document.getElementById('div2se1'), 1); // after the "inner" DIV + sel.addRange(r); + + r = document.createRange(); + r.setStart(div1.childNodes[1], 0); // the start of "after" + r.setEnd(parent, 1); + sel.addRange(r); + copySelectionToClipboard(true); + testPasteHTML('contentEditable5', '<div id="div2s"><div id="div2se1">before</div></div><div id="div2s">after</div>'); + + // crash test for bug 1127835 + var e1 = document.getElementById('1127835crash1'); + var e2 = document.getElementById('1127835crash2'); + var e3 = document.getElementById('1127835crash3'); + var t1 = e1.childNodes[0]; + var t3 = e3.childNodes[0]; + + var sel = window.getSelection(); + sel.removeAllRanges(); + + var r = document.createRange(); + r.setStart(t1, 1); + r.setEnd(e2, 0); + sel.addRange(r); + + r = document.createRange(); + r.setStart(e2, 1); + r.setEnd(t3, 0); + sel.addRange(r); + copySelectionToClipboard(true); + testPasteHTML('contentEditable6', '<span id="1127835crash1"></span><div id="1127835crash2"><div>\n</div></div><br>'); + } + + // ============ copy/paste test from/to a textarea + + var val = "1\n 2\n 3"; + textarea.value=val; + textarea.select(); + textarea.editor.copy(); + + textarea.value=""; + textarea.editor.paste(1); + is(textarea.value, val); + textarea.value=""; + + // ============ NOSCRIPT should not be copied + + copyChildrenToClipboard("div13"); + testSelectionToString("__"); + testClipboardValue("text/unicode", "__"); + testHtmlClipboardValue("text/html", "<div id=\"div13\">__</div>"); + testPasteText("__"); + + // ============ converting cell boundaries to tabs in tables + + copyToClipboard($("tr1")); + testClipboardValue("text/unicode", "foo\tbar"); + + if (!isXHTML) { + // ============ spanning multiple rows + + copyRangeToClipboard($("tr2"),0,$("tr3"),0); + testClipboardValue("text/unicode", "1\t2\n3\t4\n"); + testHtmlClipboardValue("text/html", '<table><tbody><tr id="tr2"><tr id="tr2"><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr><tr id="tr3"></tr></tr></tbody></table>'); + + // ============ spanning multiple rows in multi-range selection + + clear(); + addRange($("tr2"),0,$("tr2"),2); + addRange($("tr3"),0,$("tr3"),2); + copySelectionToClipboard(); + testClipboardValue("text/unicode", "1\t2\n5\t6"); + testHtmlClipboardValue("text/html", '<table><tbody><tr id="tr2"><td>1</td><td>2</td></tr><tr id="tr3"><td>5</td><td>6</td></tr></tbody></table>'); + } + + // ============ manipulating Selection in oncopy + + copyRangeToClipboard($("div11").childNodes[0],0, $("div11").childNodes[1],2); + testClipboardValue("text/unicode", "Xdiv11"); + testHtmlClipboardValue("text/html", "<div><p>X<span>div</span>11</p></div>"); + setTimeout(function(){testSelectionToString("div11")},0); + + setTimeout(function(){ + copyRangeToClipboard($("div12").childNodes[0],0, $("div12").childNodes[1],2); + testClipboardValue("text/unicode", "Xdiv12"); + testHtmlClipboardValue("text/html", "<div><p>X<span>div</span>12</p></div>"); + setTimeout(function(){ + testSelectionToString("div12"); + setTimeout(SimpleTest.finish,0); + },0); + },0); +} diff --git a/dom/base/test/create_file_objects.js b/dom/base/test/create_file_objects.js new file mode 100644 index 0000000000..273adc2cd6 --- /dev/null +++ b/dom/base/test/create_file_objects.js @@ -0,0 +1,10 @@ +Components.utils.importGlobalProperties(['File']); + +addMessageListener("create-file-objects", function(message) { + let files = [] + for (fileName of message.fileNames) { + files.push(File.createFromFileName(fileName)); + } + + sendAsyncMessage("created-file-objects", files); +}); diff --git a/dom/base/test/delayedServerEvents.sjs b/dom/base/test/delayedServerEvents.sjs new file mode 100644 index 0000000000..c2d2f5dd9c --- /dev/null +++ b/dom/base/test/delayedServerEvents.sjs @@ -0,0 +1,42 @@ +// this will take strings_to_send.length*500 ms = 5 sec + +var timer = null; +var strings_to_send = ["retry:999999999\ndata\r\n\nda", "ta", ":", "de", "layed1\n\n", + "", + "", + "data:delayed2\n\n", "", ""]; +var resp = null; + +function sendNextString() +{ + if (strings_to_send.length == 0) { + timer.cancel(); + resp.finish(); + timer = null; + resp = null; + return; + } + + resp.write(strings_to_send[0]); + strings_to_send = strings_to_send.splice(1, strings_to_send.length - 1); +} + +function handleRequest(request, response) +{ + var b = 0; + for (var i=0; i < strings_to_send.length; ++i) { + b += strings_to_send[i].length; + } + + response.seizePower(); + response.write("HTTP/1.1 200 OK\r\n") + response.write("Content-Length: " + b + "\r\n"); + response.write("Content-Type: text/event-stream; charset=utf-8\r\n"); + response.write("Cache-Control: no-cache, must-revalidate\r\n"); + response.write("\r\n"); + + resp = response; + + timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(sendNextString, 500, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK); +} diff --git a/dom/base/test/empty.html b/dom/base/test/empty.html new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/dom/base/test/empty.html diff --git a/dom/base/test/eventsource.resource b/dom/base/test/eventsource.resource new file mode 100644 index 0000000000..856e3b1aff --- /dev/null +++ b/dom/base/test/eventsource.resource @@ -0,0 +1,22 @@ +:this file must be enconded in utf8 +:and its Content-Type must be equal to text/event-stream + +retry:500 +data: 1 +unknow: unknow + +event: other_event_name +retry:500 +data: 1 +unknow: unknow + +event: click +retry:500 + +event: blur +retry:500 + +event:keypress +retry:500 + + diff --git a/dom/base/test/eventsource.resource^headers^ b/dom/base/test/eventsource.resource^headers^ new file mode 100644 index 0000000000..6a63b5341d --- /dev/null +++ b/dom/base/test/eventsource.resource^headers^ @@ -0,0 +1,3 @@ +Content-Type: text/event-stream +Cache-Control: no-cache, must-revalidate + diff --git a/dom/base/test/eventsource_redirect.resource b/dom/base/test/eventsource_redirect.resource new file mode 100644 index 0000000000..d073527bfb --- /dev/null +++ b/dom/base/test/eventsource_redirect.resource @@ -0,0 +1,2 @@ +redirected + diff --git a/dom/base/test/eventsource_redirect.resource^headers^ b/dom/base/test/eventsource_redirect.resource^headers^ new file mode 100644 index 0000000000..eb79e2f814 --- /dev/null +++ b/dom/base/test/eventsource_redirect.resource^headers^ @@ -0,0 +1,3 @@ +HTTP 301 Moved Permanently +Location: eventsource_redirect_to.resource + diff --git a/dom/base/test/eventsource_redirect_to.resource b/dom/base/test/eventsource_redirect_to.resource new file mode 100644 index 0000000000..1eb4081ac1 --- /dev/null +++ b/dom/base/test/eventsource_redirect_to.resource @@ -0,0 +1,4 @@ +retry:500 +data: 1 + + diff --git a/dom/base/test/eventsource_redirect_to.resource^headers^ b/dom/base/test/eventsource_redirect_to.resource^headers^ new file mode 100644 index 0000000000..6a63b5341d --- /dev/null +++ b/dom/base/test/eventsource_redirect_to.resource^headers^ @@ -0,0 +1,3 @@ +Content-Type: text/event-stream +Cache-Control: no-cache, must-revalidate + diff --git a/dom/base/test/fake_plugin.tst b/dom/base/test/fake_plugin.tst new file mode 100644 index 0000000000..b3d41aed8d --- /dev/null +++ b/dom/base/test/fake_plugin.tst @@ -0,0 +1 @@ +This is used in test_object.html to test loading by extension (.tst -> application/x-test). diff --git a/dom/base/test/file_audioLoop.html b/dom/base/test/file_audioLoop.html new file mode 100644 index 0000000000..d680c9a58f --- /dev/null +++ b/dom/base/test/file_audioLoop.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<audio src="audio.ogg" autoplay="true" loop> diff --git a/dom/base/test/file_base_xbl.xml b/dom/base/test/file_base_xbl.xml new file mode 100644 index 0000000000..bcd226f332 --- /dev/null +++ b/dom/base/test/file_base_xbl.xml @@ -0,0 +1,9 @@ +<bindings xmlns="http://www.mozilla.org/xbl" + xmlns:xhtml="http://www.w3.org/1999/xhtml" + xmlns:svg="http://www.w3.org/2000/svg"> +<binding id="test"> + <content> + <svg:g><svg:circle><xhtml:div xml:base="#shesellsseashellsbytheseashore"/></svg:circle><children/></svg:g> + </content> + </binding> +</bindings> diff --git a/dom/base/test/file_blobURL_expiring.html b/dom/base/test/file_blobURL_expiring.html new file mode 100644 index 0000000000..a1ae725709 --- /dev/null +++ b/dom/base/test/file_blobURL_expiring.html @@ -0,0 +1,4 @@ +<script> +var blob = new Blob([123]); +parent.postMessage(URL.createObjectURL(blob), "*"); +</script> diff --git a/dom/base/test/file_bug1008126_worker.js b/dom/base/test/file_bug1008126_worker.js new file mode 100644 index 0000000000..4c8b8e6dd4 --- /dev/null +++ b/dom/base/test/file_bug1008126_worker.js @@ -0,0 +1,176 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +var gEntry1 = "data_1.txt"; +var gEntry2 = "data_2.txt"; +var gEntry3 = "data_big.txt"; +var gPaddingChar = "."; +var gPaddingSize = 10000; +var gPadding = ""; +for (var i = 0; i < gPaddingSize; i++) { + gPadding += gPaddingChar; +} +var gData1 = "TEST_DATA_1:ABCDEFGHIJKLMNOPQRSTUVWXYZ" + gPadding; +var gData2 = "TEST_DATA_2:1234567890" + gPadding; + +function ok(a, msg) { + postMessage({type: "status", status: !!a, msg: msg }); +} + +function is(a, b, msg) { + postMessage({type: "status", status: a === b, msg: msg }); +} + +function checkData(xhr, data, mapped, cb) { + var ct = xhr.getResponseHeader("Content-Type"); + if (mapped) { + ok(ct.indexOf("mem-mapped") != -1, "Data is memory-mapped"); + } else { + ok(ct.indexOf("mem-mapped") == -1, "Data is not memory-mapped"); + } + ok(xhr.response, "Data is non-null"); + var str = String.fromCharCode.apply(null, new Uint8Array(xhr.response)); + ok(str == data, "Data is correct"); + cb(); +} + +self.onmessage = function onmessage(event) { + var jar = event.data; + + function makeJarURL(entry) { + return "jar:" + jar + "!/" + entry; + } + + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + + function reset_event_hander() { + xhr.onerror = function(e) { + ok(false, "Error: " + e.error + "\n"); + }; + xhr.onprogress = null; + xhr.onreadystatechange = null; + xhr.onload = null; + xhr.onloadend = null; + } + + function test_chunked_arraybuffer() { + ok(true, "Test chunked arraybuffer"); + + var lastIndex = 0; + xhr.onprogress = function(event) { + if (xhr.response) { + var buf = new Uint8Array(xhr.response); + var allMatched = true; + // The content of data cycles from 0 to 9 (i.e. 01234567890123......). + for (var i = 0; i < buf.length; i++) { + if (String.fromCharCode(buf[i]) != lastIndex % 10) { + allMatched = false; + break; + } + lastIndex++; + } + ok(allMatched, "Data chunk is correct. Loaded " + + event.loaded + "/" + event.total + " bytes."); + } + }; + xhr.onload = runTests; + xhr.open("GET", makeJarURL(gEntry3), true); + xhr.responseType = "moz-chunked-arraybuffer"; + xhr.send(); + } + + var readystatechangeCount = 0; + var loadCount = 0; + var loadendCount = 0; + + function checkEventCount(cb) { + ok(readystatechangeCount == 1 && loadCount == 1 && loadendCount == 1, + "Saw all expected events"); + cb(); + } + + function test_multiple_events() { + ok(true, "Test multiple events"); + xhr.abort(); + + xhr.onreadystatechange = function() { + if (xhr.readyState == xhr.DONE) { + readystatechangeCount++; + checkData(xhr, gData2, false, function() {} ); + } + }; + xhr.onload = function() { + loadCount++; + checkData(xhr, gData2, false, function() {} ); + }; + xhr.onloadend = function() { + loadendCount++; + checkData(xhr, gData2, false, function() {} ); + }; + xhr.open("GET", makeJarURL(gEntry2), false); + xhr.responseType = "arraybuffer"; + xhr.send(); + checkEventCount(runTests); + } + + function test_sync_xhr_data1() { + ok(true, "Test sync XHR with data1"); + xhr.open("GET", makeJarURL(gEntry1), false); + xhr.responseType = "arraybuffer"; + xhr.send(); + checkData(xhr, gData1, true, runTests); + } + + function test_sync_xhr_data2() { + ok(true, "Test sync XHR with data2"); + xhr.open("GET", makeJarURL(gEntry2), false); + xhr.responseType = "arraybuffer"; + xhr.send(); + checkData(xhr, gData2, false, runTests); + } + + function test_async_xhr_data1() { + ok(true, "Test async XHR with data1"); + xhr.onload = function() { + checkData(xhr, gData1, true, runTests); + }; + xhr.open("GET", makeJarURL(gEntry1), true); + xhr.responseType = "arraybuffer"; + xhr.send(); + } + + function test_async_xhr_data2() { + ok(true, "Test async XHR with data2"); + xhr.onload = function() { + checkData(xhr, gData2, false, runTests); + }; + xhr.open("GET", makeJarURL(gEntry2), true); + xhr.responseType = "arraybuffer"; + xhr.send(); + } + + var tests = [ + test_chunked_arraybuffer, + test_multiple_events, + test_sync_xhr_data1, + test_sync_xhr_data2, + test_async_xhr_data1, + test_async_xhr_data2 + ]; + + function runTests() { + if (!tests.length) { + postMessage({type: "finish" }); + return; + } + + reset_event_hander(); + + var test = tests.shift(); + test(); + } + + runTests(); +}; diff --git a/dom/base/test/file_bug1011748_OK.sjs b/dom/base/test/file_bug1011748_OK.sjs new file mode 100644 index 0000000000..71a0f5c3e8 --- /dev/null +++ b/dom/base/test/file_bug1011748_OK.sjs @@ -0,0 +1,4 @@ +// Function to indicate HTTP 200 OK after redirect from file_bug1011748_redirect.sjs +function handleRequest(request, response) { + response.setStatusLine(null, 200, "OK"); +} diff --git a/dom/base/test/file_bug1011748_redirect.sjs b/dom/base/test/file_bug1011748_redirect.sjs new file mode 100644 index 0000000000..3dec893675 --- /dev/null +++ b/dom/base/test/file_bug1011748_redirect.sjs @@ -0,0 +1,5 @@ +// SJS handler to redirect the XMLHttpRequest object to file_bug1011748_OK.sjs +function handleRequest(request, response) { + response.setStatusLine(null, 302, "Moved Temporarily"); + response.setHeader("Location", "file_bug1011748_OK.sjs", false); +} diff --git a/dom/base/test/file_bug1091883_frame.html b/dom/base/test/file_bug1091883_frame.html new file mode 100644 index 0000000000..a245175ae3 --- /dev/null +++ b/dom/base/test/file_bug1091883_frame.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<body> +<h2>Frame I am.</h2> +<script> +var subframeOrigin = location.hash.substr(1); // e.g., "http://example.com" +var subframe = document.createElement("iframe"); +subframe.src = subframeOrigin + + "/tests/dom/base/test/file_bug1091883_subframe.html"; +document.body.appendChild(subframe); +</script> +</body> +</html> diff --git a/dom/base/test/file_bug1091883_subframe.html b/dom/base/test/file_bug1091883_subframe.html new file mode 100644 index 0000000000..f282e1eeb9 --- /dev/null +++ b/dom/base/test/file_bug1091883_subframe.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> +<body> +<h3>Subframe I am.</h3> +</body> +</html> diff --git a/dom/base/test/file_bug1091883_target.html b/dom/base/test/file_bug1091883_target.html new file mode 100644 index 0000000000..2095595fbc --- /dev/null +++ b/dom/base/test/file_bug1091883_target.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<h3>Target I am.</h3> +<script> +var testRun = location.hash.substr(1); +parent.parent.postMessage(document.referrer + " " + testRun, + "http://mochi.test:8888"); +</script> +</head> +<body> +</body> +</html> diff --git a/dom/base/test/file_bug1198095.js b/dom/base/test/file_bug1198095.js new file mode 100644 index 0000000000..40058631ad --- /dev/null +++ b/dom/base/test/file_bug1198095.js @@ -0,0 +1,26 @@ +var { classes: Cc, interfaces: Ci, utils: Cu } = Components; +Cu.importGlobalProperties(["File"]); + +function createFileWithData(message) { + var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); + var testFile = dirSvc.get("ProfD", Ci.nsIFile); + testFile.append("fileAPItestfileBug1198095"); + + var outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); + outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate + 0o666, 0); + + outStream.write(message, message.length); + outStream.close(); + + var domFile = File.createFromNsIFile(testFile); + return domFile; +} + +addMessageListener("file.open", function (message) { + sendAsyncMessage("file.opened", createFileWithData(message)); +}); + +addMessageListener("file.modify", function (message) { + sendAsyncMessage("file.modified", createFileWithData(message)); +}); diff --git a/dom/base/test/file_bug1250148.sjs b/dom/base/test/file_bug1250148.sjs new file mode 100644 index 0000000000..a85347896b --- /dev/null +++ b/dom/base/test/file_bug1250148.sjs @@ -0,0 +1,60 @@ +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function utf8decode(s) { + return decodeURIComponent(escape(s)); +} + +function utf8encode(s) { + return unescape(encodeURIComponent(s)); +} + +function handleRequest(request, response) { + var bodyStream = new BinaryInputStream(request.bodyInputStream); + + var requestBody = ""; + while ((bodyAvail = bodyStream.available()) > 0) { + requestBody += bodyStream.readBytes(bodyAvail); + } + + var result = []; + + if (request.method == "POST") { + var contentTypeParams = {}; + request.getHeader("Content-Type").split(/\s*\;\s*/).forEach(function(s) { + if (s.indexOf('=') >= 0) { + let [name, value] = s.split('='); + contentTypeParams[name] = value; + } + else { + contentTypeParams[''] = s; + } + }); + + if (contentTypeParams[''] == "multipart/form-data" && + request.queryString == "") { + requestBody.split("--" + contentTypeParams.boundary).slice(1, -1).forEach(function (s) { + + let headers = {}; + let headerEnd = s.indexOf("\r\n\r\n"); + s.substr(2, headerEnd-2).split("\r\n").forEach(function(s) { + // We're assuming UTF8 for now + let [name, value] = s.split(': '); + headers[name] = utf8decode(value); + }); + + let body = s.substring(headerEnd + 4, s.length - 2); + if (!headers["Content-Type"] || headers["Content-Type"] == "text/plain") { + // We're assuming UTF8 for now + body = utf8decode(body); + } + result.push({ headers: headers, body: body}); + }); + } + } + + response.setHeader("Content-Type", "text/plain; charset=utf-8", false); + response.write(utf8encode(JSON.stringify(result))); +} diff --git a/dom/base/test/file_bug1263696_frame_fail.html b/dom/base/test/file_bug1263696_frame_fail.html new file mode 100644 index 0000000000..b45561aa6f --- /dev/null +++ b/dom/base/test/file_bug1263696_frame_fail.html @@ -0,0 +1,12 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/REC-html401-19991224/strict.dtd"> +<html> + <head> + <title>Bug 1263696 - iframe that should not be loaded</title> + </head> + <body> + <script> + parent.SimpleTest.ok(false, "this iframe should not load"); + </script> + </body> +</html> diff --git a/dom/base/test/file_bug1263696_frame_pass.html b/dom/base/test/file_bug1263696_frame_pass.html new file mode 100644 index 0000000000..7f49d6541c --- /dev/null +++ b/dom/base/test/file_bug1263696_frame_pass.html @@ -0,0 +1,13 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/REC-html401-19991224/strict.dtd"> +<html> + <head> + <title>Bug 1263696 - iframe that should be loaded</title> + </head> + <body> + <script> + parent.index = parent.index + 1; + parent.SimpleTest.ok(true, "this iframe should load"); + </script> + </body> +</html> diff --git a/dom/base/test/file_bug1268962.sjs b/dom/base/test/file_bug1268962.sjs new file mode 100644 index 0000000000..42b1ecef3d --- /dev/null +++ b/dom/base/test/file_bug1268962.sjs @@ -0,0 +1,90 @@ +// Test server for bug 1268962 +'use strict'; +Components.utils.importGlobalProperties(["URLSearchParams"]); +const HTTPStatus = new Map([ + [100, 'Continue'], + [101, 'Switching Protocol'], + [200, 'OK'], + [201, 'Created'], + [202, 'Accepted'], + [203, 'Non-Authoritative Information'], + [204, 'No Content'], + [205, 'Reset Content'], + [206, 'Partial Content'], + [300, 'Multiple Choice'], + [301, 'Moved Permanently'], + [302, 'Found'], + [303, 'See Other'], + [304, 'Not Modified'], + [305, 'Use Proxy'], + [306, 'unused'], + [307, 'Temporary Redirect'], + [308, 'Permanent Redirect'], + [400, 'Bad Request'], + [401, 'Unauthorized'], + [402, 'Payment Required'], + [403, 'Forbidden'], + [404, 'Not Found'], + [405, 'Method Not Allowed'], + [406, 'Not Acceptable'], + [407, 'Proxy Authentication Required'], + [408, 'Request Timeout'], + [409, 'Conflict'], + [410, 'Gone'], + [411, 'Length Required'], + [412, 'Precondition Failed'], + [413, 'Request Entity Too Large'], + [414, 'Request-URI Too Long'], + [415, 'Unsupported Media Type'], + [416, 'Requested Range Not Satisfiable'], + [417, 'Expectation Failed'], + [500, 'Internal Server Error'], + [501, 'Not Implemented'], + [502, 'Bad Gateway'], + [503, 'Service Unavailable'], + [504, 'Gateway Timeout'], + [505, 'HTTP Version Not Supported'] +]); + +const SAME_ORIGIN = 'http://mochi.test:8888/tests/dom/base/test/file_bug1268962.sjs'; +const CROSS_ORIGIN = 'http://example.com/tests/dom/base/test/file_bug1268962.sjs'; + +function handleRequest(request, response) { + const queryMap = new URLSearchParams(request.queryString); + + // Check redirection before everything else. + if (queryMap.has('redirect')) { + let redirect = queryMap.get('redirect'); + let location; + if (redirect == 'sameorigin') { + location = SAME_ORIGIN; + } else if (redirect == 'crossorigin') { + location = CROSS_ORIGIN; + } + + if (location) { + // Use HTTP 302 redirection. + response.setStatusLine('1.1', 302, HTTPStatus.get(302)); + + // Forward query strings except the redirect option. + queryMap.delete('redirect'); + response.setHeader('Location', location + '?' + queryMap.toString()); + + return; + } + } + + if (queryMap.has('statusCode')) { + let statusCode = parseInt(queryMap.get('statusCode')); + let statusText = HTTPStatus.get(statusCode); + response.setStatusLine('1.1', statusCode, statusText); + } + if (queryMap.has('cacheControl')) { + let cacheControl = queryMap.get('cacheControl'); + response.setHeader('Cache-Control', cacheControl); + } + if (queryMap.has('allowOrigin')) { + let allowOrigin = queryMap.get('allowOrigin'); + response.setHeader('Access-Control-Allow-Origin', allowOrigin); + } +} diff --git a/dom/base/test/file_bug1274806.html b/dom/base/test/file_bug1274806.html new file mode 100644 index 0000000000..62bef3044b --- /dev/null +++ b/dom/base/test/file_bug1274806.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title></title> + <script> + window.onload = function() { + setTimeout(function() { + var rng = document.createRange(); + rng.setStart(document.getElementsByTagName("p").item(0).firstChild, 100); + rng.setEndAfter(document.getElementsByTagName("p").item(0)); + try { + rng.extractContents(); + opener.ok(true, "extractContents should not throw when document in iframe is being modified."); + } catch(ex) { + opener.ok(false, "extractContents shouldn't have thrown: " + ex); + } + + opener.setTimeout("SimpleTest.finish();", 0); + window.close(); + + }, 0); + }; + </script> +</head> +<body> +<p> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur elit nisi, convallis sed scelerisque sit amet, vestibulum eu odio. Pellentesque et quam et nibh sollicitudin rutrum. Fusce tristique hendrerit ligula, et euismod sapien facilisis quis. Donec tincidunt turpis tortor, in pharetra tellus euismod ac. Vestibulum consectetur nulla lacinia, consectetur mauris ac, tempus libero. Nam non dui id enim dapibus porta id sed lectus. Praesent at suscipit neque. Vestibulum tellus lorem, placerat et volutpat sed, elementum eget lacus. Sed interdum nisi et imperdiet varius. Sed non magna odio. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus velit risus, accumsan nec efficitur nec, semper sed arcu. Praesent consectetur lectus justo, fringilla imperdiet neque lobortis id. Donec efficitur pulvinar finibus. + <iframe src="data:text/html,<script>window.onunload = function() {document.removeChild(document.documentElement); }</script>" width="10" height="10"></iframe> +</p> +<p>test</p> +</body> +</html> diff --git a/dom/base/test/file_bug28293.sjs b/dom/base/test/file_bug28293.sjs new file mode 100644 index 0000000000..0954ec105e --- /dev/null +++ b/dom/base/test/file_bug28293.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setHeader("Content-Type", "text/plain", false); + response.write(decodeURIComponent(request.queryString)); +} diff --git a/dom/base/test/file_bug326337.xml b/dom/base/test/file_bug326337.xml new file mode 100644 index 0000000000..d328051e74 --- /dev/null +++ b/dom/base/test/file_bug326337.xml @@ -0,0 +1 @@ +<data root="yes"/>
diff --git a/dom/base/test/file_bug326337_inner.html b/dom/base/test/file_bug326337_inner.html new file mode 100644 index 0000000000..709fbbc610 --- /dev/null +++ b/dom/base/test/file_bug326337_inner.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=326337 +--> +<head> + <title>Inner file for Bug 326337</title> +</head> +<body> +<script> + +document.domain = "example.com"; + +runTest(); + +var xhr; + +function runTest() { + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_bug326337.xml", true); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + check(xhr.responseXML.documentElement.getAttribute("root")); + SpecialPowers.wrap(parent).location.hash = "#done"; + } + } + xhr.send(null); +} + +function check(attr) { + if (attr != "yes") { + SpeciaPowers.wrap(parent).location.hash = "#fail"; + throw 1; + } +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/file_bug326337_outer.html b/dom/base/test/file_bug326337_outer.html new file mode 100644 index 0000000000..9d63f72632 --- /dev/null +++ b/dom/base/test/file_bug326337_outer.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<body> +<iframe id="inner" src="http://test1.example.com/tests/dom/base/test/file_bug326337_inner.html"></iframe> +<script> +var t = setInterval(doCheck, 300); +function doCheck() { + if (location.hash) { + clearInterval(t); + window.opener.finishTest(location.hash); + } +} +</script> +</body> +</html> diff --git a/dom/base/test/file_bug357450.js b/dom/base/test/file_bug357450.js new file mode 100644 index 0000000000..c432052b8d --- /dev/null +++ b/dom/base/test/file_bug357450.js @@ -0,0 +1,64 @@ +/** Test for Bug 357450 **/ + +SimpleTest.waitForExplicitFinish(); + +function testGetElements (root, classtestCount) { + + ok(root.getElementsByClassName, "getElementsByClassName exists"); + is(typeof(root.getElementsByClassName), "function", "getElementsByClassName is a function"); + + var nodes = root.getElementsByClassName("f"); + + is(typeof(nodes.item), "function"); + is(typeof(nodes.length), "number"); + is(nodes.length, 0, "string with no matching class should get an empty list"); + + nodes = root.getElementsByClassName("foo"); + ok(nodes, "should have nodelist object"); + + // HTML5 says ints are allowed in class names + // should match int class + + nodes = root.getElementsByClassName("1"); + is(nodes[0], $('int-class'), "match integer class name"); + nodes = root.getElementsByClassName([1]); + is(nodes[0], $('int-class'), "match integer class name 2"); + nodes = root.getElementsByClassName(["1 junk"]); + + is(nodes.length, 0, "two classes, but no elements have both"); + + nodes = root.getElementsByClassName("test1"); + is(nodes[0], $('test1'), "Id and class name turn up the same node"); + nodes = root.getElementsByClassName("test1 test2"); + is(nodes.length, 0, "two classes, but no elements have both"); + + // WHATWG examples + nodes = document.getElementById('example').getElementsByClassName('aaa'); + is(nodes.length, 2, "returns 2 elements"); + + nodes = document.getElementById('example').getElementsByClassName('ccc bbb') + is(nodes.length, 1, "only match elements that have all the classes specified in that array. tokenize string arg.") + is(nodes[0], $('p3'), "matched tokenized string"); + + nodes = document.getElementById('example').getElementsByClassName(''); + is(nodes.length, 0, "class name with empty string shouldn't return nodes"); + + nodes = root.getElementsByClassName({}); + ok(nodes, "bogus arg shouldn't be null"); + is(typeof(nodes.item), "function"); + is(typeof(nodes.length), "number"); + is(nodes.length, 0, "bogus arg should get an empty nodelist"); +} + +addLoadEvent(function() { + if (document.getElementsByName) { + var anchorNodes = document.getElementsByName("nametest"); + is(anchorNodes.length, 1, "getElementsByName still works"); + is(anchorNodes[0].getAttribute("name"), "nametest", + "getElementsByName still works"); + } + testGetElements($("content"), 1); + testGetElements(document.documentElement, 3); + testGetElements(document, 3); +}); +addLoadEvent(SimpleTest.finish); diff --git a/dom/base/test/file_bug416317.xhtml b/dom/base/test/file_bug416317.xhtml new file mode 100644 index 0000000000..7702cc5611 --- /dev/null +++ b/dom/base/test/file_bug416317.xhtml @@ -0,0 +1,1476 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" + xml:lang="en" lang="en" dir="ltr" id="html" class="unitTest" title=":root selector"> +<head> + <title>selectorTest</title> + <!-- (c) Disruptive Innovations 2008 --> + <style type="text/css"> + /* TEST 0 : BASIC TESTS */ + /* element type selector */ + body { background-color: red; margin: 10px; padding: 10px; color: red; font-family: sans-serif } + div { background-color: red; color: red; } + div.header { background-color: #e0e0e0; color: black; padding: 10px; margin-bottom: 10px;} + /* class selector */ + .unitTest { width: 10px; background-color: red; color: red; margin: 0px; margin-right: 2px; float: left; } + .test { margin-bottom: 2px; background-color: green; color: green; } + /* group of selectors */ + .unitTest, .test { height: 10px; } + + .UI > * { float: left } + .UI { clear: both; height: auto; padding-top: 6px;} + .tilda { clear: both; height: auto; padding-top: 6px;} + .plus { clear: both; height: auto; padding-top: 6px;} + + h1, p { width: 500px; color: #000; } + a { color: #000; } + #results { background: #FFF; width: 600px; padding: 10px 40px; color: #000; font-size: 11px; line-height: 1.3em; } + #root, #root2, #root3 { display: none; } + + /* init */ + .blox16 { background-color: red; } + .blox17 { background-color: red; } + .lastChild > p { background-color: red; } + .firstOfType > p { background-color: red } + .lastOfType > p { background-color: red } + .empty > .isEmpty { color: red; } + html { background-color: red; } + </style> + <span type="text/test" id="test"><![CDATA[ + /* :target selector */ + .target :target { background-color: lime; } + + /* test 1 : childhood selector */ + html > body { background-color: green; } + .test > .blox1 { background-color: lime; } + + /* test 2 : attribute existence selector */ + /* attribute with a value */ + .blox2[align] { background-color: lime; } + /* attribute with empty value */ + .blox3[align] { background-color: lime; } + /* attribute with almost similar name */ + .blox4, .blox5 { background-color: lime } + .blox4[align], .blox5[align] { background-color: red; } + + /* test3 : attribute value selector */ + .blox6[align="center"] { background-color: lime; } + .blox6[align="c"] { background-color: red; } + .blox6[align="centera"] { background-color: red; } + .blox6[foo="\e9"] { background-color: lime; } + .blox6[\_foo="\e9"] { background-color: lime; } + + /* test 4 : [~=] */ + .blox7[class~="foo"] { background-color: lime; } + .blox8, .blox9, .blox10 { background-color: lime; } + .blox8[class~=""] { background-color: red; } + .blox9[foo~=""] { background-color: red; } + .blox10[foo~="foo"] { background-color: red; } + + /* test5 [^=] */ + .attrStart > .t3 { background-color: lime; } + .attrStart > .t1[class^="unit"] { background-color: lime; } + .attrStart > .t2 { background-color: lime; } + .attrStart > .t2[class^="nit"] { background-color: red; } + .attrStart > .t3[align^=""] { background-color: red; } + .attrStart > .t4[foo^="\e9"] { background-color: lime; } + + /* test6 [$=] */ + .attrEnd > .t3 { background-color: lime; } + .attrEnd > .t1[class$="t1"] { background-color: lime; } + .attrEnd > .t2 { background-color: lime; } + .attrEnd > .t2[class$="unit"] { background-color: red; } + .attrEnd > .t3[align$=""] { background-color: red; } + .attrEnd > .t4[foo$="\e9"] { background-color: lime; } + + /* test7 [*=] */ + .attrMiddle > .t3 { background-color: lime; } + .attrMiddle > .t1[class*="t t"] { background-color: lime; } + .attrMiddle > .t2 { background-color: lime; } + .attrMiddle > .t2[class*="a"] { background-color: red; } + .attrMiddle > .t3[align*=""] { background-color: red; } + .attrMiddle > .t4[foo*="\e9"] { background-color: lime; } + + /* :first-child tests */ + .firstChild .unitTest:first-child { background-color: lime; } + .blox12:first-child { background-color: red; } + .blox13:first-child { background-color: red; } + .blox12, .blox13 { background-color: lime } + + /* :root tests */ + :root { background-color: green; } + + /* :scope tests */ + :scope { background-color: green; } + + /* :nth-child(n) tests */ + .nthchild1 > :nth-last-child(odd) { background-color: lime; } + .nthchild1 > :nth-child(odd) { background-color: lime; } + + .nthchild2 > :nth-last-child(even) { background-color: lime; } + .nthchild2 > :nth-child(even) { background-color: lime; } + + .nthchild3 > :nth-child(3n+2) { background-color: lime; } + .nthchild3 > :nth-last-child(3n+1) { background-color: lime; } + .nthchild3 > :nth-last-child(3n+3) { background-color: lime; } + + .nthoftype1 > div:nth-of-type(odd) { background-color: lime; } + .nthoftype1 > div:nth-last-of-type(odd) { background-color: lime; } + .nthoftype1 > p { background-color: green; } + + .nthoftype2 > div:nth-of-type(even) { background-color: lime; } + .nthoftype2 > div:nth-last-of-type(even) { background-color: lime; } + .nthoftype2 > p { background-color: green; } + + .nthoftype3 > div:nth-of-type(3n+1) { background-color: lime; } + .nthoftype3 > div:nth-last-of-type(3n+1) { background-color: lime; } + .nthoftype3 > div:nth-last-of-type(3n+2) { background-color: lime; } + .nthoftype3 > p { background-color: green; } + + /* :not() tests */ + .blox14:not(span) { background-color: lime; } + .blox15:not([foo="blox14"]) { background-color: lime; } + .blox16:not(.blox15) { background-color: lime; } + + /* :only-of-type tests */ + .blox17:only-of-type { background-color: lime; } + .blox18:only-of-type { background-color: red; } + .blox18:not(:only-of-type) { background-color: lime; } + + /* :last-child tests */ + .lastChild > :last-child { background-color: lime } + .lastChild > :not(:last-child) { background-color: lime } + + /* :first-of-type tests */ + .firstOfType > *:first-of-type { background-color: lime; } + *.firstOfType > :not(:first-of-type) { background-color: lime; } + + /* :last-of-type tests */ + .lastOfType > *:last-of-type { background-color: lime; } + *.lastOfType > :not(:last-of-type) { background-color: lime; } + + /* :only-child tests */ + .onlyChild > *:not(:only-child) { background-color: lime; } + .onlyChild > .unitTest > *:only-child { background-color: lime; } + + /* :only-of-type tests */ + .onlyOfType *:only-of-type { background-color: lime; } + .onlyOfType *:not(:only-of-type) { background-color: lime; } + + /* :empty tests */ + .empty > *.isEmpty:empty { background-color: lime; color: lime; } + .empty > .isNotEmpty { background-color: blue; color: blue; } + .empty > .isNotEmpty:empty { background-color: red; color: red; } + .empty > .isNotEmpty:not(:empty) { background-color: lime; color: lime; } + + /* :lang() tests */ + .lang :lang(en) { background-color: lime; } + .lang :lang(fr) { background-color: lime; } + .lang .t1 { background-color: blue; } + .lang .t1:lang(es) { background-color: lime; } + .lang :lang(es-AR) { background-color: red; } + + /* [|=] tests */ + .attrLang .t1 { background-color: lime; } + .attrLang .t1[lang|="en"] { background-color: red; } + .attrLang [lang|="fr"] { background-color: lime; } + .attrLang .t2[lang|="en"] { background-color: lime; } + .attrLang .t3 { background-color: blue; } + .attrLang .t3[lang|="es"] { background-color: lime; } + .attrLang [lang|="es-AR"] { background-color: red; } + + /* UI tests */ + .UI .t1:enabled > .unitTest { background-color: lime; } + .UI .t2:disabled > .unitTest { background-color: lime; } + .UI .t3:checked + div { background-color: lime; } + .UI .t4:not(:checked) + div { background-color: lime; } + + /* ~ combinator tests */ + .tilda .t1 { background-color: white; } + .tilda .t1 ~ .unitTest { background-color: lime; } + .tilda .t1:hover ~ .unitTest { background-color: red; } + + /* ~ combinator tests */ + .plus .t1, .plus .t2 { background-color: white; } + .plus .t1 + .unitTest + .unitTest { background-color: lime; } + .plus .t1:hover + .unitTest + .unitTest { background-color: red; } + ]]></span> + <span type="text/test" id="error"> + .blox16:not(.blox15[foo="blox14"]) { background-color: red; } + + /* Tests from http://www.w3.org/Style/CSS/Test/CSS3/Selectors/20060307/html/index.html */ + div:not(:not(div)) { background-color : red } + + div, { background: red; } + .5cm { background: red; } + foo & address, p { background: red; } + [*=test] { background: red; } + [*|*=test] { background: red; } + + div:subject { background: red; } + :canvas { background: red; } + :viewport { background: red; } + :window { background: red; } + :menu { background: red; } + :table { background: red; } + :select { background: red; } + ::canvas { background: red; } + ::viewport { background: red; } + ::window { background: red; } + ::menu { background: red; } + ::table { background: red; } + ::select { background: red; } + + ..test { background: red; color: yellow; } + .foo..quux { background: red; color: yellow; } + .bar. { background: red; color: yellow; } + </span> + <script><![CDATA[ + window.onload = function() { + if (window.parent && window.parent.SpecialPowers) { + window.parent.SpecialPowers.pushPrefEnv( + { 'set': [[ "layout.css.scope-pseudo.enabled", true]] }, + doTest); + } else { + doTest(); + } + } + + function doTest(){ + if ( window.location.hash.indexOf("target") == -1 ) + window.location.hash = "#target"; + + var root = document.getElementById("root"); + var root2 = document.getElementById("root2"); + var root3 = document.getElementById("root3"); + var results = []; + var tests = 0, passed = 0; + var cache = {}; + + var css = document.getElementById("test").firstChild.nodeValue.split("\n"); + for ( var i = 0; i < css.length; i++ ) { + css[i] = css[i].replace(/\/\*.*?\*\//g, "") + .replace(/^\s*|\s*$/g, "").split(/\s*{/); + } + + var ecss = document.getElementById("error").firstChild.nodeValue.split("\n"); + for ( var i = 0; i < ecss.length; i++ ) { + ecss[i] = ecss[i].replace(/\/\*.*?\*\//g, "") + .replace(/^\s*|\s*$/g, "").split(/\s*{/); + } + + var namespaceCheck = {}; + + var badNamespace = [ + {}, + null, + undefined, + ]; + + interfaceCheck(root, "Element"); + runTest( css, "Element", root, true ); + check( "Inside Element", root, true, false ); + cacheCheck( "Element", root ); + check( "Outside Element", root2, passed === 0 ? "autofail" : false, false ); + runTest( ecss, "SyntaxError: Element", root, false ); + jqTests("Element", root3, "querySelectorAll"); + + var root4 = root2.cloneNode(true); + interfaceCheck(root4, "Disconnected Element"); + runTest( css, "Disconnected Element", root4, true ); + check( "Disconnected Element", root4, true, true ); + cacheCheck( "Disconnected Element", root4 ); + runTest( ecss, "SyntaxError: Disconnected Element", root4, false ); + jqTests("Disconnected Element", root3.cloneNode(true), "querySelectorAll"); + var newRoot = document.createElement("nosuchtag"); + newRoot.appendChild(root3.cloneNode(true)); + jqTests("Disconnected Element scoping", newRoot, "querySelectorAll"); + + var fragment = document.createDocumentFragment(); + fragment.appendChild( root2.cloneNode(true) ); + + interfaceCheck(fragment, "Fragment"); + runTest( css, "Fragment", fragment, true ); + check( "Fragment", fragment, true, true ); + runTest( ecss, "SyntaxError: Fragment", fragment, false ); + cacheCheck( "Fragment", fragment ); + + root.parentNode.removeChild( root ); + + interfaceCheck(document, "Document"); + runTest( css, "Document", document, true ); + check( "Document", document, true, false ); + runTest( ecss, "SyntaxError: Document", document, false ); + jqTests("Document", document, "querySelectorAll"); + cacheCheck( "Document", document ); + + done(); + + function interfaceCheck(obj, type){ + var q = typeof obj.querySelector === "function"; + assert( q, type + " supports querySelector" ); + var qa = typeof obj.querySelectorAll === "function"; + assert( qa, type + " supports querySelectorAll" ); + return q && qa; + } + + function done(){ + if (window.parent && window.parent.SimpleTest) { + window.parent.SimpleTest.finish(); + } else { + var r = document.getElementById("results"); + var li = document.createElement("li"); + var b = document.createElement("b"); + b.appendChild( document.createTextNode( ((passed / tests) * 100).toFixed(1) + "%" ) ); + li.appendChild( b ); + li.appendChild( document.createTextNode( ": " + passed + " passed, " + (tests - passed) + " failed" ) ); + r.appendChild( li ); + + for ( var i = 0; i < results.length; i++ ) { + var li = document.createElement("li"); + var span = document.createElement("span"); + span.style.color = (results[i][0] === "FAIL" ? "red" : "green"); + span.appendChild( document.createTextNode( results[i][0] ) ); + li.appendChild( span ); + li.appendChild( document.createTextNode( " " + results[i][1] ) ); + r.appendChild( li ); + } + } + } + + function cacheCheck( type, root ) { + try { + var pre = root.querySelectorAll( "div" ), preLength = pre.length; + + var div = document.createElement("div"); + (root.body || root).appendChild( div ); + + var post = root.querySelectorAll( "div" ), postLength = post.length; + + assert( pre.length == preLength, type + ": StaticNodeList" ); + assert( post.length != pre.length, type + ": StaticNodeList" ); + } catch(e) { + assert( false, type + ": StaticNodeList" ); + assert( false, type + ": StaticNodeList" ); + } + + if ( div ) + (root.body || root).removeChild( div ); + } + + + function runTest( css, type, root, expect ) { + var pass = false; + try { + root.querySelectorAll(""); + } catch(e){ pass = e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR; } + assert( pass, type + ".querySelectorAll Empty String" ); + + pass = false; + try { + pass = root.querySelectorAll(null).length === 0; + } catch(e){ pass = false; } + assert( pass, type + ".querySelectorAll null" ); + + pass = false; + try { + pass = root.querySelectorAll(undefined).length === 0; + } catch(e){ pass = false; } + assert( pass, type + ".querySelectorAll undefined" ); + + pass = false; + try { + if ( root.querySelectorAll ) + root.querySelectorAll(); + } catch(e){ pass = true; } + assert( pass, type + ".querySelectorAll no value" ); + + pass = false; + try { + root.querySelector(""); + } catch(e){ pass = e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR; } + assert( pass, type + ".querySelector Empty String" ); + + pass = false; + try { + pass = root.querySelector(null) === null; + } catch(e){ pass = false; } + assert( pass, type + ".querySelector null" ); + + pass = false; + try { + pass = root.querySelector(undefined) === null; + } catch(e){ pass = false; } + assert( pass, type + ".querySelector undefined" ); + + pass = false; + try { + if ( root.querySelector ) + root.querySelector(); + } catch(e){ pass = true; } + assert( pass, type + ".querySelector no value" ); + + for ( var i = 0; i < css.length; i++ ) { + var test = css[i]; + if ( test.length == 2 ) { + var query = test[0], color = test[1].match(/: ([^\s;]+)/)[1]; + + try { + var found = root.querySelectorAll(query); + + for ( var f = 0; f < found.length; f++ ) { + found[f].style.backgroundColor = color; + } + + var pass = color != "red" || found.length === 0; + + assert(expect && pass, type + ".querySelectorAll: " + query); + } catch(e){ + var pass = !expect && e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR || false; + assert(pass, type + ".querySelectorAll: " + query); + } + + if ( expect ) { + var pass = false; + + try { + var found2 = root.querySelectorAll( " \t\r\n " + query + " \t\r\n " ); + pass = found2.length == found.length; + } catch(e) {} + + assert(pass, type + ".querySelectorAll Whitespace Trim: " + query); + } + + try { + var single = root.querySelector(query); + + var pass = found.length == 0 && single === null || + found.length && found[0] == single; + + assert(expect, type + ".querySelector: " + query); + } catch(e){ + var pass = !expect && e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR || false; + assert(pass, type + ".querySelector: " + query); + } + } + } + } + + function check( type, root, expect, fragment ){ + var walker = document.createTreeWalker( root, NodeFilter.SHOW_ELEMENT, { acceptNode: function(){ return 1; } } ); + + while ( walker.nextNode() ) { + var div = walker.currentNode; + if ( (div.getAttribute("class") || "").toString().indexOf("unitTest") > -1 && + (!fragment || div.getAttribute("id") !== "nofragment") ) { + // If we're display:none, we need to toggle that when doing computed + // style. + var needToggle = + (window.frameElement && + window.frameElement.style.display == "none"); + if (needToggle) { + if ((div.getAttribute("class") || "").toString().indexOf("skipWhenToggling") > -1) { + continue; + } + window.frameElement.style.display = ""; + // make sure it kicks in immediately + document.body.offsetWidth; + } + var view = document.defaultView.getComputedStyle(div, null); + var bg = view.getPropertyValue("background-color") || div.style.backgroundColor; + if (needToggle) { + window.frameElement.style.display = "none"; + // make sure it kicks in immediately + document.body.offsetWidth; + } + + var pass = bg && bg.indexOf("(255, 0, 0") == -1 && bg.indexOf("#ff0000") == -1 && bg.indexOf("red") == -1; + //var pass = bg && bg.indexOf("(255, 0, 0") == -1 && bg.indexOf("#ff0000") == -1; + assert(pass === expect, type + ": " + (div.title || div.parentNode.title)); + } + } + } + + function assert(pass, title) { + // Update |passed| no matter what: some tests depend on this + passed += (pass ? 1 : 0); + + if (window.parent && window.parent.SimpleTest) { + window.parent.SimpleTest.ok(pass, title); + } else { + results.push([ (!pass ? "FAIL" : "PASS"), title ]); + tests++; + } + } + + function jqTests(type, root, select) { + + function query(q, resolver){ + try { + return root[select](q, resolver); + } catch(e){ + if ( e.message.indexOf("ERR") > -1 || + (e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR) ) + throw e; + } + } + + var all = query("*"); + + function checkMatchesSelector(results, q) { + var key = +new Date + ":" + Math.random(); + + function report(item, shouldMatch) { + assert( item.matches(q) === shouldMatch, + item + (shouldMatch ? "does not match" : "matches") + + " selector '" + q + "'" ); + } + + for (var i = 0; i < results.length; i++) { + var item = results.item(i); + item[key] = true; + report( item, true ); + } + + for (var stride = 15, // reduce test spam + i = Math.round(Math.random() * stride); + i < all.length; i += stride) + { + var item = all.item(i), + shouldMatch = !!item[key]; + report( item, shouldMatch ); + } + + for (var i = 0; i < results.length; i++) + delete results.item(i)[key]; + } + + function t( name, q, ids, restrict, ids2 ) { + var pass = true; + + if ( restrict === false && root != document ) + return; + + var namespaced = /\|[^=]/.test( q ); + var prepend = namespaced ? "xHTML|*#root3 " : "#root3 "; + q = (restrict === false || restrict === ":root" || + restrict === ":scope" ? "" : prepend) + + q.replace(/,/g, ", " + prepend); + var nq = q.replace(/>/g, ">").replace(/</g, "<"); + + if ( namespaced ) { + for ( var i = 0; i < badNamespace.length; i++ ) { + var resolver = badNamespace[i], pass = false, results = null; + + try { + results = query(q, resolver); + } catch(e) { + pass = (e.message === "bad ERROR" || + (e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR)); + } + + assert( pass, type + ": " + name + " Bad Resolver #" + (i+1) + " (" + nq + ")" + + (pass ? "" : " Expected: " + extra(ids) + " Received: " + extra(results)) ); + } + } else { + var pass = false; + + try { + var results = query(q); + pass = hasPassed( results, ids ); + } catch(e) { + pass = e.name == "SyntaxError" && e.code == DOMException.SYNTAX_ERR; + } + + assert( pass, type + ": " + name + " (" + nq + ")" + + (pass ? "" : " Expected: " + extra(ids) + " Received: " + extra(results)) ); + + // For now, don't use checkMatchesSelector when + // restrict === ":scope" because we have no way to hand the + // right scope to it yet. + if (results && restrict !== ":scope") + checkMatchesSelector( results, q ); + } + + function hasPassed(results, ids){ + var pass = (results && results.length == ids.length) || (!results && !ids); + + if ( ids && results ) { + for ( var i = 0; ids && i < ids.length; i++ ) { + if ( ids[i] !== results[i].getAttribute("id") ) { + pass = false; + } + } + } else { + pass = false; + } + + return pass; + } + + function extra(results){ + var extra = " ["; + if ( results ) { + for ( var i = 0; i < results.length; i++ ) { + extra += (extra.length > 2 ? "," : "") + "'" + (results[i].id || results[i]) + "'"; + } + } + + extra += "]"; + return extra; + } + } + + t( "SVG", "*|svg", ["svg1","svg2","svg3"] ); + t( "SVG", "svg|svg", ["svg2","svg3"] ); + t( "SVG", "svg|svg *|circle", ["circle2","circle3"] ); + t( "SVG", "svg|svg svg|circle", ["circle2","circle3"] ); + t( "SVG", "xHTML|div *|svg", ["svg1","svg2","svg3"] ); + t( "SVG", "div svg|svg", ["svg2","svg3"] ); + t( "SVG", "xHTML|div svg|svg", ["svg2","svg3"] ); + t( "SVG", "xHTML|div svg|svg *|circle", ["circle2","circle3"] ); + t( "SVG", "xHTML|div svg *|circle", ["circle1","circle2","circle3"], true, ["circle1"] ); + t( "SVG", "xHTML|div svg|svg svg|circle", ["circle2","circle3"] ); + + t( "Element Selector", "xHTML|p", ["firstp","ap","sndp","en","sap","first"] ); + t( "Parent Element", "xHTML|div p", ["firstp","ap","sndp","en","sap","first"] ); + t( "Parent Element", "xHTML|div xHTML|p", ["firstp","ap","sndp","en","sap","first"] ); + t( "Parent Element", "*|div xHTML|p", ["firstp","ap","sndp","en","sap","first"] ); + t( "Parent Element", "*|div *|p", ["firstp","ap","sndp","en","sap","first"] ); + t( "Child", "xHTML|p > xHTML|a", ["simon1","google","groups","mark","yahoo","simon"] ); + t( "Adjacent", "xHTML|a + xHTML|a", ["groups"] ); + t( "Adjacent", "xHTML|a + a", ["groups"] ); + t( "Nth-child", "xHTML|*#form xHTML|*#select1 xHTML|option:nth-child(3)", ["option1c"] ); + + assert( all && all.length > 30, type + ": Select all" ); + var good = all && all.length; + for ( var i = 0; all && i < all.length; i++ ) + if ( all[i].nodeType != 1 ) + good = false; + assert( good, type + ": Select all elements, no comment nodes" ); + + if ( root == document ) { + t( ":root Selector", ":root", ["html"], false ); + t( ":scope Selector", ":scope", ["html"], ":scope" ); + } else { + t( ":root Selector", ":root", [], ":root" ); + if (root.localName != "nosuchtag") { + t( ":scope Selector", ":scope > nosuchtag", + [ "outerbogustag" ], ":scope"); + } + t( ":scope Selector", ":scope nosuchtag nosuchtag", + [ "innerbogustag" ], ":scope"); + + if ( !root.parentNode ) { + t( ":root All Selector", ":root *", [], ":root" ); + } + } + + if ( root.parentNode || root == document ) { + assert( query(":root *").length == query("*").length - (root == document ? 1 : 0), type + ": :root All Selector" ); + } + assert( query(":scope *").length == query("*").length - (root == document ? 1 : 0), type + ": :scope All Selector" ); + + t( "Element Selector", "p", ["firstp","ap","sndp","en","sap","first"] ); + t( "Element Selector", "body", ["body"], false ); + t( "Element Selector", "html", ["html"], false ); + t( "Parent Element", "div p", ["firstp","ap","sndp","en","sap","first"] ); + var param = query("#object1 param"); + assert( param && param.length == 2, type + ": Object/param as context" ); + + var l = query("#length"); + assert( l && l.length, type + ': <input name="length"> cannot be found under IE' ); + var lin = query("#lengthtest input"); + assert( lin && lin.length, type + ': <input name="length"> cannot be found under IE' ); + + t( "Broken Selector", "[" ); + t( "Broken Selector", "(" ); + t( "Broken Selector", "{" ); + t( "Broken Selector", "<" ); + t( "Broken Selector", "()" ); + t( "Broken Selector", "<>" ); + t( "Broken Selector", "{}" ); + + t( "ID Selector", "#body", ["body"], false ); + t( "ID Selector w/ Element", "body#body", ["body"], false ); + t( "ID Selector w/ Element", "ul#first", [] ); + t( "ID selector with existing ID descendant", "#firstp #simon1", ["simon1"] ); + t( "ID selector with nonexistent descendant", "#firstp #foobar", [] ); + + t( "ID selector using UTF8", "#台北Táiběi", ["台北Táiběi"] ); + t( "Multiple ID selectors using UTF8", "#台北Táiběi, #台北", ["台北Táiběi","台北"] ); + t( "Descendant ID selector using UTF8", "div #台北", ["台北"] ); + t( "Child ID selector using UTF8", "form > #台北", ["台北"] ); + + t( "Escaped ID", "#foo\\:bar", ["foo:bar"] ); + t( "Escaped ID", "#test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); + t( "Descendant escaped ID", "div #foo\\:bar", ["foo:bar"] ); + t( "Descendant escaped ID", "div #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); + t( "Child escaped ID", "form > #foo\\:bar", ["foo:bar"] ); + t( "Child escaped ID", "form > #test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); + + t( "ID Selector, child ID present", "#form > #radio1", ["radio1"] ); // bug #267 + t( "ID Selector, not an ancestor ID", "#form #first", [] ); + t( "ID Selector, not a child ID", "#form > #option1a", [] ); + + t( "All Children of ID", "#foo > *", ["sndp", "en", "sap"] ); + t( "All Children of ID with no children", "#firstUL > *", [] ); + + t( "ID selector with nonexistent ancestor", "#asdfasdf #foobar", [] ); // bug #986 + + //t( "body div#form", [], "ID selector within the context of another element" ); + + t( "Class Selector", ".blog", ["mark","simon"] ); + t( "Class Selector", ".blog.link", ["simon"] ); + t( "Class Selector w/ Element", "a.blog", ["mark","simon"] ); + t( "Parent Class Selector", "p .blog", ["mark","simon"] ); + + t( "Class selector using UTF8", ".台北Táiběi", ["utf8class1"] ); + t( "Class selector using UTF8", ".台北", ["utf8class1","utf8class2"] ); + t( "Class selector using UTF8", ".台北Táiběi.台北", ["utf8class1"] ); + t( "Class selector using UTF8", ".台北Táiběi, .台北", ["utf8class1","utf8class2"] ); + t( "Descendant class selector using UTF8", "div .台北Táiběi", ["utf8class1"] ); + t( "Child class selector using UTF8", "form > .台北Táiběi", ["utf8class1"] ); + + t( "Escaped Class", ".foo\\:bar", ["foo:bar"] ); + t( "Escaped Class", ".test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); + t( "Descendant scaped Class", "div .foo\\:bar", ["foo:bar"] ); + t( "Descendant scaped Class", "div .test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); + t( "Child escaped Class", "form > .foo\\:bar", ["foo:bar"] ); + t( "Child escaped Class", "form > .test\\.foo\\[5\\]bar", ["test.foo[5]bar"] ); + + t( "Comma Support", "a.blog, p", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + t( "Comma Support", "a.blog , p", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + t( "Comma Support", "a.blog ,p", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + t( "Comma Support", "a.blog,p", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + + t( "Outer Whitespace", " a.blog,p", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + t( "Outer Whitespace", "a.blog,p ", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + t( "Outer Whitespace", " p,a.blog", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + t( "Outer Whitespace", "p,a.blog ", ['firstp','ap','mark','sndp','en','sap','simon','first'] ); + + t( "Child", "p > a", ["simon1","google","groups","mark","yahoo","simon"] ); + t( "Child", "p> a", ["simon1","google","groups","mark","yahoo","simon"] ); + t( "Child", "p >a", ["simon1","google","groups","mark","yahoo","simon"] ); + t( "Child", "p>a", ["simon1","google","groups","mark","yahoo","simon"] ); + t( "Child w/ Class", "p > a.blog", ["mark","simon"] ); + t( "All Children", "code > *", ["anchor1","anchor2"] ); + t( "All Grandchildren", "p > * > *", ["anchor1","anchor2"] ); + t( "Adjacent", "a + a", ["groups"] ); + t( "Adjacent", "a +a", ["groups"] ); + t( "Adjacent", "a+ a", ["groups"] ); + t( "Adjacent", "a+a", ["groups"] ); + t( "Adjacent", "p + p", ["ap","en","sap"] ); + t( "Comma, Child, and Adjacent", "a + a, code > a", ["groups","anchor1","anchor2"] ); + + t( "First Child", "p:first-child", ["firstp","sndp"] ); + t( "Nth Child", "p:nth-child(1)", ["firstp","sndp"] ); + + t( "Last Child", "p:last-child", ["sap"] ); + t( "Last Child", "a:last-child", ["simon1","anchor1","mark","yahoo","anchor2","simon"] ); + + t( "Nth-child", "#main form#form > *:nth-child(2)", ["text2"] ); + t( "Nth-child", "#main form#form > :nth-child(2)", ["text2"] ); + + t( "Nth-child", "#form #select1 option:nth-child(3)", ["option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(0n+3)", ["option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(1n+0)", ["option1a", "option1b", "option1c", "option1d"] ); + t( "Nth-child", "#form #select1 option:nth-child(1n)", ["option1a", "option1b", "option1c", "option1d"] ); + t( "Nth-child", "#form #select1 option:nth-child(n)", ["option1a", "option1b", "option1c", "option1d"] ); + t( "Nth-child", "#form #select1 option:nth-child(even)", ["option1b", "option1d"] ); + t( "Nth-child", "#form #select1 option:nth-child(odd)", ["option1a", "option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(2n)", ["option1b", "option1d"] ); + t( "Nth-child", "#form #select1 option:nth-child(2n+1)", ["option1a", "option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n)", ["option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n+1)", ["option1a", "option1d"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n+2)", ["option1b"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n+3)", ["option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n-1)", ["option1b"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n-2)", ["option1a", "option1d"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n-3)", ["option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(3n+0)", ["option1c"] ); + t( "Nth-child", "#form #select1 option:nth-child(-n+3)", ["option1a", "option1b", "option1c"] ); + + t( "Attribute Exists", "a[title]", ["google"] ); + t( "Attribute Exists", "*[title]", ["google"] ); + t( "Attribute Exists", "[title]", ["google"] ); + + t( "Attribute Equals", "a[rel='bookmark']", ["simon1"] ); + t( "Attribute Equals", 'a[rel="bookmark"]', ["simon1"] ); + t( "Attribute Equals", "a[rel=bookmark]", ["simon1"] ); + t( "Multiple Attribute Equals", "#form input[type='hidden'],#form input[type='radio']", ['radio1','radio2','hidden1'] ); + t( "Multiple Attribute Equals", "#form input[type=\"hidden\"],#form input[type='radio']", ['radio1','radio2','hidden1'] ); + t( "Multiple Attribute Equals", "#form input[type=hidden],#form input[type=radio]", ['radio1','radio2','hidden1'] ); + + t( "Attribute selector using UTF8", "span[lang=中文]", ["台北"] ); + + t( "Attribute Begins With", "a[href ^= 'http://www']", ["google","yahoo"] ); + t( "Attribute Ends With", "a[href $= 'org/']", ["mark"] ); + t( "Attribute Contains", "a[href *= 'google']", ["google","groups"] ); + + // t("Select options via [selected]", "#select1 option[selected]", ["option1a"] ); + t("Select options via [selected]", "#select1 option[selected]", [] ); + t("Select options via [selected]", "#select2 option[selected]", ["option2d"] ); + t("Select options via [selected]", "#select3 option[selected]", ["option3b", "option3c"] ); + + t( "Grouped Form Elements", "input[name='foo[bar]']", ["hidden2"] ); + + t( ":not() Existing attribute", "#form select:not([multiple])", ["select1", "select2"]); + t( ":not() Equals attribute", "#form select:not([name=select1])", ["select2", "select3"]); + t( ":not() Equals quoted attribute", "#form select:not([name='select1'])", ["select2", "select3"]); + + t( "First Child", "p:first-child", ["firstp","sndp"] ); + t( "Last Child", "p:last-child", ["sap"] ); + t( "Only Child", "a:only-child", ["simon1","anchor1","yahoo","anchor2"] ); + t( "Empty", "ul:empty", ["firstUL"] ); + //t( "Enabled UI Element", "#form input:enabled", ["text1","radio1","radio2","check1","check2","hidden2","name"] ); + t( "Disabled UI Element", "#form input:disabled", ["text2"] ); + t( "Checked UI Element", "#form input:checked", ["radio2","check1"] ); + t( "Element Preceded By", "p ~ div", ["foo","fx-queue","fx-tests", "moretests"] ); + t( "Not", "a.blog:not(.link)", ["mark"] ); + } + }; + ]]></script> +</head> +<body id="body" class="unitTest" title="childhood and element type selectors"> +<h1><a href="http://www.w3.org/TR/selectors-api/">Selectors API</a> Test Suite</h1> +<p>Testrunner by <a href="http://ejohn.org/">John Resig</a>, tests by <a href="http://ejohn.org/">John Resig</a>, <a href="http://disruptive-innovations.com/zoo/css3tests/selectorTest.html">Disruptive Innovations</a>, <a href="http://www.w3.org/Style/CSS/Test/CSS3/Selectors/20060307/html/index.html">W3C CSS Working Group</a>, <a href="http://jquery.com/test/">jQuery JavaScript Library</a>.</p> +<div id="root"> + <div class="header"> + <h3>CSS 3 Selectors tests</h3> + <p>(c) <a href="http://www.disruptive-innovations.com">Disruptive Innovations</a> 2008<br/> + Last update: 2008-06-06</p> + </div> + + <div class="test target"> + <div class="unitTest skipWhenToggling" id="target" title=":target selector"></div> + </div> + + <div class="test"> + <div class="blox1 unitTest" title="childhood selector"></div> + </div> + + <div class="test attributeExistence"> + <div class="blox2 unitTest" align="center" title="attribute existence selector"></div> + <div class="blox3 unitTest" align="" title="attribute existence selector with empty string value"></div> + <div class="blox4 unitTest" valign="center" title="attribute existence selector with almost identical attribute"></div> + <div class="blox5 unitTest" alignv="center" title="attribute existence selector with almost identical attribute"></div> + </div> + + <div class="test attributeValue"> + <div class="blox6 unitTest" align="center" title="attribute value selector"></div> + <div class="blox6 unitTest" foo="é" title="attribute value selector with an entity in the attribute and an escaped value in the selector"></div> + <div class="blox6 unitTest" _foo="é" title="attribute value selector with an entity in the attribute, an escaped value in the selector, and a leading underscore in the attribute name"></div> + </div> + + <div class="test attributeSpaceSeparatedValues"> + <div class="blox7 foo unitTest" title="[~=] attribute selector"></div> + <div class="blox8 unitTest" title="[~=] attribute selector looking for empty string"></div> + <div class="blox9 unitTest" foo="" title="[~=] attribute selector looking for empty string in empty attribute"></div> + <div class="blox10 unitTest" foo="foobar" title="[~=] attribute selector looking for 'foo' in 'foobar'"></div> + </div> + + <div class="test attrStart"> + <div class="unitTest t1" title="[^=] attribute selector"></div> + <div class="unitTest t2" title="[^=] attribute selector"></div> + <div class="unitTest t3" align="center" title="[^=] attribute selector looking for empty string"></div> + <div class="unitTest t4" foo="étagada" title="[^=] attribute selector looking for é"></div> + </div> + + <div class="test attrEnd"> + <div class="unitTest t1" title="[$=] attribute selector"></div> + <div class="unitTest t2" title="[$=] attribute selector"></div> + <div class="unitTest t3" align="center" title="[$=] attribute selector looking for empty string"></div> + <div class="unitTest t4" foo="tagadaé" title="[$=] attribute selector looking for é"></div> + </div> + + <div class="test attrMiddle"> + <div class="unitTest t1" title="[*=] attribute selector"></div> + <div class="unitTest t2" title="[*=] attribute selector"></div> + <div class="unitTest t3" align="center" title="[*=] attribute selector looking for empty string"></div> + <div class="unitTest t4" foo="tagadaéfoo" title="[*=] attribute selector looking for é"></div> + </div> + + <div class="test firstChild"> + <div class="unitTest" title=":first-child selector"></div> + <div class="blox12 unitTest" title=":first-child selector should not match non first child"></div> + <div class="blox13 unitTest" title=":first-child selector should not match non first child"></div> + </div> + + <div class="test not"> + <div class="blox14 unitTest" title="negation pseudo-class with argument being an element type selector"></div> + <div class="blox15 unitTest" foo="blox15" title="negation pseudo-class with argument being an attribute selector"></div> + <div class="blox16 unitTest" foo="blox15" title="negation pseudo-class accepts only simple selectors for argument"></div> + </div> + + <div class="test onlyOfType"> + <div class="blox17 unitTest" title=":only-of-type selector"></div> + <p class="blox18 unitTest" title="negated :only-of-type selector"></p> + <p class="blox18 unitTest" title="negated :only-of-type selector"></p> + </div> + + <div class="test nthchild1"> + <div class="unitTest" title=":nth-child(odd) selector"></div> + <div class="unitTest" title=":nth-last-child(odd) selector"></div> + <div class="unitTest" title=":nth-child(odd) selector"></div> + <div class="unitTest" title=":nth-last-child(odd) selector"></div> + <div class="unitTest" title=":nth-child(odd) selector"></div> + <div class="unitTest" title=":nth-last-child(odd) selector"></div> + </div> + <div class="test nthchild2"> + <div class="unitTest" title=":nth-last-child(even) selector"></div> + <div class="unitTest" title=":nth-child(even) selector"></div> + <div class="unitTest" title=":nth-last-child(even) selector"></div> + <div class="unitTest" title=":nth-child(even) selector"></div> + <div class="unitTest" title=":nth-last-child(even) selector"></div> + <div class="unitTest" title=":nth-child(even) selector"></div> + </div> + <div class="test nthchild3"> + <div class="unitTest no" title=":nth-last-child(3n+3) selector"></div> + <div class="unitTest" title=":nth-child(3n+2) selector"></div> + <div class="unitTest no" title=":nth-last-child(3n+1) selector"></div> + <div class="unitTest no" title=":nth-last-child(3n+3) selector"></div> + <div class="unitTest" title=":nth-child(3n+2) selector"></div> + <div class="unitTest no" title=":nth-last-child(3n+1) selector"></div> + </div> + + <div class="test nthoftype1"> + <div class="unitTest" title=":nth-of-type(odd) selector"></div> + <p class="unitTest" title=":nth-* selector"></p> + <p class="unitTest" title=":nth-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(odd) selector"></div> + <p class="unitTest" title=":nth-* selector"></p> + <div class="unitTest" title=":nth-of-type(odd) selector"></div> + <div class="unitTest" title=":nth-last-of-type(odd) selector"></div> + </div> + <div class="test nthoftype2"> + <div class="unitTest" title=":nth-last-of-type(even) selector"></div> + <p class="unitTest" title=":nth-* selector"></p> + <p class="unitTest" title=":nth-* selector"></p> + <div class="unitTest" title=":nth-of-type(even) selector"></div> + <p class="unitTest" title=":nth-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(even) selector"></div> + <div class="unitTest" title=":nth-of-type(even) selector"></div> + </div> + <div class="test nthoftype3"> + <div class="unitTest" title=":nth-of-type(3n+1) selector"></div> + <p class="unitTest" title=":nth-* selector"></p> + <p class="unitTest" title=":nth-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(3n+2) selector"></div> + <p class="unitTest" title=":nth-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(3n+1) selector"></div> + <div class="unitTest" title=":nth-of-type(3n+1) selector"></div> + <p class="unitTest" title=":nth-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(3n+2) selector"></div> + <div class="unitTest" title=":nth-last-of-type(3n+1) selector"></div> + </div> + + <div class="test lastChild"> + <p class="unitTest" title=":not(:last-child) selector"></p> + <div class="unitTest" title=":last-child selector"></div> + </div> + + <div class="test firstOfType"> + <p class="unitTest" title=":first-of-type selector"></p> + <div class="unitTest" title=":first-of-type selector"></div> + <p class="unitTest" title=":not(:first-of-type)"></p> + <div class="unitTest" title=":not(:first-of-type)"></div> + </div> + + <div class="test lastOfType"> + <p class="unitTest" title=":not(:last-of-type)"></p> + <div class="unitTest" title=":not(:last-of-type)"></div> + <p class="unitTest" title=":last-of-type selector"></p> + <div class="unitTest" title=":last-of-type selector"></div> + </div> + + <div class="test onlyChild"> + <div class="unitTest" title=":only-child where the element is NOT the only child"></div> + <div class="unitTest" title=":only-child where the element is the only child"> + <div class="unitTest" title=":only-child where the element is the only child"></div> + </div> + </div> + + <div class="test onlyOfType"> + <p class="unitTest" title=":only-of-type"></p> + <div class="unitTest" title=":only-of-type"> + <div class="unitTest" title=":only-of-type"></div> + </div> + <div class="unitTest" title=":not(only-of-type)"></div> + </div> + + <div class="test empty"> + <div class="unitTest isEmpty" title=":empty with empty element"></div> + <div class="unitTest isNotEmpty" title=":empty but element contains a whitespace"> </div> + <div class="unitTest isEmpty" title=":empty and element contains an SGML comment"><!-- foo --></div> + <div class="unitTest isNotEmpty" title=":empty but element contains a SPAN element"><span></span></div> + <div class="unitTest isNotEmpty" title=":empty but element contains an entity reference"> </div> + </div> + + <div class="test lang"> + <div id="nofragment" class="unitTest" title=":lang() where language comes from the document"></div> + <div class="unitTest" lang="fr" title=":lang() where language comes from the element"></div> + <div class="unitTest" lang="en-US" title=":lang() where language comes from the element but is a dialect of the language queried"></div> + <div class="unitTest t1" lang="es" title=":lang() where language comes from the element but the language queried is a dialect of the element's one so it should not match"></div> + </div> + + <div class="test attrLang"> + <div class="unitTest t1" title="[|=] where language comes from the document"></div> + <div class="unitTest" lang="fr" title="[|=] where language comes from the element"></div> + <div class="unitTest t2" lang="en-US" title="[|=] where language comes from the element but is a dialect of the language queried"></div> + <div class="unitTest t3" lang="es" title="[|=] where language comes from the element but the language queried is a dialect of the element's one so it should not match"></div> + </div> + + <div class="test UI"> + <button name="submit" type="submit" value="submit" class="t1" title=":enabled pseudo-class"><div class="unitTest"></div></button> + <button name="submit" type="submit" value="submit" class="t2" disabled="true" title=":enabled pseudo-class"><div class="unitTest"></div></button> + </div> + <div class="test UI"> + <input class="t3" type="checkbox" checked="true"/><div class="unitTest" title=":checked"></div> + the previous square should be green when the checkbox is checked and become red when you uncheck it + </div> + <div class="test UI"> + <input class="t4" type="checkbox"/><div class="unitTest" title=":not(:checked)"></div> + the previous square should be green when the checkbox is NOT checked and become red when you check it + </div> + + <div class="test tilda"> + <div class="unitTest t1" title="~ combinator"></div> + <div class="unitTest" title="~ combinator"></div> + <div class="unitTest" title="~ combinator"></div> + <div class="unitTest" title="~ combinator"></div> + <span style="float:left">the three last squares should be green and become red when the pointer hovers over the white square</span> + </div> + <div class="test plus"> + <div class="unitTest t1" title="+ combinator"></div> + <div class="unitTest t2" title="+ combinator"></div> + <div class="unitTest" title="+ combinator"></div> + <span style="float:left">the last square should be green and become red when the pointer hovers over the FIRST white square</span> + </div> +</div> +<div id="root2"> + <div class="header"> + <h3>CSS 3 Selectors tests</h3> + <p>(c) <a href="http://www.disruptive-innovations.com">Disruptive Innovations</a> 2008<br/> + Last update: 2008-06-06</p> + </div> + + <div class="test"> + <div class="blox1 unitTest" title="childhood selector"></div> + </div> + + <div class="test attributeExistence"> + <div class="blox2 unitTest" align="center" title="attribute existence selector"></div> + <div class="blox3 unitTest" align="" title="attribute existence selector with empty string value"></div> + <div class="blox4 unitTest" valign="center" title="attribute existence selector with almost identical attribute"></div> + <div class="blox5 unitTest" alignv="center" title="attribute existence selector with almost identical attribute"></div> + </div> + + <div class="test attributeValue"> + <div class="blox6 unitTest" align="center" title="attribute value selector"></div> + <div class="blox6 unitTest" foo="é" title="attribute value selector with an entity in the attribute and an escaped value in the selector"></div> + <div class="blox6 unitTest" _foo="é" title="attribute value selector with an entity in the attribute, an escaped value in the selector, and a leading underscore in the attribute name"></div> + </div> + + <div class="test attributeSpaceSeparatedValues"> + <div class="blox7 foo unitTest" title="[~=] attribute selector"></div> + <div class="blox8 unitTest" title="[~=] attribute selector looking for empty string"></div> + <div class="blox9 unitTest" foo="" title="[~=] attribute selector looking for empty string in empty attribute"></div> + <div class="blox10 unitTest" foo="foobar" title="[~=] attribute selector looking for 'foo' in 'foobar'"></div> + </div> + + <div class="test attrStart"> + <div class="unitTest t1" title="[^=] attribute selector"></div> + <div class="unitTest t2" title="[^=] attribute selector"></div> + <div class="unitTest t3" align="center" title="[^=] attribute selector looking for empty string"></div> + <div class="unitTest t4" foo="étagada" title="[^=] attribute selector looking for é"></div> + </div> + + <div class="test attrEnd"> + <div class="unitTest t1" title="[$=] attribute selector"></div> + <div class="unitTest t2" title="[$=] attribute selector"></div> + <div class="unitTest t3" align="center" title="[$=] attribute selector looking for empty string"></div> + <div class="unitTest t4" foo="tagadaé" title="[$=] attribute selector looking for é"></div> + </div> + + <div class="test attrMiddle"> + <div class="unitTest t1" title="[*=] attribute selector"></div> + <div class="unitTest t2" title="[*=] attribute selector"></div> + <div class="unitTest t3" align="center" title="[*=] attribute selector looking for empty string"></div> + <div class="unitTest t4" foo="tagadaéfoo" title="[*=] attribute selector looking for é"></div> + </div> + + <div class="test firstChild"> + <div class="unitTest" title=":first-child selector"></div> + <div class="blox12 unitTest" title=":first-child selector should not match non first child"></div> + <div class="blox13 unitTest" title=":first-child selector should not match non first child"></div> + </div> + + <div class="test not"> + <div class="blox14 unitTest" title="negation pseudo-class with argument being an element type selector"></div> + <div class="blox15 unitTest" foo="blox15" title="negation pseudo-class with argument being an attribute selector"></div> + <div class="blox16 unitTest" foo="blox15" title="negation pseudo-class accepts only simple selectors for argument"></div> + </div> + + <div class="test onlyOfType"> + <div class="blox17 unitTest" title=":only-of-type selector"></div> + <p class="blox18 unitTest" title="negated :only-of-type selector"></p> + <p class="blox18 unitTest" title="negated :only-of-type selector"></p> + </div> + + <div class="test nthchild1"> + <div class="unitTest" title=":nth-child(odd) selector"></div> + <div class="unitTest" title=":nth-last-child(odd) selector"></div> + <div class="unitTest" title=":nth-child(odd) selector"></div> + <div class="unitTest" title=":nth-last-child(odd) selector"></div> + <div class="unitTest" title=":nth-child(odd) selector"></div> + <div class="unitTest" title=":nth-last-child(odd) selector"></div> + </div> + <div class="test nthchild2"> + <div class="unitTest" title=":nth-last-child(even) selector"></div> + <div class="unitTest" title=":nth-child(even) selector"></div> + <div class="unitTest" title=":nth-last-child(even) selector"></div> + <div class="unitTest" title=":nth-child(even) selector"></div> + <div class="unitTest" title=":nth-last-child(even) selector"></div> + <div class="unitTest" title=":nth-child(even) selector"></div> + </div> + <div class="test nthchild3"> + <div class="unitTest no" title=":nth-last-child(3n+3) selector"></div> + <div class="unitTest" title=":nth-child(3n+2) selector"></div> + <div class="unitTest no" title=":nth-last-child(3n+1) selector"></div> + <div class="unitTest no" title=":nth-last-child(3n+3) selector"></div> + <div class="unitTest" title=":nth-child(3n+2) selector"></div> + <div class="unitTest no" title=":nth-last-child(3n+1) selector"></div> + </div> + + <div class="test nthoftype1"> + <div class="unitTest" title=":nth-of-type(odd) selector"></div> + <p class="unitTest" title=":nth-of-* selector"></p> + <p class="unitTest" title=":nth-of-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(odd) selector"></div> + <p class="unitTest" title=":nth-of-* selector"></p> + <div class="unitTest" title=":nth-of-type(odd) selector"></div> + <div class="unitTest" title=":nth-last-of-type(odd) selector"></div> + </div> + <div class="test nthoftype2"> + <div class="unitTest" title=":nth-last-of-type(even) selector"></div> + <p class="unitTest" title=":nth-of-* selector"></p> + <p class="unitTest" title=":nth-of-* selector"></p> + <div class="unitTest" title=":nth-of-type(even) selector"></div> + <p class="unitTest" title=":nth-of-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(even) selector"></div> + <div class="unitTest" title=":nth-of-type(even) selector"></div> + </div> + <div class="test nthoftype3"> + <div class="unitTest" title=":nth-of-type(3n+1) selector"></div> + <p class="unitTest" title=":nth-of-* selector"></p> + <p class="unitTest" title=":nth-of-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(3n+2) selector"></div> + <p class="unitTest" title=":nth-of-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(3n+1) selector"></div> + <div class="unitTest" title=":nth-of-type(3n+1) selector"></div> + <p class="unitTest" title=":nth-of-* selector"></p> + <div class="unitTest" title=":nth-last-of-type(3n+2) selector"></div> + <div class="unitTest" title=":nth-last-of-type(3n+1) selector"></div> + </div> + + <div class="test lastChild"> + <p class="unitTest" title=":not(:last-child) selector"></p> + <div class="unitTest" title=":last-child selector"></div> + </div> + + <div class="test firstOfType"> + <p class="unitTest" title=":first-of-type selector"></p> + <div class="unitTest" title=":first-of-type selector"></div> + <p class="unitTest" title=":not(:first-of-type)"></p> + <div class="unitTest" title=":not(:first-of-type)"></div> + </div> + + <div class="test lastOfType"> + <p class="unitTest" title=":not(:last-of-type)"></p> + <div class="unitTest" title=":not(:last-of-type)"></div> + <p class="unitTest" title=":last-of-type selector"></p> + <div class="unitTest" title=":last-of-type selector"></div> + </div> + + <div class="test onlyChild"> + <div class="unitTest" title=":only-child where the element is NOT the only child"></div> + <div class="unitTest" title=":only-child where the element is the only child"> + <div class="unitTest" title=":only-child where the element is the only child"></div> + </div> + </div> + + <div class="test onlyOfType"> + <p class="unitTest" title=":only-of-type"></p> + <div class="unitTest" title=":only-of-type"> + <div class="unitTest" title=":only-of-type"></div> + </div> + <div class="unitTest" title=":not(only-of-type)"></div> + </div> + + <div class="test empty"> + <div class="unitTest isEmpty" title=":empty with empty element"></div> + <div class="unitTest isNotEmpty" title=":empty but element contains a whitespace"> </div> + <div class="unitTest isEmpty" title=":empty and element contains an SGML comment"><!-- foo --></div> + <div class="unitTest isNotEmpty" title=":empty but element contains a SPAN element"><span></span></div> + <div class="unitTest isNotEmpty" title=":empty but element contains an entity reference"> </div> + </div> + + <div class="test lang"> + <div id="nofragment" class="unitTest" title=":lang() where language comes from the document"></div> + <div class="unitTest" lang="fr" title=":lang() where language comes from the element"></div> + <div class="unitTest" lang="en-US" title=":lang() where language comes from the element but is a dialect of the language queried"></div> + <div class="unitTest t1" lang="es" title=":lang() where language comes from the element but the language queried is a dialect of the element's one so it should not match"></div> + </div> + + <div class="test attrLang"> + <div class="unitTest t1" title="[|=] where language comes from the document"></div> + <div class="unitTest" lang="fr" title="[|=] where language comes from the element"></div> + <div class="unitTest t2" lang="en-US" title="[|=] where language comes from the element but is a dialect of the language queried"></div> + <div class="unitTest t3" lang="es" title="[|=] where language comes from the element but the language queried is a dialect of the element's one so it should not match"></div> + </div> + + <div class="test UI"> + <button name="submit" type="submit" value="submit" class="t1" title=":enabled pseudo-class"><div class="unitTest"></div></button> + <button name="submit" type="submit" value="submit" class="t2" disabled="true" title=":enabled pseudo-class"><div class="unitTest"></div></button> + </div> + <div class="test UI"> + <input class="t3" type="checkbox" checked="true"/><div class="unitTest" title=":checked"></div> + the previous square should be green when the checkbox is checked and become red when you uncheck it + </div> + <div class="test UI"> + <input class="t4" type="checkbox"/><div class="unitTest" title=":not(:checked)"></div> + the previous square should be green when the checkbox is NOT checked and become red when you check it + </div> + + <div class="test tilda"> + <div class="unitTest t1" title="~ combinator"></div> + <div class="unitTest" title="~ combinator"></div> + <div class="unitTest" title="~ combinator"></div> + <div class="unitTest" title="~ combinator"></div> + <span style="float:left">the three last squares should be green and become red when the pointer hovers over the white square</span> + </div> + <div class="test plus"> + <div class="unitTest t1" title="+ combinator"></div> + <div class="unitTest t2" title="+ combinator"></div> + <div class="unitTest" title="+ combinator"></div> + <span style="float:left">the last square should be green and become red when the pointer hovers over the FIRST white square</span> + </div> +</div> +<div id="root3"> + <div id="svgs"> + <!-- svg elements, but in the xhtml namespace --> + <svg width="12cm" height="4cm" viewBox="0 0 1200 400" version="1.1" id="svg1"> + <desc id="desc1">Example circle01 - circle filled with red and stroked with blue</desc> + <rect id="rect1" x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2"/> + <circle id="circle1" cx="600" cy="200" r="100" fill="red" stroke="blue" stroke-width="10" /> + </svg> + <!-- svg elements using svg: --> + <svg:svg width="12cm" height="4cm" viewBox="0 0 1200 400" version="1.1" id="svg2"> + <svg:desc id="desc2">Example circle01 - circle filled with red and stroked with blue</svg:desc> + <svg:rect id="rect2" x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2"/> + <svg:circle id="circle2" cx="600" cy="200" r="100" fill="red" stroke="blue" stroke-width="10" /> + </svg:svg> + <!-- svg using an inline xmlns --> + <svg width="12cm" height="4cm" viewBox="0 0 1200 400" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg3"> + <desc id="desc3">Example circle01 - circle filled with red and stroked with blue</desc> + <rect id="rect3" x="1" y="1" width="1198" height="398" fill="none" stroke="blue" stroke-width="2"/> + <circle id="circle3" cx="600" cy="200" r="100" fill="red" stroke="blue" stroke-width="10" /> + </svg> + </div> + + <h1 id="header">jQuery Test Suite</h1> + <h2 id="banner"></h2> + <h2 id="userAgent"></h2> + + <!-- Test HTML --> + <div id="nothiddendiv" style="height:1px;background:white;"> + + <div id="nothiddendivchild"></div> + </div> + <!-- Test for scoping --> + <nosuchtag id="outerbogustag"> + <nosuchtag id="innerbogustag"></nosuchtag> + </nosuchtag> + <!-- this iframe is outside the #main so it won't reload constantly wasting time, but it means the tests must be "safe" and clean up after themselves --> + <iframe id="loadediframe" name="loadediframe" style="display:none;" src="data/iframe.html"></iframe> + <dl id="dl" style="display:none;"> + <div id="main" style="display: none;"> + <p id="firstp">See <a id="simon1" href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a> for more information.</p> + + <p id="ap"> + Here are some links in a normal paragraph: <a id="google" href="http://www.google.com/" title="Google!">Google</a>, + <a id="groups" href="http://groups.google.com/">Google Groups</a>. + This link has <code><a href="http://smin" id="anchor1">class="blog"</a></code>: + <a href="http://diveintomark.org/" class="blog" hreflang="en" id="mark">diveintomark</a> + + </p> + <div id="foo"> + + <p id="sndp">Everything inside the red border is inside a div with <code>id="foo"</code>.</p> + <p lang="en" id="en">This is a normal link: <a id="yahoo" href="http://www.yahoo.com/" class="blogTest">Yahoo</a></p> + <p id="sap">This link has <code><a href="#2" id="anchor2">class="blog"</a></code>: <a href="http://simon.incutio.com/" class="blog link" id="simon">Simon Willison's Weblog</a></p> + + </div> + + <p id="first">Try them out:</p> + <ul id="firstUL"></ul> + <ol id="empty"></ol> + <form id="form" action="formaction"> + <input type="text" name="action" value="Test" id="text1" maxlength="30"/> + <input type="text" name="text2" value="Test" id="text2" disabled="disabled"/> + <input type="radio" name="radio1" id="radio1" value="on"/> + + <input type="radio" name="radio2" id="radio2" checked="checked"/> + + <input type="checkbox" name="check" id="check1" checked="checked"/> + <input type="checkbox" id="check2" value="on"/> + + <input type="hidden" name="hidden" id="hidden1"/> + <input type="text" style="display:none;" name="foo[bar]" id="hidden2"/> + + <input type="text" id="name" name="name" value="name" /> + + <button id="button" name="button">Button</button> + + <textarea id="area1" maxlength="30">foobar</textarea> + + + <select name="select1" id="select1"> + <option id="option1a" class="emptyopt" value="">Nothing</option> + <option id="option1b" value="1">1</option> + <option id="option1c" value="2">2</option> + <option id="option1d" value="3">3</option> + </select> + <select name="select2" id="select2"> + + <option id="option2a" class="emptyopt" value="">Nothing</option> + <option id="option2b" value="1">1</option> + <option id="option2c" value="2">2</option> + <option id="option2d" selected="selected" value="3">3</option> + </select> + <select name="select3" id="select3" multiple="multiple"> + <option id="option3a" class="emptyopt" value="">Nothing</option> + + <option id="option3b" selected="selected" value="1">1</option> + <option id="option3c" selected="selected" value="2">2</option> + <option id="option3d" value="3">3</option> + </select> + + <object id="object1" codebase="stupid"> + <param name="p1" value="x1" /> + <param name="p2" value="x2" /> + + </object> + + <span id="台北Táiběi"></span> + <span id="台北" lang="中文"></span> + <span id="utf8class1" class="台北Táiběi 台北"></span> + <span id="utf8class2" class="台北"></span> + <span id="foo:bar" class="foo:bar"></span> + <span id="test.foo[5]bar" class="test.foo[5]bar"></span> + + <foo_bar id="foobar">test element</foo_bar> + + </form> + <b id="floatTest">Float test.</b> + <iframe id="iframe" name="iframe"></iframe> + <form id="lengthtest"> + <input type="text" id="length" name="test"/> + <input type="text" id="idTest" name="id"/> + </form> + <table id="table"></table> + + + <div id="fx-queue"> + <div id="fadein" class='chain test'>fadeIn<div>fadeIn</div></div> + <div id="fadeout" class='chain test out'>fadeOut<div>fadeOut</div></div> + + <div id="show" class='chain test'>show<div>show</div></div> + <div id="hide" class='chain test out'>hide<div>hide</div></div> + + + <div id="togglein" class='chain test'>togglein<div>togglein</div></div> + <div id="toggleout" class='chain test out'>toggleout<div>toggleout</div></div> + + + <div id="slideup" class='chain test'>slideUp<div>slideUp</div></div> + <div id="slidedown" class='chain test out'>slideDown<div>slideDown</div></div> + + <div id="slidetogglein" class='chain test'>slideToggleIn<div>slideToggleIn</div></div> + + <div id="slidetoggleout" class='chain test out'>slideToggleOut<div>slideToggleOut</div></div> + </div> + + <div id="fx-tests"></div> + + <form id="testForm" action="#" method="get"> + <textarea name="T3" rows="2" cols="15">? +Z</textarea> + <input type="hidden" name="H1" value="x" /> + <input type="hidden" name="H2" /> + + <input name="PWD" type="password" value="" /> + <input name="T1" type="text" /> + <input name="T2" type="text" value="YES" readonly="readonly" /> + <input type="checkbox" name="C1" value="1" /> + <input type="checkbox" name="C2" /> + <input type="radio" name="R1" value="1" /> + <input type="radio" name="R1" value="2" /> + <input type="text" name="My Name" value="me" /> + <input type="reset" name="reset" value="NO" /> + + <select name="S1"> + <option value="abc">ABC</option> + <option value="abc">ABC</option> + <option value="abc">ABC</option> + </select> + <select name="S2" multiple="multiple" size="3"> + <option value="abc">ABC</option> + + <option value="abc">ABC</option> + <option value="abc">ABC</option> + </select> + <select name="S3"> + <option selected="selected">YES</option> + </select> + <select name="S4"> + + <option value="" selected="selected">NO</option> + </select> + <input type="submit" name="sub1" value="NO" /> + <input type="submit" name="sub2" value="NO" /> + <input type="image" name="sub3" value="NO" /> + <button name="sub4" type="submit" value="NO">NO</button> + <input name="D1" type="text" value="NO" disabled="disabled" /> + <input type="checkbox" checked="checked" disabled="disabled" name="D2" value="NO" /> + + <input type="radio" name="D3" value="NO" checked="checked" disabled="disabled" /> + <select name="D4" disabled="disabled"> + <option selected="selected" value="NO">NO</option> + </select> + </form> + <div id="moretests"> + <form> + <div id="checkedtest" style="display:none;"> + + <input type="radio" name="checkedtestradios" checked="checked"/> + <input type="radio" name="checkedtestradios" value="on"/> + <input type="checkbox" name="checkedtestcheckboxes" checked="checked"/> + <input type="checkbox" name="checkedtestcheckboxes" /> + </div> + </form> + <div id="nonnodes"><span>hi</span> there <!-- mon ami --></div> + + <div id="t2037"> + <div><div class="hidden">hidden</div></div> + </div> + </div> + </div> + </dl> + + <ol id="tests"></ol> +</div> +<ol id="results"></ol> +</body> +</html> diff --git a/dom/base/test/file_bug426646-1.html b/dom/base/test/file_bug426646-1.html new file mode 100644 index 0000000000..db07734412 --- /dev/null +++ b/dom/base/test/file_bug426646-1.html @@ -0,0 +1,36 @@ +<html><head> +<title>Bug 426646, Using location.replace breaks iframe history</title> +<script type="text/javascript"> +var url1 = "data:text/html;charset=utf-8,1st%20page"; + +function soon(f) { + return function() { setTimeout(f, 0); }; +} + +function doe() { + document.body.innerHTML = "<iframe src='about:blank'></iframe>"; + document.body.innerHTML += "<iframe src='about:blank'></iframe>"; + window.frames[0].frameElement.onload = soon(doe2); + window.frames[0].location.replace(url1); +} + +function doe2() { + window.frames[0].location = 'data:text/html;charset=utf-8,2nd%20page'; + window.frames[0].frameElement.onload = soon(doe3); +} + +function doe3() { + window.frames[0].frameElement.onload = soon(doe4); + history.go(-1); +} + +function doe4() { + opener.is(String(window.frames[0].location), url1, "History.go(-1) didn't work?"); + opener.is(String(window.frames[1].location), "about:blank", + "History.go(-1) didn't work?"); + close(); +} +</script> +</head> +<body onload="doe();" onunload="opener.nextTest();"> +</body></html> diff --git a/dom/base/test/file_bug426646-2.html b/dom/base/test/file_bug426646-2.html new file mode 100644 index 0000000000..1f8fae950c --- /dev/null +++ b/dom/base/test/file_bug426646-2.html @@ -0,0 +1,64 @@ +<html><head> +<title>Bug 426646, Using location.replace breaks iframe history</title> +<script type="text/javascript"> +var url1 = "data:text/html;charset=utf-8,1st%20page"; + +var win0 = null; + +function soon(f) { + return function() { setTimeout(f, 0); }; +} + +function doe() { + document.body.innerHTML = "<iframe src='about:blank'></iframe>"; + document.body.innerHTML += "<iframe src='about:blank'></iframe>"; + win0 = window.frames[0]; + win0.frameElement.onload = soon(doe2); + win0.location.replace(url1); +} + +function doe2() { + // Add some iframes/docshells. Session history should still work. + var ifr1 = document.createElement("iframe"); + document.body.insertBefore(ifr1, document.body.firstChild); + ifr1.onload = soon(doe3); + + var ifr2 = document.createElement("iframe"); + document.body.insertBefore(ifr2, document.body.firstChild); + ifr2.onload = soon(doe3); + + var ifr3 = document.createElement("iframe"); + document.body.insertBefore(ifr3, document.body.firstChild); + ifr3.onload = soon(doe3); +} + +var doe3_count = 0; +function doe3() { + // Wait until all three iframes have loaded about:blank before navigating + // win0. + doe3_count++; + if (doe3_count < 3) { + return; + } + if (doe3_count > 3) { + ok(false, 'Unexpected ' + doe3_count + 'th call to doe3.'); + return; + } + + win0.frameElement.onload = soon(doe4); + win0.location = 'data:text/html;charset=utf-8,2nd%20page'; +} + +function doe4() { + win0.frameElement.onload = soon(doe5); + history.go(-1); +} + +function doe5() { + opener.is(String(win0.location), url1, "History.go(-1) didn't work?"); + close(); +} +</script> +</head> +<body onload="setTimeout(doe, 0);" onunload="opener.nextTest();"> +</body></html> diff --git a/dom/base/test/file_bug428847-1.xhtml b/dom/base/test/file_bug428847-1.xhtml new file mode 100644 index 0000000000..b88701ece2 --- /dev/null +++ b/dom/base/test/file_bug428847-1.xhtml @@ -0,0 +1,4 @@ +<?xml-stylesheet type="text/xsl" href="http://example.com/whatever.xsl"?> +<html xmlns="http://www.w3.org/1999/xhtml"> +<body id='body' onload="if (document.getElementById('body')) parent.iframe1Loaded = true;"/> +</html> diff --git a/dom/base/test/file_bug428847-2.xhtml b/dom/base/test/file_bug428847-2.xhtml new file mode 100644 index 0000000000..75c60b7792 --- /dev/null +++ b/dom/base/test/file_bug428847-2.xhtml @@ -0,0 +1,4 @@ +<?xml-stylesheet type="text/xsl" href=":"?> +<html xmlns="http://www.w3.org/1999/xhtml"> +<body id='body' onload="if (document.getElementById('body')) parent.iframeLoaded = true;"/> +</html> diff --git a/dom/base/test/file_bug498897.css b/dom/base/test/file_bug498897.css new file mode 100644 index 0000000000..84beffdefc --- /dev/null +++ b/dom/base/test/file_bug498897.css @@ -0,0 +1 @@ +body { background: orange; } diff --git a/dom/base/test/file_bug498897.html b/dom/base/test/file_bug498897.html new file mode 100644 index 0000000000..b0d36f4ca5 --- /dev/null +++ b/dom/base/test/file_bug498897.html @@ -0,0 +1,23 @@ +<html> +<head> + <title>Testcase for bug 498897</title> +<script type="application/javascript" language="javascript"> +<!-- +function test() +{ + var hadException = false; + try { + document.createComment('a'); + } + catch (e) { + hadException = true; + } + parent.ok(!hadException, "Shouldn't have got an exception!"); + parent.testFinished(); +} +//--> +</script> +</head> +<body onload="test();"> +</body> +</html> diff --git a/dom/base/test/file_bug498897.html^headers^ b/dom/base/test/file_bug498897.html^headers^ new file mode 100644 index 0000000000..09b46ca4ee --- /dev/null +++ b/dom/base/test/file_bug498897.html^headers^ @@ -0,0 +1 @@ +Link: <file_bug498897.css>; rel=stylesheet diff --git a/dom/base/test/file_bug503473-frame.sjs b/dom/base/test/file_bug503473-frame.sjs new file mode 100644 index 0000000000..5a78292fb4 --- /dev/null +++ b/dom/base/test/file_bug503473-frame.sjs @@ -0,0 +1,23 @@ +function handleRequest(request, response) { + response.processAsync(); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/html; charset=utf-8", false); + response.setHeader("Cache-Control", "no-cache", false); + + response.write( + '<!DOCTYPE html>' + + '<div></div>' + + '<script>' + + 'function doWrite() {' + + ' document.write("<p></p>");' + + ' parent.done();' + + ' document.close();' + + '}' + + 'setTimeout(doWrite, 0);' + + '</script>' + ); + + response.bodyOutputStream.flush(); + // leave the stream open +} + diff --git a/dom/base/test/file_bug503481.sjs b/dom/base/test/file_bug503481.sjs new file mode 100644 index 0000000000..917208b4b3 --- /dev/null +++ b/dom/base/test/file_bug503481.sjs @@ -0,0 +1,43 @@ +// 'timer' is global to avoid getting GCed which would cancel the timer +var timer; +const nsITimer = Components.interfaces.nsITimer; + +function attemptUnblock(s) { + try { + let blockedResponse = null; + getObjectState("bug503481_" + s, function(x) {blockedResponse = x.wrappedJSObject.r}); + blockedResponse.finish(); + setObjectState("bug503481_" + s, null); + } catch(e) { + dump("unable to unblock " + s + "retrying in half a second\n"); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(nsITimer); + timer.initWithCallback(function () { attemptUnblock(s) }, 500, nsITimer.TYPE_ONE_SHOT); + } +} + +function handleRequest(request, response) +{ + var query = {}; + request.queryString.split('&').forEach(function (val) { + var [name, value] = val.split('='); + query[name] = unescape(value); + }); + + dump("processing:" + request.queryString + "\n"); + + if (query.unblock) { + attemptUnblock(query.unblock); + } + + if (query.blockOn) { + response.processAsync(); + x = { r: response, QueryInterface: function(iid) { return this } }; + x.wrappedJSObject = x; + setObjectState("bug503481_" + query.blockOn, x); + } + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/plain", false); + response.write(query.body); +} diff --git a/dom/base/test/file_bug503481b_inner.html b/dom/base/test/file_bug503481b_inner.html new file mode 100644 index 0000000000..6b34bc47b6 --- /dev/null +++ b/dom/base/test/file_bug503481b_inner.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> +<!-- Async script that isn't preloaded --> +<script async src="file_bug503481.sjs?blockOn=R&body=runFirst();"></script> +<script> +firstRan = false; +secondRan = false; +thirdRan = false; +forthRan = false; +function runFirst() { + firstRan = true; +} +function runThird() { + parent.is(forthRan, false, "forth should still be blocked"); + unblock("T"); + thirdRan = true; +} +function runForth() { + forthRan = true; +} + +function done() { + parent.is(firstRan, true, "first should have run by onload"); + parent.is(secondRan, true, "second should have run by onload"); + parent.is(thirdRan, true, "third should have run by onload"); + parent.is(forthRan, true, "forth should have run by onload"); + parent.SimpleTest.finish(); +} + +var reqs = []; +function unblock(s) { + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_bug503481.sjs?unblock=" + s); + xhr.send(); + reqs.push(xhr); +} + + +parent.is(firstRan, false, "First async script shouldn't have run"); +unblock("R"); +</script> + +<!-- test that inline async isn't actually async --> +<script async> +secondRan = true; +</script> +<script> +parent.is(secondRan, true, "Second script shouldn't be async"); +</script> + +<!-- test that setting both defer and async treats the script as async --> +<script defer async src="file_bug503481.sjs?blockOn=S&body=runThird();"></script> +<script> +parent.is(thirdRan, false, "third should not have run yet"); +unblock("S"); +</script> +<script src="file_bug503481.sjs?blockOn=T&body=runForth();"></script> + +</head> + +<body onload="done()"> diff --git a/dom/base/test/file_bug541937.html b/dom/base/test/file_bug541937.html new file mode 100644 index 0000000000..93056754f9 --- /dev/null +++ b/dom/base/test/file_bug541937.html @@ -0,0 +1,7 @@ +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test</title> + <link rel="Top" href=""> foo </link> + +</head><body> + <p>Hello world</p> +</body></html>
\ No newline at end of file diff --git a/dom/base/test/file_bug541937.xhtml b/dom/base/test/file_bug541937.xhtml new file mode 100644 index 0000000000..f4e5f3d320 --- /dev/null +++ b/dom/base/test/file_bug541937.xhtml @@ -0,0 +1,12 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test</title> + <link rel="Top" href=""> foo </link> + +</head> +<body> + <p>Hello world</p> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_bug557892.html b/dom/base/test/file_bug557892.html new file mode 100644 index 0000000000..4b91ddafdd --- /dev/null +++ b/dom/base/test/file_bug557892.html @@ -0,0 +1,25 @@ +<html><head> +<title>Crash [@ nsGenericElement::SetAttr] with classList.toggle</title> +<script> +var classList; +var interval; +function run() { + classList = window.frames[0].document.documentElement.classList; + window.frames[0].location.reload(); + interval = setInterval(function(aClassList) {aClassList.toggle('a'); forcegc();}, 10, classList); + // Let the interval run for awhile and close the window after 2 seconds. + setTimeout(function() { clearInterval(interval); window.opener.done(); window.close(); }, 2000); +} + +function forcegc(){ + SpecialPowers.forceGC(); + SpecialPowers.gc(); +} + + </script> + </head> + <body onload="run()"> + <iframe></iframe> + </body> +</html> + diff --git a/dom/base/test/file_bug562137.txt b/dom/base/test/file_bug562137.txt new file mode 100644 index 0000000000..4a21b817e5 --- /dev/null +++ b/dom/base/test/file_bug562137.txt @@ -0,0 +1 @@ +Ihavenbsp diff --git a/dom/base/test/file_bug590812-ref.xhtml b/dom/base/test/file_bug590812-ref.xhtml new file mode 100644 index 0000000000..dd0948b08a --- /dev/null +++ b/dom/base/test/file_bug590812-ref.xhtml @@ -0,0 +1,3 @@ +<out><div id="top" class="highlight" xmlns="http://www.w3.org/1999/xhtml"><link href="chrome://global/content/xml/XMLPrettyPrint.css" type="text/css" rel="stylesheet"/><div id="header"><p> + This XML file does not appear to have any style information associated with it. The document tree is shown below. + </p></div><div><<span class="start-tag">out</span>><span class="text">Here be sea hags</span></<span class="end-tag">out</span>></div></div></out> diff --git a/dom/base/test/file_bug590812.xml b/dom/base/test/file_bug590812.xml new file mode 100644 index 0000000000..759d5066cf --- /dev/null +++ b/dom/base/test/file_bug590812.xml @@ -0,0 +1 @@ +<out>Here be sea hags</out> diff --git a/dom/base/test/file_bug590870.html b/dom/base/test/file_bug590870.html new file mode 100644 index 0000000000..4432b01d3c --- /dev/null +++ b/dom/base/test/file_bug590870.html @@ -0,0 +1,16 @@ +<html> + <head> + <script> +onload = function() { + var x = null; + try { + x = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "spacer"); + } catch(ex) {} + window.parent.postMessage(x == null, "http://mochi.test:8888"); +} + </script> + </head> + <body> + Here be dragons! + </body> +</html> diff --git a/dom/base/test/file_bug601803a.html b/dom/base/test/file_bug601803a.html new file mode 100644 index 0000000000..c39ff7219e --- /dev/null +++ b/dom/base/test/file_bug601803a.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 601803</title> +<script type="application/javascript"> +function runTest() { + document.domain = "example.org"; + var thrown = false; + try { + document.getElementById("frame").contentDocument.adoptNode(document.createTextNode("foo")); + } + catch (e) { + thrown = true; + } + parent.postMessage(thrown, "*"); +} +</script> +</head> +<body> +<iframe id="frame" src="http://test1.example.org/tests/dom/base/test/file_bug601803b.html" onload="runTest();"></iframe> +</body> +</html> diff --git a/dom/base/test/file_bug601803b.html b/dom/base/test/file_bug601803b.html new file mode 100644 index 0000000000..0363654c06 --- /dev/null +++ b/dom/base/test/file_bug601803b.html @@ -0,0 +1,11 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Bug 601803</title> +</head> +<body> +<script type="application/javascript"> +document.domain = "example.org"; +</script> +</body> +</html> diff --git a/dom/base/test/file_bug604660-1.xml b/dom/base/test/file_bug604660-1.xml new file mode 100644 index 0000000000..231b4357d6 --- /dev/null +++ b/dom/base/test/file_bug604660-1.xml @@ -0,0 +1,3 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/xsl" href="file_bug604660-2.xsl" ?> +<placeholder/> diff --git a/dom/base/test/file_bug604660-2.xsl b/dom/base/test/file_bug604660-2.xsl new file mode 100644 index 0000000000..16611726ce --- /dev/null +++ b/dom/base/test/file_bug604660-2.xsl @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> + <xsl:template match="/"> + <html> + <head> + <title>XSLT script execution test</title> + </head> + <body> + <script defer="" src="data:text/javascript,parent.scriptRan(5);"></script> + <script>parent.scriptRan(1);</script> + <script async="" src="data:text/javascript,parent.asyncRan();"></script> + <script src="file_bug604660-3.js"></script> + <script>parent.scriptRan(3);</script> + <script src="file_bug604660-4.js"></script> + </body> + </html> + </xsl:template> +</xsl:stylesheet> + diff --git a/dom/base/test/file_bug604660-3.js b/dom/base/test/file_bug604660-3.js new file mode 100644 index 0000000000..c11ae68f28 --- /dev/null +++ b/dom/base/test/file_bug604660-3.js @@ -0,0 +1 @@ +parent.scriptRan(2); diff --git a/dom/base/test/file_bug604660-4.js b/dom/base/test/file_bug604660-4.js new file mode 100644 index 0000000000..2bd5b43e5b --- /dev/null +++ b/dom/base/test/file_bug604660-4.js @@ -0,0 +1 @@ +parent.scriptRan(4); diff --git a/dom/base/test/file_bug604660-5.xml b/dom/base/test/file_bug604660-5.xml new file mode 100644 index 0000000000..58c6382836 --- /dev/null +++ b/dom/base/test/file_bug604660-5.xml @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<placeholder/> diff --git a/dom/base/test/file_bug604660-6.xsl b/dom/base/test/file_bug604660-6.xsl new file mode 100644 index 0000000000..4a75777d90 --- /dev/null +++ b/dom/base/test/file_bug604660-6.xsl @@ -0,0 +1,9 @@ +<?xml version="1.0"?> +<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"> + <xsl:template match="/"> + <html> + <script>xsltProcessorCreatedScriptRan();</script> + </html> + </xsl:template> +</xsl:stylesheet> + diff --git a/dom/base/test/file_bug622088.sjs b/dom/base/test/file_bug622088.sjs new file mode 100644 index 0000000000..8619f10b19 --- /dev/null +++ b/dom/base/test/file_bug622088.sjs @@ -0,0 +1,6 @@ +function handleRequest(request, response) +{ + // Echos the referrer back to the requester. + response.setHeader('Content-Type', 'text/plain', false); + response.write(request.getHeader('Referer')); +} diff --git a/dom/base/test/file_bug622088_inner.html b/dom/base/test/file_bug622088_inner.html new file mode 100644 index 0000000000..e89273d89b --- /dev/null +++ b/dom/base/test/file_bug622088_inner.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> +<script> +function load() { + (window.opener || window.parent).innerLoaded(window); +} + +function doXHR(req) { + // Do a sync XHR and return the XHR's referrer. + if (!req) { + req = new XMLHttpRequest(); + } + + // file_bug622088.sjs echos its referrer back to us. We need to refer to it + // using an absolute URI because we sometimes pass in |req| from a window + // which has a data: URI. In that case, a relative path would not get + // resolved properly! + // + // Resolve our relative URI to an absolute one by creating an anchor element + // and reading its href property. + var anchor = document.createElement('a'); + anchor.href = 'file_bug622088.sjs'; + + dump('anchor.href=' + anchor.href + '\n'); + + req.open('GET', anchor.href, false); + req.send(null); + return req.responseText; +} +</script> +</head> + +<body onload='load()'> +<!--Inner frame target for test_bug622088_2.html. --> +</body> + +</html> diff --git a/dom/base/test/file_bug675121.sjs b/dom/base/test/file_bug675121.sjs new file mode 100644 index 0000000000..45ad03d7f6 --- /dev/null +++ b/dom/base/test/file_bug675121.sjs @@ -0,0 +1,15 @@ +var timer; + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/plain", false); + response.write("Responded"); + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() { + response.finish(); + // 50ms certainly be enough for one refresh driver firing to happen! + }, 50, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} diff --git a/dom/base/test/file_bug687859-16.js b/dom/base/test/file_bug687859-16.js Binary files differnew file mode 100644 index 0000000000..58f82cdda3 --- /dev/null +++ b/dom/base/test/file_bug687859-16.js diff --git a/dom/base/test/file_bug687859-16.js^headers^ b/dom/base/test/file_bug687859-16.js^headers^ new file mode 100644 index 0000000000..e0d4fce5d0 --- /dev/null +++ b/dom/base/test/file_bug687859-16.js^headers^ @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=tis-620 diff --git a/dom/base/test/file_bug687859-bom.js b/dom/base/test/file_bug687859-bom.js new file mode 100644 index 0000000000..7536004bb6 --- /dev/null +++ b/dom/base/test/file_bug687859-bom.js @@ -0,0 +1 @@ +var stringFromBomScript = "€"; diff --git a/dom/base/test/file_bug687859-bom.js^headers^ b/dom/base/test/file_bug687859-bom.js^headers^ new file mode 100644 index 0000000000..e0d4fce5d0 --- /dev/null +++ b/dom/base/test/file_bug687859-bom.js^headers^ @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=tis-620 diff --git a/dom/base/test/file_bug687859-charset.js b/dom/base/test/file_bug687859-charset.js new file mode 100644 index 0000000000..e812a1e37f --- /dev/null +++ b/dom/base/test/file_bug687859-charset.js @@ -0,0 +1 @@ +var stringFromCharsetScript = "";
\ No newline at end of file diff --git a/dom/base/test/file_bug687859-http.js b/dom/base/test/file_bug687859-http.js new file mode 100644 index 0000000000..1b1456d480 --- /dev/null +++ b/dom/base/test/file_bug687859-http.js @@ -0,0 +1 @@ +var stringFromHttpScript = ""; diff --git a/dom/base/test/file_bug687859-http.js^headers^ b/dom/base/test/file_bug687859-http.js^headers^ new file mode 100644 index 0000000000..e0d4fce5d0 --- /dev/null +++ b/dom/base/test/file_bug687859-http.js^headers^ @@ -0,0 +1 @@ +Content-Type: text/javascript; charset=tis-620 diff --git a/dom/base/test/file_bug687859-inherit.js b/dom/base/test/file_bug687859-inherit.js new file mode 100644 index 0000000000..b83f60b2fb --- /dev/null +++ b/dom/base/test/file_bug687859-inherit.js @@ -0,0 +1 @@ +var stringFromInheritScript = "";
\ No newline at end of file diff --git a/dom/base/test/file_bug692434.xml b/dom/base/test/file_bug692434.xml new file mode 100644 index 0000000000..2d559c3aed --- /dev/null +++ b/dom/base/test/file_bug692434.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="windows-1251"?><root></root> diff --git a/dom/base/test/file_bug704320_preload_common.js b/dom/base/test/file_bug704320_preload_common.js new file mode 100644 index 0000000000..efae9f4985 --- /dev/null +++ b/dom/base/test/file_bug704320_preload_common.js @@ -0,0 +1,34 @@ +// Common code for the iframes used by bug704320_preload. + +var loadCount = 0; + +// Called by the various onload handlers to indicate that a resource has +// been fully loaded. We require three loads to complete (img, script, +// link) for this test. +function incrementLoad(tag) { + loadCount++; + if (loadCount == 3) { + window.parent.postMessage("childLoadComplete", window.location.origin); + } else if (loadCount > 3) { + document.write("<h1>Too Many Load Events!</h1>"); + window.parent.postMessage("childOverload", window.location.origin); + } +} + +// This is same as incrementLoad, but the caller passes in the loadCount. +function incrementLoad2(tag, expectedLoadCount) { + loadCount++; + if (loadCount == expectedLoadCount) { + window.parent.postMessage("childLoadComplete", window.location.origin); + } else if (loadCount > expectedLoadCount) { + document.write("<h1>Too Many Load Events!</h1>"); + window.parent.postMessage("childOverload", window.location.origin); + } +} + +// in case something fails to load, cause the test to fail. +function postfail(msg) { + window.parent.postMessage("fail-" + msg, window.location.origin); +} + + diff --git a/dom/base/test/file_bug704320_preload_noreuse.html b/dom/base/test/file_bug704320_preload_noreuse.html new file mode 100644 index 0000000000..908240172d --- /dev/null +++ b/dom/base/test/file_bug704320_preload_noreuse.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed. +https://bugzilla.mozilla.org/show_bug.cgi?id=704320 +--> +<head> + <meta charset="utf-8"> + <script type="text/javascript" src="file_bug704320_preload_common.js"></script> + + <script type="text/javascript"> + // mess with parser speculation's choice of referrer policy + document.write("<meta name='referrer' content='origin'>"); + </script> + + <!-- preload happens with full referrer, but real load should happen with origin --> + <script src="/tests/dom/base/test/bug704320_counter.sjs?type=js" + onload="incrementLoad('script');"></script> + + <!-- preload happens with full referrer, but real load should happen with origin --> + <link rel="stylesheet" + href="/tests/dom/base/test/bug704320_counter.sjs?type=css" + onload="incrementLoad('link');"/> + +</head> +<body> + + <!-- preload happens with full referrer, but real load should happen with origin --> +<img src="/tests/dom/base/test/bug704320_counter.sjs?type=img" + onload="incrementLoad('img');" + onerror="postfail('image load caused an error in noreuse test');"/> +</body> +</html> diff --git a/dom/base/test/file_bug704320_preload_reuse.html b/dom/base/test/file_bug704320_preload_reuse.html new file mode 100644 index 0000000000..5643e3d8d6 --- /dev/null +++ b/dom/base/test/file_bug704320_preload_reuse.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed. +https://bugzilla.mozilla.org/show_bug.cgi?id=704320 +--> +<head> + <meta charset="utf-8"> + <meta name="referrer" content="origin"> + <script type="text/javascript" src="file_bug704320_preload_common.js"></script> + <script language="javascript" type="text/javascript"> + // mess with parser speculation -- the loads here MAY be reused because the + // referrer policy did not change. + document.write("<meta name='referrer' content='origin'>"); + </script> + + <script src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=js" + onload="incrementLoad('script');"></script> + + <link rel="stylesheet" + href="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=css" + onload="incrementLoad('link');"/> + +</head> +<body> + +<img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img" + onload="incrementLoad('img');" + onerror="postfail('image load caused an error in reuse test');"/> +</body> +</html> diff --git a/dom/base/test/file_bug704320_redirect.html b/dom/base/test/file_bug704320_redirect.html new file mode 100644 index 0000000000..09ed05d6fd --- /dev/null +++ b/dom/base/test/file_bug704320_redirect.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> + <script> + parent.postMessage('', 'http://mochi.test:8888'); + </script> +</head> +<body> +</body> +</html> diff --git a/dom/base/test/file_bug707142_baseline.json b/dom/base/test/file_bug707142_baseline.json new file mode 100644 index 0000000000..6d95903051 --- /dev/null +++ b/dom/base/test/file_bug707142_baseline.json @@ -0,0 +1 @@ +{"foo": "bar"} diff --git a/dom/base/test/file_bug707142_bom.json b/dom/base/test/file_bug707142_bom.json new file mode 100644 index 0000000000..40852d8ef8 --- /dev/null +++ b/dom/base/test/file_bug707142_bom.json @@ -0,0 +1 @@ +{"foo": "bar"} diff --git a/dom/base/test/file_bug707142_utf-16.json b/dom/base/test/file_bug707142_utf-16.json Binary files differnew file mode 100644 index 0000000000..eb28f6bb7e --- /dev/null +++ b/dom/base/test/file_bug707142_utf-16.json diff --git a/dom/base/test/file_bug708620-2.html b/dom/base/test/file_bug708620-2.html new file mode 100644 index 0000000000..86899201df --- /dev/null +++ b/dom/base/test/file_bug708620-2.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Non-UTF form target</title> +<body onload="parent.finish();"> diff --git a/dom/base/test/file_bug708620.html b/dom/base/test/file_bug708620.html new file mode 100644 index 0000000000..a90e6aeeba --- /dev/null +++ b/dom/base/test/file_bug708620.html @@ -0,0 +1,7 @@ +<!doctype html> +<meta charset=windows-1252> +<title>Non-UTF form</title> +<body onload="document.forms[0].submit();"> +<form action="file_bug708620-2.html"> +<input name=foo value=bar> +</form> diff --git a/dom/base/test/file_bug769117.html b/dom/base/test/file_bug769117.html new file mode 100644 index 0000000000..424f8dff1c --- /dev/null +++ b/dom/base/test/file_bug769117.html @@ -0,0 +1,16 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=769117 + --> + <head> + </head> + <body> + <embed id="testembed" + src="https://mochitest.youtube.com/v/Xm5i5kbIXzc" + type="application/x-shockwave-flash" + allowscriptaccess="always"></embed> + <object id="testobject" + data="https://mochitest.youtube.com/v/Xm5i5kbIXzc"></embed> + </body> +</html> diff --git a/dom/base/test/file_bug782342.txt b/dom/base/test/file_bug782342.txt new file mode 100644 index 0000000000..3b18e512db --- /dev/null +++ b/dom/base/test/file_bug782342.txt @@ -0,0 +1 @@ +hello world diff --git a/dom/base/test/file_bug787778.sjs b/dom/base/test/file_bug787778.sjs new file mode 100644 index 0000000000..84c6744225 --- /dev/null +++ b/dom/base/test/file_bug787778.sjs @@ -0,0 +1,8 @@ +function handleRequest(request, response) +{ + response.processAsync(); + response.setHeader("Content-Type", "text/plain", false); + response.setHeader("X-Frame-Options", "DENY", false); + + response.finish(); +} diff --git a/dom/base/test/file_bug804395.jar b/dom/base/test/file_bug804395.jar Binary files differnew file mode 100644 index 0000000000..f8359f65fa --- /dev/null +++ b/dom/base/test/file_bug804395.jar diff --git a/dom/base/test/file_bug869432.eventsource b/dom/base/test/file_bug869432.eventsource new file mode 100644 index 0000000000..de92d4dd86 --- /dev/null +++ b/dom/base/test/file_bug869432.eventsource @@ -0,0 +1,4 @@ +retry:500 +data: data + + diff --git a/dom/base/test/file_bug869432.eventsource^headers^ b/dom/base/test/file_bug869432.eventsource^headers^ new file mode 100644 index 0000000000..b8db77c582 --- /dev/null +++ b/dom/base/test/file_bug869432.eventsource^headers^ @@ -0,0 +1,3 @@ +HTTP 304 NO CONTENT (CLOSE) +Content-Type: text/event-stream +Cache-Control: no-cache, must-revalidate
\ No newline at end of file diff --git a/dom/base/test/file_bug902350.html b/dom/base/test/file_bug902350.html new file mode 100644 index 0000000000..ce87072f3e --- /dev/null +++ b/dom/base/test/file_bug902350.html @@ -0,0 +1,19 @@ +<DOCTYPE HTML> +<html> +<!-- +Test for Mixed Content Blocker target="_top" frame navigation +https://bugzilla.mozilla.org/show_bug.cgi?id=902350 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 902350</title> +</head> + +<body> + <div id="framediv"> + <iframe src="https://example.com/tests/dom/base/test/file_bug902350_frame.html" id="testing_frame"></iframe> + </div> +</body> +</html> + + diff --git a/dom/base/test/file_bug902350_frame.html b/dom/base/test/file_bug902350_frame.html new file mode 100644 index 0000000000..183dabe255 --- /dev/null +++ b/dom/base/test/file_bug902350_frame.html @@ -0,0 +1,14 @@ +<!DOCTYPE HTML> +<html> +<!-- +Tests for Mixed Content Blocker - Opening link with _top target from an https iframe. +https://bugzilla.mozilla.org/show_bug.cgi?id=902350 +--> +<head> + <meta charset="utf-8"> + <title>Tests for Mixed Content Frame Navigation</title> +</head> +<body> +<a href="http://example.com/" id="topTarget" target="_top">Go to http site</a> +</body> +</html> diff --git a/dom/base/test/file_bug907892.html b/dom/base/test/file_bug907892.html new file mode 100644 index 0000000000..bbd417a167 --- /dev/null +++ b/dom/base/test/file_bug907892.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<script> + var threw; + try { + document.domain = "example.org"; + threw = false; + } catch (e) { + threw = true; + } + var sandboxed = (location.search == "?sandboxed"); + parent.postMessage({ threw: threw, sandboxed: sandboxed }, "*"); +</script> diff --git a/dom/base/test/file_bug945152.jar b/dom/base/test/file_bug945152.jar Binary files differnew file mode 100644 index 0000000000..eb732980d9 --- /dev/null +++ b/dom/base/test/file_bug945152.jar diff --git a/dom/base/test/file_bug945152_worker.js b/dom/base/test/file_bug945152_worker.js new file mode 100644 index 0000000000..bc0d79ba56 --- /dev/null +++ b/dom/base/test/file_bug945152_worker.js @@ -0,0 +1,103 @@ +var gData1 = "TEST_DATA_1:ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +var gData2 = "TEST_DATA_2:1234567890"; +var gPaddingChar = '.'; +var gPaddingSize = 10000; +var gPadding = ""; + +for (var i = 0; i < gPaddingSize; i++) { + gPadding += gPaddingChar; +} + +function ok(a, msg) { + postMessage({type: 'status', status: !!a, msg: msg }); +} + +function is(a, b, msg) { + postMessage({type: 'status', status: a === b, msg: msg }); +} + +function checkData(response, data_head, cb) { + ok(response, "Data is non-null"); + var str = String.fromCharCode.apply(null, new Uint8Array(response)); + ok(str.length == data_head.length + gPaddingSize, "Data size is correct"); + ok(str.slice(0, data_head.length) == data_head, "Data head is correct"); + ok(str.slice(data_head.length) == gPadding, "Data padding is correct"); + cb(); +} + +self.onmessage = function onmessage(event) { + var jar = event.data; + + function makeJarURL(entry) { + return "jar:" + jar + "!/" + entry; + } + + function test_mapped_sync() { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open('GET', makeJarURL('data_1.txt'), false); + xhr.responseType = 'arraybuffer'; + xhr.send(); + if (xhr.status) { + ok(xhr.status == 200, "Status is 200"); + var ct = xhr.getResponseHeader("Content-Type"); + ok(ct.indexOf("mem-mapped") != -1, "Data is memory-mapped"); + checkData(xhr.response, gData1, runTests); + } + } + + function test_mapped_async() { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open('GET', makeJarURL('data_1.txt')); + xhr.responseType = 'arraybuffer'; + xhr.onreadystatechange = function() { + if (xhr.readyState !== xhr.DONE) { + return; + } + if (xhr.status) { + ok(xhr.status == 200, "Status is 200"); + var ct = xhr.getResponseHeader("Content-Type"); + ok(ct.indexOf("mem-mapped") != -1, "Data is memory-mapped"); + checkData(xhr.response, gData1, runTests); + } + } + xhr.send(); + } + + // Make sure array buffer retrieved from compressed file in package is + // handled by memory allocation instead of memory mapping. + function test_non_mapped() { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open('GET', makeJarURL('data_2.txt')); + xhr.responseType = 'arraybuffer'; + xhr.onreadystatechange = function() { + if (xhr.readyState !== xhr.DONE) { + return; + } + if (xhr.status) { + ok(xhr.status == 200, "Status is 200"); + var ct = xhr.getResponseHeader("Content-Type"); + ok(ct.indexOf("mem-mapped") == -1, "Data is not memory-mapped"); + checkData(xhr.response, gData2, runTests); + } + } + xhr.send(); + } + + var tests = [ + test_mapped_sync, + test_mapped_async, + test_non_mapped + ]; + + function runTests() { + if (!tests.length) { + postMessage({type: 'finish' }); + return; + } + + var test = tests.shift(); + test(); + } + + runTests(); +}; diff --git a/dom/base/test/file_change_policy_redirect.html b/dom/base/test/file_change_policy_redirect.html new file mode 100644 index 0000000000..e48386d97c --- /dev/null +++ b/dom/base/test/file_change_policy_redirect.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> +<head> + <script> + parent.postMessage('childLoadComplete', 'http://mochi.test:8888'); + </script> +</head> +<body> +</body> +</html> diff --git a/dom/base/test/file_empty.html b/dom/base/test/file_empty.html new file mode 100644 index 0000000000..495c23ec8a --- /dev/null +++ b/dom/base/test/file_empty.html @@ -0,0 +1 @@ +<!DOCTYPE html><html><body></body></html> diff --git a/dom/base/test/file_explicit_user_agent.sjs b/dom/base/test/file_explicit_user_agent.sjs new file mode 100644 index 0000000000..7a5a595b96 --- /dev/null +++ b/dom/base/test/file_explicit_user_agent.sjs @@ -0,0 +1,8 @@ +function handleRequest(request, response) +{ + if (request.hasHeader("User-Agent")) { + response.setHeader("Result-User-Agent", + request.getHeader("User-Agent")); + } + response.write(""); +} diff --git a/dom/base/test/file_general_document.html b/dom/base/test/file_general_document.html new file mode 100644 index 0000000000..2539669de9 --- /dev/null +++ b/dom/base/test/file_general_document.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<html> +<head> +<meta charset="utf-8"> +<title>General document for testing</title> +</head> +<body> +<p>Hello mochitest!</p> +</body> +</html> diff --git a/dom/base/test/file_htmlserializer_1.html b/dom/base/test/file_htmlserializer_1.html new file mode 100644 index 0000000000..9576b5d7d6 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1.html @@ -0,0 +1,44 @@ +<!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_bodyonly.html b/dom/base/test/file_htmlserializer_1_bodyonly.html new file mode 100644 index 0000000000..848167c62a --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_bodyonly.html @@ -0,0 +1,43 @@ +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_format.html b/dom/base/test/file_htmlserializer_1_format.html new file mode 100644 index 0000000000..09f80467e4 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_format.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + </head> + <body> + <p>Hello world</p> + <p> Lorem ipsum dolor sit amet, <strong>consectetuer</strong> + adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis + ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent + taciti <span>sociosqu ad litora</span> torquent <a + href="file_htmlserializer_1_result1.html">per conubia</a> + nostra, per inceptos hymenaeos. </p> + <ul> + <li>Nam tellus massa,éàèçù</li> + <li> fringilla aliquam,</li> + <li> fermentum sit amet,</li> + <li>posuere ac,</li> + <li> est.</li> + </ul> + <div> Duis tristique egestas ligula. Mauris quis felis. </div> + <script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + <ol> + <li>Fusce a ipsum</li> + <li> non lacus posuere aliquet.</li> + <li> Sed fermentum posuere nulla</li> + <li> Donec tempor.</li> + </ol> + Donec sollicitudin tortor + <!-- test on +comments --> + <pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> + ut gravida eros leo ut libero + <p></p> + <noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> + <p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus + aliquet lectus. Nunc vitae eros. Class aptent taciti</p> + </body> +</html> diff --git a/dom/base/test/file_htmlserializer_1_linebreak.html b/dom/base/test/file_htmlserializer_1_linebreak.html new file mode 100644 index 0000000000..8194b8b415 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_linebreak.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_links.html b/dom/base/test/file_htmlserializer_1_links.html new file mode 100644 index 0000000000..f0864c940c --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_links.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="http://mochi.test:8888/tests/dom/base/test/file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html> diff --git a/dom/base/test/file_htmlserializer_1_nested_body.html b/dom/base/test/file_htmlserializer_1_nested_body.html new file mode 100644 index 0000000000..94f67547e3 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_nested_body.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p><body><p>this is an other body element</p></body></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_no_body.html b/dom/base/test/file_htmlserializer_1_no_body.html new file mode 100644 index 0000000000..9c749721b1 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_no_body.html @@ -0,0 +1,5 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_noflag.html b/dom/base/test/file_htmlserializer_1_noflag.html new file mode 100644 index 0000000000..8194b8b415 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_noflag.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_noformatpre.html b/dom/base/test/file_htmlserializer_1_noformatpre.html new file mode 100644 index 0000000000..aba95b62c8 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_noformatpre.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet. + + Cras quis + + nisi at odio + + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, + +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_raw.html b/dom/base/test/file_htmlserializer_1_raw.html new file mode 100644 index 0000000000..c646f26963 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_raw.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_sibling_body.html b/dom/base/test/file_htmlserializer_1_sibling_body.html new file mode 100644 index 0000000000..f533e6679a --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_sibling_body.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body><p>this is an other body element</p></body><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_sibling_body_only_body.html b/dom/base/test/file_htmlserializer_1_sibling_body_only_body.html new file mode 100644 index 0000000000..97c1625156 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_sibling_body_only_body.html @@ -0,0 +1,43 @@ +<body><p>this is an other body element</p></body><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_1_wrap.html b/dom/base/test/file_htmlserializer_1_wrap.html new file mode 100644 index 0000000000..fc641e3f97 --- /dev/null +++ b/dom/base/test/file_htmlserializer_1_wrap.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="content-type" content="text/html; +charset=UTF-8"> + <title>Test for html serializer</title> + +</head><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu + ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per + conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script type="text/javascript"> +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} + +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum +posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br> + Cras quis<br> + nisi at odio<br> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br> +lacus risus pulvinar ante. +</pre> +ut gravida eros leo ut libero +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc & non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus +aliquet lectus. Nunc vitae eros. Class aptent taciti</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_2.html b/dom/base/test/file_htmlserializer_2.html new file mode 100644 index 0000000000..2156b1610c --- /dev/null +++ b/dom/base/test/file_htmlserializer_2.html @@ -0,0 +1,22 @@ +<!DOCTYPE html><html><head><title>Test for html serializer with entities</title> +</head><body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ +Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø +Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê +ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ ϖ • … ′ ″ ‾ ⁄ ℘ ℑ ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ ⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ ∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ ⌉ ⌊ ⌋ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜       ‌ ‍ ‎ ‏–— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ › € +</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_2_basic.html b/dom/base/test/file_htmlserializer_2_basic.html new file mode 100644 index 0000000000..56ac95dfdd --- /dev/null +++ b/dom/base/test/file_htmlserializer_2_basic.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset="><title>Test for html serializer with entities</title> +</head><body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯ ° ± ² ³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ +Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø +Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê +ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ ϖ • … ′ ″ ‾ ⁄ ℘ ℑ ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ ⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ ∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ ⌉ ⌊ ⌋ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜ –— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ › € +</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_2_enthtml.html b/dom/base/test/file_htmlserializer_2_enthtml.html new file mode 100644 index 0000000000..09bb761e92 --- /dev/null +++ b/dom/base/test/file_htmlserializer_2_enthtml.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset="><title>Test for html serializer with entities</title> +</head><body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ +© ª « ¬ ­ ® ¯ ° ± ² +³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ +¾ ¿ À Á Â Ã Ä Å +Æ +Ç È É Ê Ë Ì Í Î +Ï Ð Ñ Ò Ó Ô Õ Ö × +Ø +Ù Ú Û Ü Ý Þ ß à +á â ã ä å æ ç è +é ê +ë ì í î ï ð ñ ò ó + ô õ ö ÷ ø ù ú û +ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε +Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο +Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε +ζ η θ ι κ λ μ ν ξ ο +π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ +ϖ • … ′ ″ ‾ ⁄ ℘ ℑ +ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ +⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ +∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ +∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ +≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ +⌉ ⌊ ⌋ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜     +  ‌ ‍ ‎ ‏–— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ +› € +</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_2_entw3c.html b/dom/base/test/file_htmlserializer_2_entw3c.html new file mode 100644 index 0000000000..09bb761e92 --- /dev/null +++ b/dom/base/test/file_htmlserializer_2_entw3c.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset="><title>Test for html serializer with entities</title> +</head><body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ +© ª « ¬ ­ ® ¯ ° ± ² +³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ +¾ ¿ À Á Â Ã Ä Å +Æ +Ç È É Ê Ë Ì Í Î +Ï Ð Ñ Ò Ó Ô Õ Ö × +Ø +Ù Ú Û Ü Ý Þ ß à +á â ã ä å æ ç è +é ê +ë ì í î ï ð ñ ò ó + ô õ ö ÷ ø ù ú û +ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε +Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο +Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε +ζ η θ ι κ λ μ ν ξ ο +π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ +ϖ • … ′ ″ ‾ ⁄ ℘ ℑ +ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ +⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ +∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ +∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ +≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ +⌉ ⌊ ⌋ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜     +  ‌ ‍ ‎ ‏–— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ +› € +</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_2_latin1.html b/dom/base/test/file_htmlserializer_2_latin1.html new file mode 100644 index 0000000000..b41e9964fa --- /dev/null +++ b/dom/base/test/file_htmlserializer_2_latin1.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html><head> +<meta http-equiv="content-type" content="text/html; charset="><title>Test for html serializer with entities</title> +</head><body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ +© ª « ¬ ­ ® ¯ ° ± ² +³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ +¾ ¿ À Á Â Ã Ä Å +Æ +Ç È É Ê Ë Ì Í Î +Ï Ð Ñ Ò Ó Ô Õ Ö × +Ø +Ù Ú Û Ü Ý Þ ß à +á â ã ä å æ ç è +é ê +ë ì í î ï ð ñ ò ó + ô õ ö ÷ ø ù ú û +ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ ϖ • … ′ ″ ‾ ⁄ ℘ ℑ ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ ⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ ∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ ⌉ ⌊ ⌋ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜ –— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ › € +</p></body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_ipv6.html b/dom/base/test/file_htmlserializer_ipv6.html new file mode 100644 index 0000000000..298493e718 --- /dev/null +++ b/dom/base/test/file_htmlserializer_ipv6.html @@ -0,0 +1,5 @@ +<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title>Testcase for IPv6 addresses</title> + <body> + <a href="http://[2001:4860:a003::68]/">Test</a> + </body></html>
\ No newline at end of file diff --git a/dom/base/test/file_htmlserializer_ipv6_out.html b/dom/base/test/file_htmlserializer_ipv6_out.html new file mode 100644 index 0000000000..675a406d85 --- /dev/null +++ b/dom/base/test/file_htmlserializer_ipv6_out.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title>Testcase for IPv6 addresses</title> + </head><body> + <a href="http://[2001:4860:a003::68]/">Test</a> + </body></html>
\ No newline at end of file diff --git a/dom/base/test/file_lock_orientation.html b/dom/base/test/file_lock_orientation.html new file mode 100644 index 0000000000..e370ab91c8 --- /dev/null +++ b/dom/base/test/file_lock_orientation.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<body> +<script src="orientationcommon.js"></script> +<script> +window.addEventListener("message", function(event) { + var p = specialPowersLock(event.data); + p.then(function() { + event.source.postMessage("success", "*"); + }).catch(function(err) { + event.source.postMessage("error", "*"); + }); +}, false); +</script> diff --git a/dom/base/test/file_messagemanager_unload.html b/dom/base/test/file_messagemanager_unload.html new file mode 100644 index 0000000000..3df810d502 --- /dev/null +++ b/dom/base/test/file_messagemanager_unload.html @@ -0,0 +1,6 @@ +<!DOCTYPE html> +<html> + <body> + <iframe id="frame" src="about:robots"></iframe> + </body> +</html> diff --git a/dom/base/test/file_mozfiledataurl_audio.ogg b/dom/base/test/file_mozfiledataurl_audio.ogg Binary files differnew file mode 100644 index 0000000000..88b2c1b5b2 --- /dev/null +++ b/dom/base/test/file_mozfiledataurl_audio.ogg diff --git a/dom/base/test/file_mozfiledataurl_doc.html b/dom/base/test/file_mozfiledataurl_doc.html new file mode 100644 index 0000000000..763b20a0f9 --- /dev/null +++ b/dom/base/test/file_mozfiledataurl_doc.html @@ -0,0 +1,6 @@ +<!doctype html> +<html> +<body> +<p>This here is a document!</p> +<img id=img src="file_mozfiledataurl_img.jpg"> +</html> diff --git a/dom/base/test/file_mozfiledataurl_img.jpg b/dom/base/test/file_mozfiledataurl_img.jpg Binary files differnew file mode 100644 index 0000000000..dcd99b9670 --- /dev/null +++ b/dom/base/test/file_mozfiledataurl_img.jpg diff --git a/dom/base/test/file_mozfiledataurl_inner.html b/dom/base/test/file_mozfiledataurl_inner.html new file mode 100644 index 0000000000..960be3d9f9 --- /dev/null +++ b/dom/base/test/file_mozfiledataurl_inner.html @@ -0,0 +1,76 @@ +<!doctype html> +<html> +<script type="application/javascript;version=1.8"> +var img; +var audio; +var iframe; + +addEventListener("message", function(e) { + mess = JSON.parse(e.data); + + if ("img" in mess) + img.src = mess.img; + else if ("audio" in mess) + audio.src = mess.audio + else if ("iframe" in mess) + iframe.src = mess.iframe; + else if ("xhr" in mess) { + let xhr = new XMLHttpRequest(); + xhr.onerror = function() { + sendItUp({ didError: true }); + } + xhr.onload = function() { + sendItUp({ text: xhr.responseText }); + } + try { + xhr.open("GET", mess.xhr); + xhr.send(); + } + catch (ex) { + sendItUp({ didThrow: true }); + } + } + +}, false); + +function sendItUp(obj) { + window.parent.postMessage(JSON.stringify(obj), "*"); +} + +function audioNotifyParent(e) { + sendItUp({ type: e.type }); +} + +function imgNotifyParent(e) { + sendItUp({ type: e.type, + width: e.target.width, + height: e.target.height }); +} + +function iframeNotifyParent(e) { + res = { type: e.type }; + try { + res.text = e.target.contentDocument.getElementsByTagName("p")[0].textContent; + } catch (ex) {} + try { + res.imgWidth = e.target.contentDocument.getElementById("img").width; + } catch (ex) {} + + sendItUp(res); +} + +onload = function() { + img = document.getElementById('img'); + img.onerror = img.onload = imgNotifyParent; + iframe = document.getElementById('iframe'); + iframe.onerror = iframe.onload = iframeNotifyParent; + audio = document.getElementById('audio'); + audio.onerror = audio.onloadeddata = audioNotifyParent; +} + +</script> +<body> +<img id=img> +<audio id=audio> +<iframe id=iframe></iframe> +</html> diff --git a/dom/base/test/file_mozfiledataurl_text.txt b/dom/base/test/file_mozfiledataurl_text.txt new file mode 100644 index 0000000000..315338aa9b --- /dev/null +++ b/dom/base/test/file_mozfiledataurl_text.txt @@ -0,0 +1 @@ +Yarr, here be plaintext file, ya landlubber diff --git a/dom/base/test/file_navigator_resolve_identity_xrays.xul b/dom/base/test/file_navigator_resolve_identity_xrays.xul new file mode 100644 index 0000000000..4b28736376 --- /dev/null +++ b/dom/base/test/file_navigator_resolve_identity_xrays.xul @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=985827 +--> +<window title="Mozilla Bug 985827" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <iframe id="t"></iframe> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 985827 **/ + + addLoadEvent(function() { + var ok = parent.ok; + var is = parent.is; + + var nav = document.getElementById("t").contentWindow.navigator; + + ok(Components.utils.isXrayWrapper(nav), "Should have an Xray here"); + }); + + ]]> + </script> +</window> diff --git a/dom/base/test/file_nonascii_blob_url.html b/dom/base/test/file_nonascii_blob_url.html new file mode 100644 index 0000000000..89183f4613 --- /dev/null +++ b/dom/base/test/file_nonascii_blob_url.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test blob URL for non-ascii domain</title> +</head> +<body> + <p id="result"></p> + <script type="application/javascript"> + +window.onmessage = function(e) { + var blob = new Blob([e.data]); + var url = URL.createObjectURL(blob); + + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, false); + xhr.send(null); + + parent.postMessage(xhr.responseText, '*'); +} + + </script> +</body> +</html> diff --git a/dom/base/test/file_pluginAudio.html b/dom/base/test/file_pluginAudio.html new file mode 100644 index 0000000000..02ef8bd02b --- /dev/null +++ b/dom/base/test/file_pluginAudio.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<embed type="application/x-test" width="200" height="200"></embed> +<script> +var plugin = document.querySelector("embed"); +onload = function() { + plugin.startAudioPlayback(); +}; +function stopAudio() { + plugin.stopAudioPlayback(); +} +function pluginMuted() { + return plugin.audioMuted(); +} +function toggleMuteState(muted) { + var Ci = SpecialPowers.Ci; + var utils = SpecialPowers.wrap(window).top + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + utils.audioMuted = muted; +} +</script> diff --git a/dom/base/test/file_pluginAudioNonAutoStart.html b/dom/base/test/file_pluginAudioNonAutoStart.html new file mode 100644 index 0000000000..5a5c9e0c26 --- /dev/null +++ b/dom/base/test/file_pluginAudioNonAutoStart.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<embed type="application/x-test" width="200" height="200"></embed> +<script> +var plugin = document.querySelector("embed"); + +function startAudio() { + plugin.startAudioPlayback(); +} + +function stopAudio() { + plugin.stopAudioPlayback(); +} + +function pluginMuted() { + return plugin.audioMuted(); +} + +function toggleMuteState(muted) { + var Ci = SpecialPowers.Ci; + var utils = SpecialPowers.wrap(window).top + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + utils.audioMuted = muted; +} +</script> diff --git a/dom/base/test/file_receiveMessage.html b/dom/base/test/file_receiveMessage.html new file mode 100644 index 0000000000..66f421270f --- /dev/null +++ b/dom/base/test/file_receiveMessage.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> + <script> + window.onmessage = event => { + document.body.textContent = `${event.origin}|${event.data}`; + }; + </script> +</head> + +<body></body> +</html> + diff --git a/dom/base/test/file_record_orientation.html b/dom/base/test/file_record_orientation.html new file mode 100644 index 0000000000..a01587507b --- /dev/null +++ b/dom/base/test/file_record_orientation.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<body> +<script> +var recordedOrientations = []; + +screen.orientation.onchange = function() { + recordedOrientations.push(screen.orientation.type); +}; + +window.addEventListener("message", function(event) { + if (event.data == "report") { + event.source.postMessage(recordedOrientations, "*"); + } +}, false); +</script> diff --git a/dom/base/test/file_restrictedEventSource.sjs b/dom/base/test/file_restrictedEventSource.sjs new file mode 100644 index 0000000000..a48eb39008 --- /dev/null +++ b/dom/base/test/file_restrictedEventSource.sjs @@ -0,0 +1,48 @@ +function handleRequest(request, response) +{ + if ((request.queryString == "test=user1_xhr" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAxOnBhc3N3b3JkIDE=") || + (request.queryString == "test=user1_evtsrc" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAxOnBhc3N3b3JkIDE=")) { + response.setStatusLine(null, 200, "OK"); + response.setHeader("Content-Type", "text/event-stream", false); + response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.setHeader("Cache-Control", "no-cache, must-revalidate", false); + if (request.queryString == "test=user1_xhr") { + response.setHeader("Set-Cookie", "test=5c", false); + } + response.write("event: message\ndata: 1\n\n"); + } else if ((request.queryString == "test=user2_xhr" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAyOnBhc3N3b3JkIDI=") || + (request.queryString == "test=user2_evtsrc" && + request.hasHeader("Authorization") && + request.getHeader("Authorization") == "Basic dXNlciAyOnBhc3N3b3JkIDI=" && + request.hasHeader("Cookie") && + request.getHeader("Cookie") == "test=5d")) { + response.setStatusLine(null, 200, "OK"); + response.setHeader("Content-Type", "text/event-stream", false); + response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.setHeader("Cache-Control", "no-cache, must-revalidate", false); + if (request.queryString == "test=user2_xhr") { + response.setHeader("Set-Cookie", "test=5d", false); + } + response.write("event: message\ndata: 1\n\n"); + } else if (request.queryString == "test=user1_xhr" || + request.queryString == "test=user2_xhr") { + response.setStatusLine(null, 401, "Unauthorized"); + response.setHeader("WWW-Authenticate", "basic realm=\"restricted\"", false); + response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.write("Unauthorized"); + } else { + response.setStatusLine(null, 403, "Forbidden"); + response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false); + response.setHeader("Access-Control-Allow-Credentials", "true", false); + response.write("Forbidden"); + } +}
\ No newline at end of file diff --git a/dom/base/test/file_setname.html b/dom/base/test/file_setname.html new file mode 100644 index 0000000000..0830feb53a --- /dev/null +++ b/dom/base/test/file_setname.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> + <head> + <script> + window.name = location.search.substring(1); + </script> + </head> +</html> diff --git a/dom/base/test/file_simplecontentpolicy.js b/dom/base/test/file_simplecontentpolicy.js new file mode 100644 index 0000000000..1f9606c49d --- /dev/null +++ b/dom/base/test/file_simplecontentpolicy.js @@ -0,0 +1,73 @@ +var Ci = Components.interfaces; +var Cc = Components.classes; +var Cr = Components.results; + +Components.utils.import("resource://gre/modules/Services.jsm"); +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +function executeSoon(f) +{ + Services.tm.mainThread.dispatch(f, Ci.nsIThread.DISPATCH_NORMAL); +} + +var urlSuffix = "/this/is/the/test/url"; + +// Content policy / factory implementation for the test +var policyID = Components.ID("{6aadacff-f1f2-46f4-a6db-6d429f884a30}"); +var policyName = "@mozilla.org/simpletestpolicy;1"; +var policy = { + // nsISupports implementation + QueryInterface: + XPCOMUtils.generateQI([ + Ci.nsISupports, + Ci.nsIFactory, + Ci.nsISimpleContentPolicy]), + + // nsIFactory implementation + createInstance: function(outer, iid) { + return this.QueryInterface(iid); + }, + + // nsIContentPolicy implementation + shouldLoad: function(contentType, + contentLocation, + requestOrigin, + frame, + isTopLevel, + mimeTypeGuess, + extra) + { + // Remember last content type seen for the test url + if (contentLocation.spec.endsWith(urlSuffix)) { + assert.ok(frame === browserElement, "correct <browser> element"); + sendAsyncMessage("shouldLoad", {contentType: contentType, isTopLevel: isTopLevel}); + return Ci.nsIContentPolicy.REJECT_REQUEST; + } + + return Ci.nsIContentPolicy.ACCEPT; + }, + + shouldProcess: function() { + return Ci.nsIContentPolicy.ACCEPT; + } +} + +// Register content policy +var componentManager = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); +componentManager.registerFactory(policyID, "Test simple content policy", policyName, policy); + +var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager); +categoryManager.addCategoryEntry("simple-content-policy", policyName, policyName, false, true); + +addMessageListener("finished", () => { + // Unregister content policy + categoryManager.deleteCategoryEntry("simple-content-policy", policyName, false); + + executeSoon(function() { + // Component must be unregistered delayed, otherwise other content + // policy will not be removed from the category correctly + componentManager.unregisterFactory(policyID, policy); + }); +}); + +sendAsyncMessage("ready"); diff --git a/dom/base/test/file_timer_flood.html b/dom/base/test/file_timer_flood.html new file mode 100644 index 0000000000..dc729d7e42 --- /dev/null +++ b/dom/base/test/file_timer_flood.html @@ -0,0 +1,19 @@ +<!DOCTYPE HTML> +<html> +<body> +<script> +let count = 0; +function cb() { + count += 1; + // Notify our parent that we are ready once the timer flood has + // warmed up. + if (count === 10000) { + window.parent.postMessage('STARTED', '*'); + } + setTimeout(cb, 0); + setTimeout(cb, 0); +} +addEventListener('load', cb); +</script> +</body> +</html> diff --git a/dom/base/test/file_use_counter_outer.html b/dom/base/test/file_use_counter_outer.html new file mode 100644 index 0000000000..1a7eb90f7c --- /dev/null +++ b/dom/base/test/file_use_counter_outer.html @@ -0,0 +1,17 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=968923 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 968923</title> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=968923">Mozilla Bug 968923</a> +<img id="display" /> +<iframe id="content"> + +</iframe> +</body> +</html> diff --git a/dom/base/test/file_use_counter_svg_currentScale.svg b/dom/base/test/file_use_counter_svg_currentScale.svg new file mode 100644 index 0000000000..ea9721a599 --- /dev/null +++ b/dom/base/test/file_use_counter_svg_currentScale.svg @@ -0,0 +1,17 @@ +<?xml version="1.0" standalone="no"?> + +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="4in" height="3in" version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <desc>Test graphic for hitting currentScale + </desc> + <script type="text/javascript"> <![CDATA[ + document.documentElement.currentScale = document.documentElement.currentScale; + ]]> + </script> + <image id="i1" x="200" y="200" width="100px" height="80px"> + </image> + <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/> +</svg> diff --git a/dom/base/test/file_use_counter_svg_fill_pattern.svg b/dom/base/test/file_use_counter_svg_fill_pattern.svg new file mode 100644 index 0000000000..ec8059a3d4 --- /dev/null +++ b/dom/base/test/file_use_counter_svg_fill_pattern.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1" + xmlns="http://www.w3.org/2000/svg"> + <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc> + <!-- Outline the drawing area in blue --> + <rect fill="none" stroke="blue" + x="1" y="1" width="798" height="398"/> + + <!-- The ellipse is filled using a triangle pattern paint server + and stroked with black --> + <ellipse fill="url(http://example.com/browser/dom/base/test/file_use_counter_svg_fill_pattern_definition.svg#TrianglePattern)" stroke="black" stroke-width="5" + cx="400" cy="200" rx="350" ry="150" /> +</svg> diff --git a/dom/base/test/file_use_counter_svg_fill_pattern_data.svg b/dom/base/test/file_use_counter_svg_fill_pattern_data.svg new file mode 100644 index 0000000000..21f4753148 --- /dev/null +++ b/dom/base/test/file_use_counter_svg_fill_pattern_data.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1" + xmlns="http://www.w3.org/2000/svg"> + <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc> + <!-- Outline the drawing area in blue --> + <rect fill="none" stroke="blue" + x="1" y="1" width="798" height="398"/> + + <!-- The ellipse is filled using a triangle pattern paint server + and stroked with black --> + <ellipse fill="url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iIAogICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPgo8c3ZnIHdpZHRoPSI4Y20iIGhlaWdodD0iNGNtIiB2aWV3Qm94PSIwIDAgODAwIDQwMCIgdmVyc2lvbj0iMS4xIgogICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPGRlc2M+Qm9ycm93ZWQgZnJvbSBodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcvcHNlcnZlcnMuaHRtbDwvZGVzYz4KICA8ZGVmcz4KICAgIDxwYXR0ZXJuIGlkPSJUcmlhbmdsZVBhdHRlcm4iIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiCiAgICAgICAgICAgICB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIKICAgICAgICAgICAgIHZpZXdCb3g9IjAgMCAxMCAxMCIgPgogICAgICA8cGF0aCBkPSJNIDAgMCBMIDcgMCBMIDMuNSA3IHoiIGZpbGw9InJlZCIgZmlsbC1vcGFjaXR5PSIwLjciIHN0cm9rZT0iYmx1ZSIgLz4KICAgIDwvcGF0dGVybj4gCiAgPC9kZWZzPgo8L3N2Zz4K#TrianglePattern)" stroke="black" stroke-width="5" + cx="400" cy="200" rx="350" ry="150" /> +</svg> diff --git a/dom/base/test/file_use_counter_svg_fill_pattern_definition.svg b/dom/base/test/file_use_counter_svg_fill_pattern_definition.svg new file mode 100644 index 0000000000..ffc2f1bed2 --- /dev/null +++ b/dom/base/test/file_use_counter_svg_fill_pattern_definition.svg @@ -0,0 +1,14 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1" + xmlns="http://www.w3.org/2000/svg"> + <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc> + <defs> + <pattern id="TrianglePattern" patternUnits="userSpaceOnUse" + x="0" y="0" width="100" height="100" + viewBox="0 0 10 10" > + <path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" fill-opacity="0.7" stroke="blue" /> + </pattern> + </defs> +</svg> diff --git a/dom/base/test/file_use_counter_svg_fill_pattern_internal.svg b/dom/base/test/file_use_counter_svg_fill_pattern_internal.svg new file mode 100644 index 0000000000..3b0670cd0b --- /dev/null +++ b/dom/base/test/file_use_counter_svg_fill_pattern_internal.svg @@ -0,0 +1,23 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="8cm" height="4cm" viewBox="0 0 800 400" version="1.1" + xmlns="http://www.w3.org/2000/svg"> + <desc>Borrowed from http://www.w3.org/TR/SVG/pservers.html</desc> + <!-- Outline the drawing area in blue --> + <rect fill="none" stroke="blue" + x="1" y="1" width="798" height="398"/> + + <defs> + <pattern id="TrianglePattern" patternUnits="userSpaceOnUse" + x="0" y="0" width="100" height="100" + viewBox="0 0 10 10" > + <path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" fill-opacity="0.7" stroke="blue" /> + </pattern> + </defs> + + <!-- The ellipse is filled using a triangle pattern paint server + and stroked with black --> + <ellipse fill="url(#TrianglePattern)" stroke="black" stroke-width="5" + cx="400" cy="200" rx="350" ry="150" /> +</svg> diff --git a/dom/base/test/file_use_counter_svg_getElementById.svg b/dom/base/test/file_use_counter_svg_getElementById.svg new file mode 100644 index 0000000000..3393f43752 --- /dev/null +++ b/dom/base/test/file_use_counter_svg_getElementById.svg @@ -0,0 +1,22 @@ +<?xml version="1.0" standalone="no"?> + +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg width="4in" height="3in" version="1.1" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <desc>Test graphic for hitting getElementById + </desc> + <image id="i1" x="200" y="200" width="100px" height="80px"> + </image> + <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/> + <script type="text/javascript"> <![CDATA[ + var image = document.documentElement.getElementById("i1"); + image.addEventListener("load", + function() { + document.documentElement.removeAttribute("class"); + }, + false); + ]]> + </script> +</svg> diff --git a/dom/base/test/file_webaudioLoop.html b/dom/base/test/file_webaudioLoop.html new file mode 100644 index 0000000000..c255bc5414 --- /dev/null +++ b/dom/base/test/file_webaudioLoop.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<script> +var ac = new AudioContext(); +var runningPromise = new Promise(resolve => { + ac.onstatechange = event => { + if (ac.state == "running") { + resolve(); + } + }; +}); +fetch("audio.ogg").then(response => { + return response.arrayBuffer(); +}).then(ab => { + return ac.decodeAudioData(ab); +}).then(ab => { + var src = ac.createBufferSource(); + src.buffer = ab; + src.loop = true; + src.loopStart = 0; + src.loopEnd = ab.duration; + src.start(); + src.connect(ac.destination); +}); + +var suspendPromise; +function suspendAC() { + runningPromise.then(() => { + suspendPromise = ac.suspend(); + }); +} + +var resumePromise; +function resumeAC() { + suspendPromise.then(() => { + resumePromise = ac.resume(); + }); +} + +function closeAC() { + resumePromise.then(() => { + ac.close(); + }); +} +</script> diff --git a/dom/base/test/file_webaudioLoop2.html b/dom/base/test/file_webaudioLoop2.html new file mode 100644 index 0000000000..8453a436d1 --- /dev/null +++ b/dom/base/test/file_webaudioLoop2.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<script> +var ac = new AudioContext(); +fetch("audio.ogg").then(response => { + return response.arrayBuffer(); +}).then(ab => { + return ac.decodeAudioData(ab); +}).then(ab => { + var src = ac.createBufferSource(); + src.buffer = ab; + src.loop = true; + src.start(); + src.connect(ac.destination); +}); +</script> diff --git a/dom/base/test/file_websocket_basic_wsh.py b/dom/base/test/file_websocket_basic_wsh.py new file mode 100644 index 0000000000..498e278435 --- /dev/null +++ b/dom/base/test/file_websocket_basic_wsh.py @@ -0,0 +1,29 @@ +from mod_pywebsocket import msgutil + +def web_socket_do_extra_handshake(request): + # must set request.ws_protocol to the selected version from ws_requested_protocols + request.ws_protocol = request.ws_requested_protocols[0] + + if (request.ws_protocol == 'error'): + raise ValueError('Error') + pass + +def web_socket_transfer_data(request): + while True: + line = msgutil.receive_message(request) + if line == 'protocol': + msgutil.send_message(request, request.ws_protocol) + continue + + if line == 'resource': + msgutil.send_message(request, request.ws_resource) + continue + + if line == 'origin': + msgutil.send_message(request, request.ws_origin) + continue + + msgutil.send_message(request, line) + + if line == 'end': + return diff --git a/dom/base/test/file_websocket_hello_wsh.py b/dom/base/test/file_websocket_hello_wsh.py new file mode 100644 index 0000000000..9f75754391 --- /dev/null +++ b/dom/base/test/file_websocket_hello_wsh.py @@ -0,0 +1,10 @@ +from mod_pywebsocket import msgutil + +def web_socket_do_extra_handshake(request): + pass + +def web_socket_transfer_data(request): + resp = "Test" + if msgutil.receive_message(request) == "data": + resp = "Hello world!" + msgutil.send_message(request, resp) diff --git a/dom/base/test/file_websocket_http_resource.txt b/dom/base/test/file_websocket_http_resource.txt new file mode 100644 index 0000000000..35dc67f08d --- /dev/null +++ b/dom/base/test/file_websocket_http_resource.txt @@ -0,0 +1 @@ +server data diff --git a/dom/base/test/file_websocket_permessage_deflate_disabled_wsh.py b/dom/base/test/file_websocket_permessage_deflate_disabled_wsh.py new file mode 100644 index 0000000000..98dedcd0cf --- /dev/null +++ b/dom/base/test/file_websocket_permessage_deflate_disabled_wsh.py @@ -0,0 +1,17 @@ +from mod_pywebsocket import msgutil +from mod_pywebsocket import common + +def web_socket_do_extra_handshake(request): + if request.ws_requested_extensions is not None: + for extension_request in request.ws_requested_extensions: + if extension_request.name() == "permessage-deflate": + raise ValueError('permessage-deflate should not be offered') + +def web_socket_transfer_data(request): + while True: + rcvd = msgutil.receive_message(request) + opcode = request.ws_stream.get_last_received_opcode() + if (opcode == common.OPCODE_BINARY): + msgutil.send_message(request, rcvd, binary=True) + elif (opcode == common.OPCODE_TEXT): + msgutil.send_message(request, rcvd) diff --git a/dom/base/test/file_websocket_permessage_deflate_params_wsh.py b/dom/base/test/file_websocket_permessage_deflate_params_wsh.py new file mode 100644 index 0000000000..36169f4c28 --- /dev/null +++ b/dom/base/test/file_websocket_permessage_deflate_params_wsh.py @@ -0,0 +1,23 @@ +from mod_pywebsocket import msgutil +from mod_pywebsocket import common + +def web_socket_do_extra_handshake(request): + deflate_found = False + + if request.ws_extension_processors is not None: + for extension_processor in request.ws_extension_processors: + if extension_processor.name() == "deflate": + extension_processor.set_client_no_context_takeover(True) + deflate_found = True + + if deflate_found is False: + raise ValueError('deflate extension processor not found') + +def web_socket_transfer_data(request): + while True: + rcvd = msgutil.receive_message(request) + opcode = request.ws_stream.get_last_received_opcode() + if (opcode == common.OPCODE_BINARY): + msgutil.send_message(request, rcvd, binary=True) + elif (opcode == common.OPCODE_TEXT): + msgutil.send_message(request, rcvd) diff --git a/dom/base/test/file_websocket_permessage_deflate_rejected_wsh.py b/dom/base/test/file_websocket_permessage_deflate_rejected_wsh.py new file mode 100644 index 0000000000..b21da97cde --- /dev/null +++ b/dom/base/test/file_websocket_permessage_deflate_rejected_wsh.py @@ -0,0 +1,23 @@ +from mod_pywebsocket import msgutil +from mod_pywebsocket import common + +def web_socket_do_extra_handshake(request): + deflate_removed = False + + if request.ws_extension_processors is not None: + for extension_processor in request.ws_extension_processors: + if extension_processor.name() == "deflate": + request.ws_extension_processors.remove(extension_processor) + deflate_removed = True + + if deflate_removed is False: + raise ValueError('deflate extension processor not found') + +def web_socket_transfer_data(request): + while True: + rcvd = msgutil.receive_message(request) + opcode = request.ws_stream.get_last_received_opcode() + if (opcode == common.OPCODE_BINARY): + msgutil.send_message(request, rcvd, binary=True) + elif (opcode == common.OPCODE_TEXT): + msgutil.send_message(request, rcvd) diff --git a/dom/base/test/file_websocket_permessage_deflate_wsh.py b/dom/base/test/file_websocket_permessage_deflate_wsh.py new file mode 100644 index 0000000000..65752dee11 --- /dev/null +++ b/dom/base/test/file_websocket_permessage_deflate_wsh.py @@ -0,0 +1,22 @@ +from mod_pywebsocket import msgutil +from mod_pywebsocket import common + +def web_socket_do_extra_handshake(request): + pmce_offered = False + + if request.ws_requested_extensions is not None: + for extension_request in request.ws_requested_extensions: + if extension_request.name() == "permessage-deflate": + pmce_offered = True + + if pmce_offered is False: + raise ValueError('permessage-deflate not offered') + +def web_socket_transfer_data(request): + while True: + rcvd = msgutil.receive_message(request) + opcode = request.ws_stream.get_last_received_opcode() + if (opcode == common.OPCODE_BINARY): + msgutil.send_message(request, rcvd, binary=True) + elif (opcode == common.OPCODE_TEXT): + msgutil.send_message(request, rcvd) diff --git a/dom/base/test/file_websocket_wsh.py b/dom/base/test/file_websocket_wsh.py new file mode 100644 index 0000000000..ef440580ef --- /dev/null +++ b/dom/base/test/file_websocket_wsh.py @@ -0,0 +1,159 @@ +from mod_pywebsocket import msgutil + +import time +import sys +import struct + +# see the list of tests in test_websocket.html + +def web_socket_do_extra_handshake(request): + # must set request.ws_protocol to the selected version from ws_requested_protocols + for x in request.ws_requested_protocols: + if x != "test-does-not-exist": + request.ws_protocol = x + break + + if request.ws_protocol == "test-2.1": + time.sleep(3) + elif request.ws_protocol == "test-9": + time.sleep(3) + elif request.ws_protocol == "test-10": + time.sleep(3) + elif request.ws_protocol == "test-19": + raise ValueError('Aborting (test-19)') + elif request.ws_protocol == "test-20" or request.ws_protocol == "test-17": + time.sleep(3) + elif request.ws_protocol == "test-22": + # The timeout is 5 seconds + time.sleep(13) + elif request.ws_protocol == "test-41b": + request.sts = "max-age=100" + else: + pass + +# Behave according to recommendation of RFC 6455, section # 5.5.1: +# "When sending a Close frame in response, the endpoint typically echos the +# status code it received." +# - Without this, pywebsocket replies with 1000 to any close code. +# +# Note that this function is only called when the client initiates the close +def web_socket_passive_closing_handshake(request): + if request.ws_close_code == 1005: + return None, None + else: + return request.ws_close_code, request.ws_close_reason + + +def web_socket_transfer_data(request): + if request.ws_protocol == "test-2.1" or request.ws_protocol == "test-2.2": + msgutil.close_connection(request) + elif request.ws_protocol == "test-6": + resp = "wrong message" + if msgutil.receive_message(request) == "1": + resp = "2" + msgutil.send_message(request, resp.decode('utf-8')) + resp = "wrong message" + if msgutil.receive_message(request) == "3": + resp = "4" + msgutil.send_message(request, resp.decode('utf-8')) + resp = "wrong message" + if msgutil.receive_message(request) == "5": + resp = "あいうえお" + msgutil.send_message(request, resp.decode('utf-8')) + msgutil.close_connection(request) + elif request.ws_protocol == "test-7": + msgutil.send_message(request, "test-7 data") + elif request.ws_protocol == "test-10": + msgutil.close_connection(request) + elif request.ws_protocol == "test-11": + resp = "wrong message" + if msgutil.receive_message(request) == "client data": + resp = "server data" + msgutil.send_message(request, resp.decode('utf-8')) + elif request.ws_protocol == "test-12": + msg = msgutil.receive_message(request) + if msg == u'a\ufffdb': + # converted unpaired surrogate in UTF-16 to UTF-8 OK + msgutil.send_message(request, "SUCCESS") + else: + msgutil.send_message(request, "FAIL got '" + msg + + "' instead of string with replacement char'") + elif request.ws_protocol == "test-13": + # first one binary message containing the byte 0x61 ('a') + request.connection.write('\xff\x01\x61') + # after a bad utf8 message + request.connection.write('\x01\x61\xff') + msgutil.close_connection(request) + elif request.ws_protocol == "test-14": + msgutil.close_connection(request) + msgutil.send_message(request, "server data") + elif request.ws_protocol == "test-15": + # DISABLED: close_connection hasn't supported 2nd 'abort' argument for a + # long time. Passing extra arg was causing exception, which conveniently + # caused abort :) but as of pywebsocket v606 raising an exception here no + # longer aborts, and there's no obvious way to close TCP connection w/o + # sending websocket CLOSE. + raise RuntimeError("test-15 should be disabled for now") + #msgutil.close_connection(request, True) # OBSOLETE 2nd arg + return + elif request.ws_protocol == "test-17" or request.ws_protocol == "test-21": + time.sleep(2) + resp = "wrong message" + if msgutil.receive_message(request) == "client data": + resp = "server data" + msgutil.send_message(request, resp.decode('utf-8')) + time.sleep(2) + msgutil.close_connection(request) + elif request.ws_protocol == "test-20": + msgutil.send_message(request, "server data") + msgutil.close_connection(request) + elif request.ws_protocol == "test-34": + request.ws_stream.close_connection(1001, "going away now") + elif request.ws_protocol == "test-35a": + while not request.client_terminated: + msgutil.receive_message(request) + global test35code + test35code = request.ws_close_code + global test35reason + test35reason = request.ws_close_reason + elif request.ws_protocol == "test-35b": + request.ws_stream.close_connection(test35code + 1, test35reason) + elif request.ws_protocol == "test-37b": + while not request.client_terminated: + msgutil.receive_message(request) + global test37code + test37code = request.ws_close_code + global test37reason + test37reason = request.ws_close_reason + elif request.ws_protocol == "test-37c": + request.ws_stream.close_connection(test37code, test37reason) + elif request.ws_protocol == "test-42": + # Echo back 3 messages + msgutil.send_message(request, + msgutil.receive_message(request)) + msgutil.send_message(request, + msgutil.receive_message(request)) + msgutil.send_message(request, + msgutil.receive_message(request)) + elif request.ws_protocol == "test-44": + rcv = msgutil.receive_message(request) + # check we received correct binary msg + if len(rcv) == 3 \ + and ord(rcv[0]) == 5 and ord(rcv[1]) == 0 and ord(rcv[2]) == 7: + # reply with binary msg 0x04 + msgutil.send_message(request, struct.pack("cc", chr(0), chr(4)), True, True) + else: + msgutil.send_message(request, "incorrect binary msg received!") + elif request.ws_protocol == "test-45": + rcv = msgutil.receive_message(request) + # check we received correct binary msg + if rcv == "flob": + # send back same blob as binary msg + msgutil.send_message(request, rcv, True, True) + else: + msgutil.send_message(request, "incorrect binary msg received: '" + rcv + "'") + elif request.ws_protocol == "test-46": + msgutil.send_message(request, "client must drop this if close was called") + + while not request.client_terminated: + msgutil.receive_message(request) diff --git a/dom/base/test/file_x-frame-options_main.html b/dom/base/test/file_x-frame-options_main.html new file mode 100644 index 0000000000..63a918b992 --- /dev/null +++ b/dom/base/test/file_x-frame-options_main.html @@ -0,0 +1,44 @@ +<html> +<head> +<title>X-Frame-Options tests</title> +<script type="text/javascript"> +// This frame loading means all subframes have either loaded or errored out. We +// can now tell the test harness to check each subframe for the expected result. +window.addEventListener('load', parent.testFramesLoaded, false); +</script> +</head> +<body> + +<iframe id="control1" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=control1"></iframe><br> +<iframe id="control2" src="http://example.com/tests/dom/base/test/file_x-frame-options_page.sjs?testid=control2"></iframe><br> +<iframe id="deny" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny"></iframe><br> +<iframe id="sameorigin1" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin1&xfo=sameorigin"></iframe><br> +<iframe id="sameorigin2" src="http://example.com/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin2&xfo=sameorigin"></iframe><br> +<iframe id="sameorigin5" src="http://example.com/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin5&xfo=sameorigin2"></iframe><br> +<iframe id="sameorigin6" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin6&xfo=sameorigin2"></iframe><br> +<iframe id="sameorigin7" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin7&xfo=sameorigin3"></iframe><br> +<iframe id="sameorigin8" src="http://example.com/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin8&xfo=sameorigin3"></iframe><br> +<iframe id="mixedpolicy" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=mixedpolicy&xfo=mixedpolicy"></iframe><br> +<iframe id="allow-from-allow" src="http://example.com/tests/dom/base/test/file_x-frame-options_page.sjs?testid=allow-from-allow&xfo=afa"></iframe><br> +<iframe id="allow-from-deny" src="http://example.com/tests/dom/base/test/file_x-frame-options_page.sjs?testid=allow-from-deny&xfo=afd"></iframe><br> +<iframe id="sameorigin-multipart" src="http://example.com/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin-multipart&xfo=sameorigin&multipart=1"></iframe><br> +<iframe id="sameorigin-multipart2" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin-multipart2&xfo=sameorigin&multipart=1"></iframe><br> + +<!-- added for bug 836132 --> +<script type="text/javascript"> + + function addFrame(test, xfo) { + var baseurl = "http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs"; + var ifr = "<iframe id='" + test + "'" + "src='" + baseurl + "?testid=" + test + "&xfo=" + xfo + "' style='border:2px solid red;'></iframe>"; + document.write(ifr); + } + + addFrame("allow-from-allow-1", "afa1"); + for (var i = 1; i<=14; i++) + addFrame("allow-from-deny-"+i, "afd"+i); + +</script> + + +</body> +</html> diff --git a/dom/base/test/file_x-frame-options_page.sjs b/dom/base/test/file_x-frame-options_page.sjs new file mode 100644 index 0000000000..24ebbe1a89 --- /dev/null +++ b/dom/base/test/file_x-frame-options_page.sjs @@ -0,0 +1,60 @@ +// SJS file for X-Frame-Options mochitests +function handleRequest(request, response) +{ + var query = {}; + var BOUNDARY = "BOUNDARYOMG3984"; + request.queryString.split('&').forEach(function (val) { + var [name, value] = val.split('='); + query[name] = unescape(value); + }); + + if (query['multipart'] == "1") { + response.setHeader("Content-Type", "multipart/x-mixed-replace;boundary=" + BOUNDARY, false); + response.setHeader("Cache-Control", "no-cache", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write("--" + BOUNDARY + "\r\n"); + response.write("Content-Type: text/html\r\n\r\n"); + } else { + response.setHeader("Content-Type", "text/html", false); + response.setHeader("Cache-Control", "no-cache", false); + } + + var testHeaders = { + "deny": "DENY", + "sameorigin": "SAMEORIGIN", + "sameorigin2": "SAMEORIGIN, SAMEORIGIN", + "sameorigin3": "SAMEORIGIN,SAMEORIGIN , SAMEORIGIN", + "mixedpolicy": "DENY,SAMEORIGIN", + + /* added for bug 836132 */ + "afa": "ALLOW-FROM http://mochi.test:8888/", + "afd": "ALLOW-FROM http://example.com/", + "afa1": "ALLOW-FROM http://mochi.test:8888", + "afd1": "ALLOW-FROM:example.com", + "afd2": "ALLOW-FROM: example.com", + "afd3": "ALLOW-FROM example.com", + "afd4": "ALLOW-FROM:http://example.com", + "afd5": "ALLOW-FROM: http://example.com", + "afd6": "ALLOW-FROM http://example.com", + "afd7": "ALLOW-FROM:mochi.test:8888", + "afd8": "ALLOW-FROM: mochi.test:8888", + "afd9": "ALLOW-FROM:http://mochi.test:8888", + "afd10": "ALLOW-FROM: http://mochi.test:8888", + "afd11": "ALLOW-FROM mochi.test:8888", + "afd12": "ALLOW-FROM", + "afd13": "ALLOW-FROM ", + "afd14": "ALLOW-FROM:" + }; + + if (testHeaders.hasOwnProperty(query['xfo'])) { + response.setHeader("X-Frame-Options", testHeaders[query['xfo']], false); + } + + // from the test harness we'll be checking for the presence of this element + // to test if the page loaded + response.write("<h1 id=\"test\">" + query["testid"] + "</h1>"); + + if (query['multipart'] == "1") { + response.write("\r\n--" + BOUNDARY + "\r\n"); + } +} diff --git a/dom/base/test/file_xhtmlserializer_1.xhtml b/dom/base/test/file_xhtmlserializer_1.xhtml new file mode 100644 index 0000000000..64271ce2ce --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1.xhtml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html> diff --git a/dom/base/test/file_xhtmlserializer_1_bodyonly.xhtml b/dom/base/test/file_xhtmlserializer_1_bodyonly.xhtml new file mode 100644 index 0000000000..fbefe91d6e --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_bodyonly.xhtml @@ -0,0 +1,56 @@ +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_format.xhtml b/dom/base/test/file_xhtmlserializer_1_format.xhtml new file mode 100644 index 0000000000..d62cc367ba --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_format.xhtml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + </head> + <body> + <p>Hello world</p> + <p> Lorem ipsum dolor sit amet, <strong>consectetuer</strong> + adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis + ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent + taciti <span>sociosqu ad litora</span> torquent <a + href="file_htmlserializer_1_result1.html">per conubia</a> + nostra, per inceptos hymenaeos. </p> + <ul> + <li>Nam tellus massa,éàèçù</li> + <li> fringilla aliquam,</li> + <li> fermentum sit amet,</li> + <li>posuere ac,</li> + <li> est.</li> + </ul> + <div> Duis tristique egestas ligula. Mauris quis felis. </div> + <script id="script" type="text/javascript"></script> + <script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + <ol> + <li>Fusce a ipsum</li> + <li> non lacus posuere aliquet.</li> + <li> Sed fermentum posuere nulla</li> + <li> Donec tempor.</li> + </ol> + Donec sollicitudin tortor + <!-- test on +comments --> + <pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> + ut gravida eros <br /> + leo ut libero + <!-- empty element: end tag should be generated for backward compatibility with HTML --> + <p></p> + <noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> + <p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus + aliquet lectus. Nunc vitae eros. Class aptent taciti</p> + <pre xmlns="http://mozilla.org/ns/foo">lacinia + <em>libero</em> ullamcorper laoreet.<br/> Cras quis<br/> nisi at + odio<br/> consectetuer molestie. Curabitur consectetuer urna a + sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in + faucibus orci luctus et ultrices posuere cubilia Curae; Sed + sollicitudin, nulla at pharetra rutrum, + <br/> + lacus risus pulvinar ante. + </pre> + </body> +</html> diff --git a/dom/base/test/file_xhtmlserializer_1_linebreak.xhtml b/dom/base/test/file_xhtmlserializer_1_linebreak.xhtml new file mode 100644 index 0000000000..a0aecdd2c6 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_linebreak.xhtml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_links.xhtml b/dom/base/test/file_xhtmlserializer_1_links.xhtml new file mode 100644 index 0000000000..0c2814311b --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_links.xhtml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="http://mochi.test:8888/tests/dom/base/test/file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html> diff --git a/dom/base/test/file_xhtmlserializer_1_nested_body.xhtml b/dom/base/test/file_xhtmlserializer_1_nested_body.xhtml new file mode 100644 index 0000000000..120f8e7dcb --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_nested_body.xhtml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +<body><p>this is an other body element</p></body></body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_no_body.xhtml b/dom/base/test/file_xhtmlserializer_1_no_body.xhtml new file mode 100644 index 0000000000..6f5055bd57 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_no_body.xhtml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> + +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_noflag.xhtml b/dom/base/test/file_xhtmlserializer_1_noflag.xhtml new file mode 100644 index 0000000000..a0aecdd2c6 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_noflag.xhtml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_noformatpre.xhtml b/dom/base/test/file_xhtmlserializer_1_noformatpre.xhtml new file mode 100644 index 0000000000..a5eb6e9692 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_noformatpre.xhtml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet. + + Cras quis + + nisi at odio + + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, + +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_raw.xhtml b/dom/base/test/file_xhtmlserializer_1_raw.xhtml new file mode 100644 index 0000000000..d13fce2ccd --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_raw.xhtml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_sibling_body.xhtml b/dom/base/test/file_xhtmlserializer_1_sibling_body.xhtml new file mode 100644 index 0000000000..9ef4840e36 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_sibling_body.xhtml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body><p>this is an other body element</p></body><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_sibling_body_only_body.xhtml b/dom/base/test/file_xhtmlserializer_1_sibling_body_only_body.xhtml new file mode 100644 index 0000000000..f9f92a0670 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_sibling_body_only_body.xhtml @@ -0,0 +1,56 @@ +<body><p>this is an other body element</p></body><body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_1_wrap.xhtml b/dom/base/test/file_xhtmlserializer_1_wrap.xhtml new file mode 100644 index 0000000000..6b156278ad --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_1_wrap.xhtml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> + <title>Test for html serializer</title> + +</head> +<body> +<p>Hello world</p> <p> + + Lorem ipsum dolor sit amet, <strong>consectetuer</strong> +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti <span>sociosqu + ad + litora</span> torquent <a href="file_htmlserializer_1_result1.html">per + conubia</a> +nostra, per inceptos hymenaeos. </p> + + +<ul><li>Nam tellus massa,éàèçù</li><li> + fringilla +aliquam,</li><li> fermentum sit amet,</li><li>posuere ac,</li><li> est.</li></ul> +<div> Duis tristique egestas ligula. Mauris quis felis. </div> +<script id="script" type="text/javascript"></script> +<script type="text/javascript"> +//<![CDATA[ +// a script which does nothing + +function nothing() { + var hey="hello"; + var aLongLine="consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere"; +} +var a=3, b=4, c=7; +// here we test the non-serialization of xml character into javascript content +var d = a < b && a > c; +//]]> +</script> + +<ol><li>Fusce + a ipsum</li><li> non lacus posuere aliquet.</li><li> Sed fermentum +posuere nulla</li><li> Donec tempor.</li></ol> +Donec sollicitudin tortor +<!-- test on +comments --> +<pre>lacinia <em>libero</em> ullamcorper laoreet.<br /> + Cras quis<br /> + nisi at odio<br /> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at pharetra rutrum, <br /> +lacus risus pulvinar ante. +</pre> +ut gravida eros <br />leo ut libero +<!-- empty element: end tag should be generated for backward compatibility with HTML --> +<p></p> +<noscript> +<p>Curabitur consectetuer urna a sem. Nunc non urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci luctus</p></noscript> +<p>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus +aliquet lectus. Nunc vitae eros. Class aptent taciti</p> +<pre xmlns="http://mozilla.org/ns/foo">lacinia <em>libero</em> +ullamcorper laoreet.<br/> + Cras quis<br/> + nisi at odio<br/> + consectetuer molestie. Curabitur consectetuer urna a sem. Nunc non +urna. Cras in massa. Vestibulum ante ipsum primis in faucibus orci +luctus et ultrices posuere cubilia Curae; Sed sollicitudin, nulla at +pharetra rutrum, <br/> +lacus risus pulvinar ante. +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_2.xhtml b/dom/base/test/file_xhtmlserializer_2.xhtml new file mode 100644 index 0000000000..2a9c55b95d --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_2.xhtml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Test for html serializer with entities</title> +</head> +<body> + +<p>The basic set is just " " & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯ ° ± ² ³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ +Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø +Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê +ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ ϖ • … ′ ″ ‾ ⁄ ℘ ℑ ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ ⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ ∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ ⌉ ⌊ ⌋ ⟨ ⟩ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜       ‌ ‍ ‎ ‏–— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ › € +</p> + +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_2_basic.xhtml b/dom/base/test/file_xhtmlserializer_2_basic.xhtml new file mode 100644 index 0000000000..c35cc48cf8 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_2_basic.xhtml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="content-type" content="text/html; charset=" /> + <title>Test for html serializer with entities</title> +</head> +<body> + +<p>The basic set is just " " & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯ ° ± ² ³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿ À Á Â Ã Ä Å Æ +Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø +Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê +ë ì í î ï ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ ϖ • … ′ ″ ‾ ⁄ ℘ ℑ ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ ⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ ∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ ⌉ ⌊ ⌋ ⟨ ⟩ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜ –— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ › € +</p> + +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_2_enthtml.xhtml b/dom/base/test/file_xhtmlserializer_2_enthtml.xhtml new file mode 100644 index 0000000000..0ba1c8421c --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_2_enthtml.xhtml @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="content-type" content="text/html; charset=" /> + <title>Test for html serializer with entities</title> +</head> +<body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ +© ª « ¬ ­ ® ¯ ° ± ² +³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ +¾ ¿ À Á Â Ã Ä Å +Æ +Ç È É Ê Ë Ì Í Î +Ï Ð Ñ Ò Ó Ô Õ Ö × +Ø +Ù Ú Û Ü Ý Þ ß à +á â ã ä å æ ç è +é ê +ë ì í î ï ð ñ ò ó + ô õ ö ÷ ø ù ú û +ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε +Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο +Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε +ζ η θ ι κ λ μ ν ξ ο +π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ +ϖ • … ′ ″ ‾ ⁄ ℘ ℑ +ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ +⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ +∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ +∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ +≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ +⌉ ⌊ ⌋ ⟨ ⟩ ◊ ♠ ♣ ♥ +♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜     +  ‌ ‍ ‎ ‏–— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ +› € +</p> + +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_2_entw3c.xhtml b/dom/base/test/file_xhtmlserializer_2_entw3c.xhtml new file mode 100644 index 0000000000..0ba1c8421c --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_2_entw3c.xhtml @@ -0,0 +1,55 @@ +<?xml version="1.0"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="content-type" content="text/html; charset=" /> + <title>Test for html serializer with entities</title> +</head> +<body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ +© ª « ¬ ­ ® ¯ ° ± ² +³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ +¾ ¿ À Á Â Ã Ä Å +Æ +Ç È É Ê Ë Ì Í Î +Ï Ð Ñ Ò Ó Ô Õ Ö × +Ø +Ù Ú Û Ü Ý Þ ß à +á â ã ä å æ ç è +é ê +ë ì í î ï ð ñ ò ó + ô õ ö ÷ ø ù ú û +ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε +Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο +Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε +ζ η θ ι κ λ μ ν ξ ο +π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ +ϖ • … ′ ″ ‾ ⁄ ℘ ℑ +ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ +⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ +∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ +∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ +≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ +⌉ ⌊ ⌋ ⟨ ⟩ ◊ ♠ ♣ ♥ +♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜     +  ‌ ‍ ‎ ‏–— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ +› € +</p> + +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_xhtmlserializer_2_latin1.xhtml b/dom/base/test/file_xhtmlserializer_2_latin1.xhtml new file mode 100644 index 0000000000..59b564ca77 --- /dev/null +++ b/dom/base/test/file_xhtmlserializer_2_latin1.xhtml @@ -0,0 +1,41 @@ +<?xml version="1.0"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="content-type" content="text/html; charset=" /> + <title>Test for html serializer with entities</title> +</head> +<body> + +<p>The basic set is just & < > " for interoperability with older products that don't support α and friends.</p> + +<p>latin1 ¡ ¢ £ ¤ ¥ ¦ § ¨ +© ª « ¬ ­ ® ¯ ° ± ² +³ ´ +µ ¶ · ¸ ¹ º » ¼ ½ +¾ ¿ À Á Â Ã Ä Å +Æ +Ç È É Ê Ë Ì Í Î +Ï Ð Ñ Ò Ó Ô Õ Ö × +Ø +Ù Ú Û Ü Ý Þ ß à +á â ã ä å æ ç è +é ê +ë ì í î ï ð ñ ò ó + ô õ ö ÷ ø ù ú û +ü ý +þ ÿ </p> +<p>symbols, math.. ƒ Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ +Φ Χ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς +σ τ υ φ χ ψ ω ϑ ϒ ϖ • … ′ ″ ‾ ⁄ ℘ ℑ ℜ +™ ℵ ← ↑ → ↓ ↔ ↵ ⇐ ⇑ ⇒ ⇓ ⇔ ∀ ∂ ∃ ∅ ∇ ∈ ∉ +∋ ∏ ∑ − ∗ √ ∝ ∞ ∠ ∧ ∨ ∩ ∪ ∫ ∴ ∼ ≅ ≈ ≠ ≡ ≤ ≥ +⊂ ⊃ ⊄ ⊆ ⊇ ⊕ ⊗ ⊥ ⋅ ⌈ ⌉ ⌊ ⌋ ⟨ ⟩ ◊ ♠ ♣ ♥ ♦ +</p> +<p> others +Œ œ Š š Ÿ ˆ ˜ –— ‘ ’ +‚“ ” „ † ‡ ‰ ‹ › € +</p> + +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/file_youtube_flash_embed.html b/dom/base/test/file_youtube_flash_embed.html new file mode 100644 index 0000000000..47bf52edeb --- /dev/null +++ b/dom/base/test/file_youtube_flash_embed.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=1240471 + --> + <head> + <meta charset="utf-8"> + <title>Test for Bug 1240471</title> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + let SimpleTest = { + finish: function() { + parent.postMessage(JSON.stringify({fn: "finish"}), "*"); + } + }; + ["ok", "is", "info"].forEach(fn => { + self[fn] = function (...args) { + parent.postMessage(JSON.stringify({fn: fn, args: args}), "*"); + } + }); + "use strict"; + function onLoad() { + let youtube_changed_url_query = "https://mochitest.youtube.com/embed/Xm5i5kbIXzc?start=10&end=20"; + + function testEmbed(embed, expected_url, expected_fullscreen) { + ok (!!embed, "Embed node exists"); + // getSVGDocument will return HTMLDocument if the content is HTML + let doc = embed.getSVGDocument(); + // doc must be unprivileged because privileged doc will always be + // allowed to use fullscreen. + is (doc.fullscreenEnabled, expected_fullscreen, + "fullscreen should be " + (expected_fullscreen ? "enabled" : "disabled")); + embed = SpecialPowers.wrap(embed); + is (embed.srcURI.spec, expected_url, "Should have src uri of " + expected_url); + } + info("Running youtube rewrite query test"); + testEmbed(document.getElementById("testembed-correct"), youtube_changed_url_query, false); + testEmbed(document.getElementById("testembed-correct-fs"), youtube_changed_url_query, true); + testEmbed(document.getElementById("testembed-wrong"), youtube_changed_url_query, false); + testEmbed(document.getElementById("testembed-whywouldyouevendothat"), youtube_changed_url_query, true); + SimpleTest.finish(); + } + </script> + </head> + <body onload="onLoad()"> + <embed id="testembed-correct" + src="https://mochitest.youtube.com/v/Xm5i5kbIXzc?start=10&end=20" + type="application/x-shockwave-flash" + allowscriptaccess="always"></embed> + <embed id="testembed-correct-fs" + src="https://mochitest.youtube.com/v/Xm5i5kbIXzc?start=10&end=20" + type="application/x-shockwave-flash" + allowfullscreen + allowscriptaccess="always"></embed> + <embed id="testembed-wrong" + src="https://mochitest.youtube.com/v/Xm5i5kbIXzc&start=10&end=20" + type="application/x-shockwave-flash" + allowscriptaccess="always"></embed> + <embed id="testembed-whywouldyouevendothat" + src="https://mochitest.youtube.com/v/Xm5i5kbIXzc&start=10?end=20" + type="application/x-shockwave-flash" + allowfullscreen + allowscriptaccess="always"></embed> + </body> +</html> diff --git a/dom/base/test/fileapi_chromeScript.js b/dom/base/test/fileapi_chromeScript.js new file mode 100644 index 0000000000..614b556edb --- /dev/null +++ b/dom/base/test/fileapi_chromeScript.js @@ -0,0 +1,29 @@ +var { classes: Cc, interfaces: Ci, utils: Cu } = Components; +Cu.importGlobalProperties(["File"]); + +var fileNum = 1; + +function createFileWithData(fileData) { + var willDelete = fileData === null; + var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); + var testFile = dirSvc.get("ProfD", Ci.nsIFile); + testFile.append("fileAPItestfile" + fileNum); + fileNum++; + var outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); + outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate + 0o666, 0); + if (willDelete) { + fileData = "some irrelevant test data\n"; + } + outStream.write(fileData, fileData.length); + outStream.close(); + var domFile = File.createFromNsIFile(testFile); + if (willDelete) { + testFile.remove(/* recursive: */ false); + } + return domFile; +} + +addMessageListener("files.open", function (message) { + sendAsyncMessage("files.opened", message.map(createFileWithData)); +}); diff --git a/dom/base/test/fileutils.js b/dom/base/test/fileutils.js new file mode 100644 index 0000000000..8a6a7334a5 --- /dev/null +++ b/dom/base/test/fileutils.js @@ -0,0 +1,254 @@ +// Utility functions +var testRanCounter = 0; +var expectedTestCount = 0; + +function testHasRun() { + //alert(testRanCounter); + ++testRanCounter; + if (testRanCounter == expectedTestCount) { + SimpleTest.finish(); + } +} + + +function testFile(file, contents, test) { + SimpleTest.requestLongerTimeout(2); + + // Load file using FileReader + var r = new FileReader(); + r.onload = getFileReaderLoadHandler(contents, contents.length, "FileReader.readAsBinaryString of " + test); + r.readAsBinaryString(file); + expectedTestCount++; + + // Load file using URL.createObjectURL and XMLHttpRequest + var xhr = new XMLHttpRequest; + xhr.open("GET", URL.createObjectURL(file)); + xhr.onload = getXHRLoadHandler(contents, contents.length, + "XMLHttpRequest load of " + test); + xhr.overrideMimeType('text/plain; charset=x-user-defined'); + xhr.send(); + expectedTestCount++; + + // Send file to server using FormData and XMLHttpRequest + xhr = new XMLHttpRequest(); + xhr.onload = function(event) { + checkMPSubmission(JSON.parse(event.target.responseText), + [{ name: "hello", value: "world"}, + { name: "myfile", + value: contents, + fileName: file.name || "blob", + contentType: file.type || "application/octet-stream" }]); + testHasRun(); + } + xhr.open("POST", "../../../dom/html/test/form_submit_server.sjs"); + var fd = new FormData; + fd.append("hello", "world"); + fd.append("myfile", file); + xhr.send(fd); + expectedTestCount++; + + // Send file to server using plain XMLHttpRequest + var xhr = new XMLHttpRequest; + xhr.open("POST", "../../../dom/xhr/tests/file_XHRSendData.sjs"); + xhr.onload = function (event) { + is(event.target.getResponseHeader("Result-Content-Type"), + file.type ? file.type : null, + "request content-type in XMLHttpRequest send of " + test); + is(event.target.getResponseHeader("Result-Content-Length"), + String(file.size), + "request content-length in XMLHttpRequest send of " + test); + }; + xhr.addEventListener("load", + getXHRLoadHandler(contents, contents.length, + "XMLHttpRequest send of " + test), + false); + xhr.overrideMimeType('text/plain; charset=x-user-defined'); + xhr.send(file); + expectedTestCount++; +} + +function getFileReaderLoadHandler(expectedResult, expectedLength, testName) { + return function (event) { + is(event.target.readyState, FileReader.DONE, + "[FileReader] readyState in test " + testName); + is(event.target.error, null, + "[FileReader] no error in test " + testName); + // Do not use |is(event.target.result, expectedResult, "...");| that may output raw binary data. + is(event.target.result.length, expectedResult.length, + "[FileReader] Length of result in test " + testName); + ok(event.target.result == expectedResult, + "[FileReader] Content of result in test " + testName); + is(event.lengthComputable, true, + "[FileReader] lengthComputable in test " + testName); + is(event.loaded, expectedLength, + "[FileReader] Loaded length in test " + testName); + is(event.total, expectedLength, + "[FileReader] Total length in test " + testName); + testHasRun(); + } +} + +function getXHRLoadHandler(expectedResult, expectedLength, testName) { + return function (event) { + is(event.target.readyState, 4, + "[XHR] readyState in test " + testName); + is(event.target.status, 200, + "[XHR] no error in test " + testName); + // Do not use |is(convertXHRBinary(event.target.responseText), expectedResult, "...");| that may output raw binary data. + var convertedData = convertXHRBinary(event.target.responseText); + is(convertedData.length, expectedResult.length, + "[XHR] Length of result in test " + testName); + ok(convertedData == expectedResult, + "[XHR] Content of result in test " + testName); + is(event.lengthComputable, event.total != 0, + "[XHR] lengthComputable in test " + testName); + is(event.loaded, expectedLength, + "[XHR] Loaded length in test " + testName); + is(event.total, expectedLength, + "[XHR] Total length in test " + testName); + + testHasRun(); + } +} + +function convertXHRBinary(s) { + var res = ""; + for (var i = 0; i < s.length; ++i) { + res += String.fromCharCode(s.charCodeAt(i) & 255); + } + return res; +} + +function testHasRun() { + //alert(testRanCounter); + ++testRanCounter; + if (testRanCounter == expectedTestCount) { + SimpleTest.finish(); + } +} + +function gc() { + window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIDOMWindowUtils) + .garbageCollect(); +} + +function checkMPSubmission(sub, expected) { + function getPropCount(o) { + var x, l = 0; + for (x in o) ++l; + return l; + } + + is(sub.length, expected.length, + "Correct number of items"); + var i; + for (i = 0; i < expected.length; ++i) { + if (!("fileName" in expected[i])) { + is(sub[i].headers["Content-Disposition"], + "form-data; name=\"" + expected[i].name + "\"", + "Correct name (A)"); + is (getPropCount(sub[i].headers), 1, + "Wrong number of headers (A)"); + } + else { + is(sub[i].headers["Content-Disposition"], + "form-data; name=\"" + expected[i].name + "\"; filename=\"" + + expected[i].fileName + "\"", + "Correct name (B)"); + is(sub[i].headers["Content-Type"], + expected[i].contentType, + "Correct content type (B)"); + is (getPropCount(sub[i].headers), 2, + "Wrong number of headers (B)"); + } + // Do not use |is(sub[i].body, expected[i].value, "...");| that may output raw binary data. + is(sub[i].body.length, expected[i].value.length, + "Length of correct value"); + ok(sub[i].body == expected[i].value, + "Content of correct value"); + } +} + +function testSlice(file, size, type, contents, fileType) { + is(file.type, type, fileType + " file is correct type"); + is(file.size, size, fileType + " file is correct size"); + ok(file instanceof File, fileType + " file is a File"); + ok(file instanceof Blob, fileType + " file is also a Blob"); + + var slice = file.slice(0, size); + ok(slice instanceof Blob, fileType + " fullsize slice is a Blob"); + ok(!(slice instanceof File), fileType + " fullsize slice is not a File"); + + slice = file.slice(0, 1234); + ok(slice instanceof Blob, fileType + " sized slice is a Blob"); + ok(!(slice instanceof File), fileType + " sized slice is not a File"); + + slice = file.slice(0, size, "foo/bar"); + is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type"); + + slice = file.slice(0, 5432, "foo/bar"); + is(slice.type, "foo/bar", fileType + " sized slice foo/bar type"); + + is(slice.slice(0, 10).type, "", fileType + " slice-slice type"); + is(slice.slice(0, 10).size, 10, fileType + " slice-slice size"); + is(slice.slice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type"); + is(slice.slice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size"); + + // Start, end, expected size + var indexes = [[0, size, size], + [0, 1234, 1234], + [size-500, size, 500], + [size-500, size+500, 500], + [size+500, size+1500, 0], + [0, 0, 0], + [1000, 1000, 0], + [size, size, 0], + [undefined, undefined, size], + [0, undefined, size], + [100, undefined, size-100], + [-100, undefined, 100], + [100, -100, size-200], + [-size-100, undefined, size], + [-2*size-100, 500, 500], + [0, -size-100, 0], + [100, -size-100, 0], + [50, -size+100, 50], + [0, 33000, 33000], + [1000, 34000, 33000], + ]; + + for (var i = 0; i < indexes.length; ++i) { + var sliceContents; + var testName; + if (indexes[i][0] == undefined) { + slice = file.slice(); + sliceContents = contents.slice(); + testName = fileType + " slice()"; + } + else if (indexes[i][1] == undefined) { + slice = file.slice(indexes[i][0]); + sliceContents = contents.slice(indexes[i][0]); + testName = fileType + " slice(" + indexes[i][0] + ")"; + } + else { + slice = file.slice(indexes[i][0], indexes[i][1]); + sliceContents = contents.slice(indexes[i][0], indexes[i][1]); + testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")"; + } + is(slice.type, "", testName + " type"); + is(slice.size, indexes[i][2], testName + " size"); + is(sliceContents.length, indexes[i][2], testName + " data size"); + testFile(slice, sliceContents, testName); + } + + // Slice of slice + var slice = file.slice(0, 40000); + testFile(slice.slice(5000, 42000), contents.slice(5000, 40000), "file slice slice"); + + // ...of slice of slice + slice = slice.slice(5000, 42000).slice(400, 700); + SpecialPowers.gc(); + testFile(slice, contents.slice(5400, 5700), "file slice slice slice"); +} + diff --git a/dom/base/test/forRemoval.resource b/dom/base/test/forRemoval.resource new file mode 100644 index 0000000000..09e882b3ba --- /dev/null +++ b/dom/base/test/forRemoval.resource @@ -0,0 +1,24 @@ +:this file must be enconded in utf8 +:and its Content-Type must be equal to text/event-stream + +retry:500 +event: message +data: 1 + +retry:500 +event: message +data: 2 + +retry:500 +event: message +data: 3 + +retry:500 +event: message +data: 4 + +retry:500 +event: message +data: 5 + + diff --git a/dom/base/test/forRemoval.resource^headers^ b/dom/base/test/forRemoval.resource^headers^ new file mode 100644 index 0000000000..6a63b5341d --- /dev/null +++ b/dom/base/test/forRemoval.resource^headers^ @@ -0,0 +1,3 @@ +Content-Type: text/event-stream +Cache-Control: no-cache, must-revalidate + diff --git a/dom/base/test/formReset.html b/dom/base/test/formReset.html new file mode 100644 index 0000000000..faee1e5b4d --- /dev/null +++ b/dom/base/test/formReset.html @@ -0,0 +1,15 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" + "http://www.w3.org/TR/REC-html401-19991224/strict.dtd"> +<html> + <head> + <title>Form Elements</title> + <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> + </head> + <body> + <p>Check me! <input type="checkbox" id="checkbox1"><br> + Uncheck me! <input type="checkbox" checked id="checkbox2"><br> + <input type="text" size=30 value="Write something here" id="textinput"><br> + <textarea id="textarea">Write something here</textarea><br> + </p> + </body> +</html> diff --git a/dom/base/test/gtest/TestNativeXMLHttpRequest.cpp b/dom/base/test/gtest/TestNativeXMLHttpRequest.cpp new file mode 100644 index 0000000000..920d80e962 --- /dev/null +++ b/dom/base/test/gtest/TestNativeXMLHttpRequest.cpp @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "nsContentUtils.h" +#include "nsIDOMDocument.h" +#include "nsIPrincipal.h" +#include "nsIScriptSecurityManager.h" +#include "nsIXMLHttpRequest.h" + +#define TEST_URL_PREFIX "data:text/xml," +#define TEST_URL_CONTENT "<foo><bar></bar></foo>" +#define TEST_URL TEST_URL_PREFIX TEST_URL_CONTENT + +TEST(NativeXMLHttpRequest, Test) +{ + nsresult rv; + + nsCOMPtr<nsIXMLHttpRequest> xhr = + do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Couldn't create nsIXMLHttpRequest instance"; + + NS_NAMED_LITERAL_CSTRING(getString, "GET"); + NS_NAMED_LITERAL_CSTRING(testURL, TEST_URL); + const nsAString& empty = EmptyString(); + + nsCOMPtr<nsIScriptSecurityManager> secman = + do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Couldn't get script security manager"; + + nsCOMPtr<nsIPrincipal> systemPrincipal; + rv = secman->GetSystemPrincipal(getter_AddRefs(systemPrincipal)); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Couldn't get system principal"; + + rv = xhr->Init(systemPrincipal, nullptr, nullptr, nullptr); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Couldn't initialize the XHR"; + + rv = xhr->Open(getString, testURL, false, empty, empty); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Open failed"; + + rv = xhr->Send(nullptr); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Send failed"; + + nsAutoString response; + rv = xhr->GetResponseText(response); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "GetResponse failed"; + ASSERT_TRUE(response.EqualsLiteral(TEST_URL_CONTENT)) << + "Response text does not match"; + + nsCOMPtr<nsIDOMDocument> dom; + rv = xhr->GetResponseXML(getter_AddRefs(dom)); + ASSERT_TRUE(NS_SUCCEEDED(rv)) << "GetResponseXML failed"; + ASSERT_TRUE(dom) << "No DOM document constructed"; +} diff --git a/dom/base/test/gtest/TestParserDialogOptions.cpp b/dom/base/test/gtest/TestParserDialogOptions.cpp new file mode 100644 index 0000000000..055f9ebfdf --- /dev/null +++ b/dom/base/test/gtest/TestParserDialogOptions.cpp @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" +#include "nsGlobalWindow.h" + +struct dialog_test { + const char* input; + const char* output; +}; + +void runTokenizeTest(dialog_test& test) +{ + NS_ConvertUTF8toUTF16 input(test.input); + + nsAString::const_iterator end; + input.EndReading(end); + + nsAString::const_iterator iter; + input.BeginReading(iter); + + nsAutoString result; + nsAutoString token; + + while (nsGlobalWindow::TokenizeDialogOptions(token, iter, end)) { + if (!result.IsEmpty()) { + result.Append(','); + } + + result.Append(token); + } + + ASSERT_STREQ(test.output, NS_ConvertUTF16toUTF8(result).get()) << "Testing " << test.input; +} + +void runTest(dialog_test& test) +{ + NS_ConvertUTF8toUTF16 input(test.input); + + nsAutoString result; + nsGlobalWindow::ConvertDialogOptions(input, result); + + ASSERT_STREQ(test.output, NS_ConvertUTF16toUTF8(result).get()) << "Testing " << test.input; +} + +TEST(GlobalWindowDialogOptions, TestDialogTokenize) +{ + dialog_test tests[] = { + /// Empty strings + { "", "" }, + { " ", "" }, + { " ", "" }, + + // 1 token + { "a", "a" }, + { " a", "a" }, + { " a ", "a" }, + { "aa", "aa" }, + { " aa", "aa" }, + { " aa ", "aa" }, + { ";", ";" }, + { ":", ":" }, + { "=", "=" }, + + // 2 tokens + { "a=", "a,=" }, + { " a= ", "a,=" }, + { " a = ", "a,=" }, + { "aa=", "aa,=" }, + { " aa= ", "aa,=" }, + { " aa = ", "aa,=" }, + { ";= ", ";,=" }, + { "==", "=,=" }, + { "::", ":,:" }, + + // 3 tokens + { "a=2", "a,=,2" }, + { "===", "=,=,=" }, + { ";:=", ";,:,=" }, + + // more + { "aaa;bbb:ccc", "aaa,;,bbb,:,ccc" }, + + // sentinel + { nullptr, nullptr } + }; + + for (uint32_t i = 0; tests[i].input; ++i) { + runTokenizeTest(tests[i]); + } +} +TEST(GlobalWindowDialogOptions, TestDialogOptions) +{ + dialog_test tests[] = { + /// Empty strings + { "", "" }, + { " ", "" }, + { " ", "" }, + + // Name without params + { "a", "" }, + { " a", "" }, + { " a ", "" }, + { "a=", "" }, + { " a= ", "" }, + { " a = ", "" }, + + // 1 unknown value + { "a=2", "" }, + { " a=2 ", "" }, + { " a = 2 ", "" }, + { "a:2", "" }, + { " a:2 ", "" }, + { " a : 2 ", "" }, + + // 1 known value, wrong value + { "center=2", "" }, + { "center:2", "" }, + + // 1 known value, good value + { "center=on", ",centerscreen=1" }, + { "center:on", ",centerscreen=1" }, + { " center : on ", ",centerscreen=1" }, + + // nonsense stuff + { " ; ", "" }, + + // sentinel + { nullptr, nullptr } + }; + + for (uint32_t i = 0; tests[i].input; ++i) { + runTest(tests[i]); + } +} diff --git a/dom/base/test/gtest/TestPlainTextSerializer.cpp b/dom/base/test/gtest/TestPlainTextSerializer.cpp new file mode 100644 index 0000000000..c293402096 --- /dev/null +++ b/dom/base/test/gtest/TestPlainTextSerializer.cpp @@ -0,0 +1,231 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include "nsServiceManagerUtils.h" +#include "nsStringGlue.h" +#include "nsIDocumentEncoder.h" +#include "nsCRT.h" +#include "nsIParserUtils.h" + +void +ConvertBufToPlainText(nsString &aConBuf, int aFlag) +{ + nsCOMPtr<nsIParserUtils> utils = do_GetService(NS_PARSERUTILS_CONTRACTID); + utils->ConvertToPlainText(aConBuf, aFlag, 72, aConBuf); +} + +// Test for ASCII with format=flowed; delsp=yes +TEST(PlainTextSerializer, ASCIIWithFlowedDelSp) +{ + nsString test; + nsString result; + + test.AssignLiteral("<html><body>" + "Firefox Firefox Firefox Firefox " + "Firefox Firefox Firefox Firefox " + "Firefox Firefox Firefox Firefox" + "</body></html>"); + + ConvertBufToPlainText(test, nsIDocumentEncoder::OutputFormatted | + nsIDocumentEncoder::OutputCRLineBreak | + nsIDocumentEncoder::OutputLFLineBreak | + nsIDocumentEncoder::OutputFormatFlowed | + nsIDocumentEncoder::OutputFormatDelSp); + + // create result case + result.AssignLiteral("Firefox Firefox Firefox Firefox " + "Firefox Firefox Firefox Firefox " + "Firefox \r\nFirefox Firefox Firefox\r\n"); + + ASSERT_TRUE(test.Equals(result)) << + "Wrong HTML to ASCII text serialization with format=flowed; delsp=yes"; +} + +// Test for CJK with format=flowed; delsp=yes +TEST(PlainTextSerializer, CJKWithFlowedDelSp) +{ + nsString test; + nsString result; + + test.AssignLiteral("<html><body>"); + for (uint32_t i = 0; i < 40; i++) { + // Insert Kanji (U+5341) + test.Append(0x5341); + } + test.AppendLiteral("</body></html>"); + + ConvertBufToPlainText(test, nsIDocumentEncoder::OutputFormatted | + nsIDocumentEncoder::OutputCRLineBreak | + nsIDocumentEncoder::OutputLFLineBreak | + nsIDocumentEncoder::OutputFormatFlowed | + nsIDocumentEncoder::OutputFormatDelSp); + + // create result case + for (uint32_t i = 0; i < 36; i++) { + result.Append(0x5341); + } + result.AppendLiteral(" \r\n"); + for (uint32_t i = 0; i < 4; i++) { + result.Append(0x5341); + } + result.AppendLiteral("\r\n"); + + ASSERT_TRUE(test.Equals(result)) << + "Wrong HTML to CJK text serialization with format=flowed; delsp=yes"; +} + +// Test for CJK with DisallowLineBreaking +TEST(PlainTextSerializer, CJKWithDisallowLineBreaking) +{ + nsString test; + nsString result; + + test.AssignLiteral("<html><body>"); + for (uint32_t i = 0; i < 400; i++) { + // Insert Kanji (U+5341) + test.Append(0x5341); + } + test.AppendLiteral("</body></html>"); + + ConvertBufToPlainText(test, nsIDocumentEncoder::OutputFormatted | + nsIDocumentEncoder::OutputCRLineBreak | + nsIDocumentEncoder::OutputLFLineBreak | + nsIDocumentEncoder::OutputFormatFlowed | + nsIDocumentEncoder::OutputDisallowLineBreaking); + + // create result case + for (uint32_t i = 0; i < 400; i++) { + result.Append(0x5341); + } + result.AppendLiteral("\r\n"); + + ASSERT_TRUE(test.Equals(result)) << + "Wrong HTML to CJK text serialization with OutputDisallowLineBreaking"; +} + +// Test for ASCII with format=flowed; and quoted lines in preformatted span. +TEST(PlainTextSerializer, PreformatFlowedQuotes) +{ + nsString test; + nsString result; + + test.AssignLiteral("<html><body>" + "<span style=\"white-space: pre-wrap;\">" + "> Firefox Firefox Firefox Firefox <br>" + "> Firefox Firefox Firefox Firefox<br>" + "><br>" + ">> Firefox Firefox Firefox Firefox <br>" + ">> Firefox Firefox Firefox Firefox<br>" + "</span></body></html>"); + + ConvertBufToPlainText(test, nsIDocumentEncoder::OutputFormatted | + nsIDocumentEncoder::OutputCRLineBreak | + nsIDocumentEncoder::OutputLFLineBreak | + nsIDocumentEncoder::OutputFormatFlowed); + + // create result case + result.AssignLiteral("> Firefox Firefox Firefox Firefox \r\n" + "> Firefox Firefox Firefox Firefox\r\n" + ">\r\n" + ">> Firefox Firefox Firefox Firefox \r\n" + ">> Firefox Firefox Firefox Firefox\r\n"); + + ASSERT_TRUE(test.Equals(result)) << + "Wrong HTML to ASCII text serialization with format=flowed; and quoted " + "lines"; +} + +TEST(PlainTextSerializer, PrettyPrintedHtml) +{ + nsString test; + test.AppendLiteral( + "<html>" NS_LINEBREAK + "<body>" NS_LINEBREAK + " first<br>" NS_LINEBREAK + " second<br>" NS_LINEBREAK + "</body>" NS_LINEBREAK "</html>"); + + ConvertBufToPlainText(test, 0); + ASSERT_TRUE(test.EqualsLiteral("first" NS_LINEBREAK "second" NS_LINEBREAK)) << + "Wrong prettyprinted html to text serialization"; +} + +TEST(PlainTextSerializer, PreElement) +{ + nsString test; + test.AppendLiteral( + "<html>" NS_LINEBREAK + "<body>" NS_LINEBREAK + "<pre>" NS_LINEBREAK + " first" NS_LINEBREAK + " second" NS_LINEBREAK + "</pre>" NS_LINEBREAK + "</body>" NS_LINEBREAK "</html>"); + + ConvertBufToPlainText(test, 0); + ASSERT_TRUE(test.EqualsLiteral(" first" NS_LINEBREAK + " second" NS_LINEBREAK NS_LINEBREAK)) << + "Wrong prettyprinted html to text serialization"; +} + +TEST(PlainTextSerializer, BlockElement) +{ + nsString test; + test.AppendLiteral( + "<html>" NS_LINEBREAK + "<body>" NS_LINEBREAK + "<div>" NS_LINEBREAK + " first" NS_LINEBREAK + "</div>" NS_LINEBREAK + "<div>" NS_LINEBREAK + " second" NS_LINEBREAK + "</div>" NS_LINEBREAK + "</body>" NS_LINEBREAK "</html>"); + + ConvertBufToPlainText(test, 0); + ASSERT_TRUE(test.EqualsLiteral("first" NS_LINEBREAK "second" NS_LINEBREAK)) << + "Wrong prettyprinted html to text serialization"; +} + +TEST(PlainTextSerializer, PreWrapElementForThunderbird) +{ + // This test examines the magic pre-wrap setup that Thunderbird relies on. + nsString test; + test.AppendLiteral( + "<html>" NS_LINEBREAK + "<body style=\"white-space: pre-wrap; width: 10ch;\">" NS_LINEBREAK + "<pre>" NS_LINEBREAK + " first line is too long" NS_LINEBREAK + " second line is even loooonger " NS_LINEBREAK + "</pre>" NS_LINEBREAK + "</body>" NS_LINEBREAK "</html>"); + + ConvertBufToPlainText(test, nsIDocumentEncoder::OutputWrap); + // "\n\n first\nline is\ntoo long\n second\nline is\neven\nloooonger\n\n\n" + ASSERT_TRUE(test.EqualsLiteral(NS_LINEBREAK NS_LINEBREAK + " first" NS_LINEBREAK + "line is" NS_LINEBREAK + "too long" NS_LINEBREAK + " second" NS_LINEBREAK + "line is" NS_LINEBREAK + "even" NS_LINEBREAK + "loooonger" NS_LINEBREAK + NS_LINEBREAK NS_LINEBREAK)) << + "Wrong prettyprinted html to text serialization"; +} + +TEST(PlainTextSerializer, Simple) +{ + nsString test; + test.AppendLiteral("<html><base>base</base><head><span>span</span></head>" + "<body>body</body></html>"); + ConvertBufToPlainText(test, 0); + ASSERT_TRUE(test.EqualsLiteral("basespanbody")) << + "Wrong html to text serialization"; +} + diff --git a/dom/base/test/gtest/moz.build b/dom/base/test/gtest/moz.build new file mode 100644 index 0000000000..a211184e86 --- /dev/null +++ b/dom/base/test/gtest/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at http://mozilla.org/MPL/2.0/. + +UNIFIED_SOURCES += [ + 'TestNativeXMLHttpRequest.cpp', + 'TestParserDialogOptions.cpp', + 'TestPlainTextSerializer.cpp', +] + +LOCAL_INCLUDES += [ + '/dom/base' +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul-gtest' diff --git a/dom/base/test/iframe_bug962251.html b/dom/base/test/iframe_bug962251.html new file mode 100644 index 0000000000..1ecad0fd48 --- /dev/null +++ b/dom/base/test/iframe_bug962251.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> +</head> +<body> +<input id="textinput" type="text"></input> +<input id="textinput1" type="text"></input> +</body> +<script> + var SimpleTest = parent.SimpleTest; + + var ok = SimpleTest.ok; + var info = SimpleTest.info; + var is = SimpleTest.is; + var finish = SimpleTest.finish.bind(SimpleTest); + + var input = document.getElementById("textinput"); + input.addEventListener("focus", function onFocus(aEvent) { + input.removeEventListener("focus", onFocus); + is(aEvent.target.id, "textinput", "Input should be focused."); + ok(aEvent.relatedTarget === null, "The relatedTarget should be null."); + parent.postMessage("runNextTest", "*"); + }); + input.focus(); +</script> +</html>
\ No newline at end of file diff --git a/dom/base/test/iframe_bug976673.html b/dom/base/test/iframe_bug976673.html new file mode 100644 index 0000000000..9b8bd9c201 --- /dev/null +++ b/dom/base/test/iframe_bug976673.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 976673</title> +</head> +<body> + <input id="input" onfocus="event.target.value = event.type;" + onblur="event.target.value = event.type;"> + <script> + var input = document.getElementById("input"); + window.addEventListener("message", function (aEvent) { + switch (aEvent.data) { + case "init": + input.blur(); + input.value = ""; + input.focus(); + case "check": + aEvent.source.postMessage("input-value: " + input.value, "*"); + break; + } + }, false); + </script> +</body> +</html> diff --git a/dom/base/test/iframe_main_bug1022229.html b/dom/base/test/iframe_main_bug1022229.html new file mode 100644 index 0000000000..4a725f9255 --- /dev/null +++ b/dom/base/test/iframe_main_bug1022229.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html> +<head> +<script> + // Uncomment this definition of SimpleTest (and comment out the one below) to + // debug in mozBrowser mode. + /* + var SimpleTest = { ok: function(c, m) { dump(m + ": " + c + "\n"); }, + info: function(m) { dump(m + "\n"); }, + finish: function() { dump("Test done\n");} }; + */ + var SimpleTest = parent.SimpleTest; + + var ok = SimpleTest.ok; + var info = SimpleTest.info; + var finish = SimpleTest.finish.bind(SimpleTest); + + var gotTargetedMessage = false; + window.onmessage = function(evt) { + var message = evt.data; + info("Received message: " + message); + switch (message) { + case 'targeted': + gotTargetedMessage = true; + break; + case 'broadcast': + ok(gotTargetedMessage, "Should have received targeted message"); + finish(); + break; + default: + ok(false, "Unexpected message: " + message); + break; + } + } +</script> +</head> +<body> +<iframe src="iframe_sandbox_bug1022229.html" sandbox="allow-scripts"></iframe> +</body> +</html> diff --git a/dom/base/test/iframe_postMessage_solidus.html b/dom/base/test/iframe_postMessage_solidus.html new file mode 100644 index 0000000000..b5cf33b402 --- /dev/null +++ b/dom/base/test/iframe_postMessage_solidus.html @@ -0,0 +1,15 @@ +<!DOCTYPE HTML> +<html> +<body> + <script type="application/javascript"> + + window.addEventListener('message', receiveMessage, false); + function receiveMessage(evt) { + window.parent.postMessage(evt.data, '*'); + } + + </script> +</body> +</html> + + diff --git a/dom/base/test/iframe_postMessages.html b/dom/base/test/iframe_postMessages.html new file mode 100644 index 0000000000..b34462f5e8 --- /dev/null +++ b/dom/base/test/iframe_postMessages.html @@ -0,0 +1,10 @@ +<!DOCTYPE HTML> +<html> +<body> +<script> +onmessage = function(e) { + parent.postMessage(e.data, '*', e.ports); +} +</script> +</body> +</html> diff --git a/dom/base/test/iframe_sandbox_bug1022229.html b/dom/base/test/iframe_sandbox_bug1022229.html new file mode 100644 index 0000000000..3d70e9d7af --- /dev/null +++ b/dom/base/test/iframe_sandbox_bug1022229.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> +<script> + // First send an origin-restricted message, and then send a non-restricted + // message to end the test promptly even in a failure mode. + parent.postMessage('targeted', 'http://mochi.test:8888'); + setTimeout(function() { parent.postMessage('broadcast', '*'); }, 0); +</script> +</head> +<body> +</body> +</html> diff --git a/dom/base/test/iframe_webSocket_sandbox.html b/dom/base/test/iframe_webSocket_sandbox.html new file mode 100644 index 0000000000..d889a79b05 --- /dev/null +++ b/dom/base/test/iframe_webSocket_sandbox.html @@ -0,0 +1,65 @@ +<html><body> +<iframe id="frame" sandbox="allow-scripts allow-popups"></iframe> +<script type="application/javascript;version=1.8"> +onmessage = function(e) { + parent.postMessage(e.data, '*'); +} + +var ifr = document.getElementById('frame'); + +if (location.search == '?nested') { + var url = new URL(location); + url.search = ""; + ifr.src = url.href; +} else if (location.search == '?popup') { + var url = new URL(location); + url.search = "?opener"; + + ifr.srcdoc = "<html><script>" + + "window.open('" + url.href + "', 'foobar');" + + "onmessage = function(e) { " + + " parent.postMessage(e.data, '*'); " + + "}" + + "</scr" + "ipt></html>"; +} else if (location.search == '?opener') { + try{ + var socket = new WebSocket('ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic'); + socket.onerror = function(e) { + opener.postMessage('WS onerror', '*'); + close(); + }; + socket.onopen = function(event) { + opener.postMessage('WS onopen', '*'); + close(); + }; + } catch(e) { + if (e.name == 'SecurityError') { + opener.postMessage('WS Throws!', '*'); + } else { + opener.postMessage('WS Throws something else!', '*'); + } + close(); + } +} else { + ifr.srcdoc = ` + <html><script> + try{ + var socket = new WebSocket('ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic'); + socket.onerror = function(e) { + parent.postMessage('WS onerror', '*'); + }; + socket.onopen = function(event) { + parent.postMessage('WS onopen', '*'); + }; + } catch(e) { + if (e.name == 'SecurityError') { + parent.postMessage('WS Throws!', '*'); + } else { + parent.postMessage('WS Throws something else!', '*'); + } + } + </scr`+`ipt> + </html>`; +} +</script> +</body></html> diff --git a/dom/base/test/img_referrer_testserver.sjs b/dom/base/test/img_referrer_testserver.sjs new file mode 100644 index 0000000000..f0ee1b963e --- /dev/null +++ b/dom/base/test/img_referrer_testserver.sjs @@ -0,0 +1,298 @@ +var BASE_URL = 'example.com/tests/dom/base/test/img_referrer_testserver.sjs'; +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); + +function createTestUrl(aPolicy, aAction, aName, aContent) { + var content = aContent || 'text'; + return 'http://' + BASE_URL + '?' + + 'action=' + aAction + '&' + + 'policy=' + aPolicy + '&' + + 'name=' + aName + '&' + + 'content=' + content; +} + +function createTestPage(aHead, aImgPolicy, aName) { + var _createTestUrl = createTestUrl.bind(null, aImgPolicy, 'test', aName); + + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <img src="' + _createTestUrl('img') + '" referrerpolicy="' + aImgPolicy + '" id="image"></img>\n\ + <script>' + + + // LOAD EVENT (of the test) + // fires when the img resource for the page is loaded + 'window.addEventListener("load", function() {\n\ + parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +// Creates the following test cases for the specified referrer +// policy combination: +// <img> with referrer +function createTest(aPolicy, aImgPolicy, aName) { + var headString = '<head>'; + if (aPolicy) { + headString += '<meta name="referrer" content="' + aPolicy + '">'; + } + + headString += '<script></script>'; + + return createTestPage(headString, aImgPolicy, aName); +} + +// testing regular load img with referrer policy +// speculative parser should not kick in here +function createTest2(aImgPolicy, name) { + return createTestPage('', aImgPolicy, name); +} + +function createTest3(aImgPolicy1, aImgPolicy2, aImgPolicy3, aName) { + return '<!DOCTYPE HTML>\n\ + <html>\n\ + <body>\n\ + <img src="' + createTestUrl(aImgPolicy1, 'test', aName + aImgPolicy1) + '" referrerpolicy="' + aImgPolicy1 + '" id="image"></img>\n\ + <img src="' + createTestUrl(aImgPolicy2, 'test', aName + aImgPolicy2) + '" referrerpolicy="' + aImgPolicy2 + '" id="image"></img>\n\ + <img src="' + createTestUrl(aImgPolicy3, 'test', aName + aImgPolicy3) + '" referrerpolicy="' + aImgPolicy3 + '" id="image"></img>\n\ + <script>\n\ + var _numLoads = 0;' + + + // LOAD EVENT (of the test) + // fires when the img resource for the page is loaded + 'window.addEventListener("load", function() {\n\ + parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createTestPage2(aHead, aPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <img src="' + createTestUrl(aPolicy, "test", aName) + '" id="image"></img>\n\ + <script>' + + + // LOAD EVENT (of the test) + // fires when the img resource for the page is loaded + 'window.addEventListener("load", function() {\n\ + parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createTestPage3(aHead, aPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <script>' + + 'var image = new Image();\n\ + image.src = "' + createTestUrl(aPolicy, "test", aName, "image") + '";\n\ + image.referrerPolicy = "' + aPolicy + '";\n\ + image.onload = function() {\n\ + window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }\n\ + document.body.appendChild(image);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createTestPage4(aHead, aPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + aHead + + '<body>\n\ + <script>' + + 'var image = new Image();\n\ + image.referrerPolicy = "' + aPolicy + '";\n\ + image.src = "' + createTestUrl(aPolicy, "test", aName, "image") + '";\n\ + image.onload = function() {\n\ + window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");\n\ + }\n\ + document.body.appendChild(image);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createSetAttributeTest1(aPolicy, aImgPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + headString += '<script></script>'; + + return createTestPage3(headString, aImgPolicy, aName); +} + +function createSetAttributeTest2(aPolicy, aImgPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + headString += '<script></script>'; + + return createTestPage4(headString, aImgPolicy, aName); +} + + +function createTest4(aPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + headString += '<script></script>'; + + return createTestPage2(headString, aPolicy, aName); +} + +function createTest5(aPolicy, aName) { + var headString = '<head>'; + headString += '<meta name="referrer" content="' + aPolicy + '">'; + + return createTestPage2(headString, aPolicy, aName); +} + +function handleRequest(request, response) { + var sharedKey = 'img_referrer_testserver.sjs'; + var params = request.queryString.split('&'); + var action = params[0].split('=')[1]; + + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/html; charset=utf-8', false); + + if (action === 'resetState') { + var state = getSharedState(sharedKey); + state = {}; + setSharedState(sharedKey, JSON.stringify(state)); + response.write(""); + return; + } + if (action === 'test') { + // ?action=test&policy=origin&name=name&content=content + var policy = params[1].split('=')[1]; + var name = params[2].split('=')[1]; + var content = params[3].split('=')[1]; + var result = getSharedState(sharedKey); + + if (result === '') { + result = {}; + } else { + result = JSON.parse(result); + } + + if (!result["tests"]) { + result["tests"] = {}; + } + + var referrerLevel = "none"; + var test = {} + if (request.hasHeader('Referer')) { + let referrer = request.getHeader('Referer'); + if (referrer.indexOf("img_referrer_testserver") > 0) { + referrerLevel = "full"; + } else if (referrer == "http://mochi.test:8888/") { + referrerLevel = "origin"; + } + test.referrer = request.getHeader('Referer'); + } else { + test.referrer = ''; + } + test.policy = referrerLevel; + test.expected = policy; + + result["tests"][name] = test; + + setSharedState(sharedKey, JSON.stringify(result)); + + if (content === 'image') { + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + } + return; + } + if (action === 'get-test-results') { + // ?action=get-result + response.write(getSharedState(sharedKey)); + return; + } + if (action === 'generate-img-policy-test') { + // ?action=generate-img-policy-test&imgPolicy=b64-encoded-string&name=name&policy=b64-encoded-string + var imgPolicy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + var metaPolicy = ''; + if (params[3]) { + metaPolicy = params[3].split('=')[1]; + } + + response.write(createTest(metaPolicy, imgPolicy, name)); + return; + } + if (action === 'generate-img-policy-test2') { + // ?action=generate-img-policy-test2&imgPolicy=b64-encoded-string&name=name + var imgPolicy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + + response.write(createTest2(imgPolicy, name)); + return; + } + if (action === 'generate-img-policy-test3') { + // ?action=generate-img-policy-test3&imgPolicy1=b64-encoded-string&imgPolicy2=b64-encoded-string&imgPolicy3=b64-encoded-string&name=name + var imgPolicy1 = unescape(params[1].split('=')[1]); + var imgPolicy2 = unescape(params[2].split('=')[1]); + var imgPolicy3 = unescape(params[3].split('=')[1]); + var name = unescape(params[4].split('=')[1]); + + response.write(createTest3(imgPolicy1, imgPolicy2, imgPolicy3, name)); + return; + } + if (action === 'generate-img-policy-test4') { + // ?action=generate-img-policy-test4&imgPolicy=b64-encoded-string&name=name + var policy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + + response.write(createTest4(policy, name)); + return; + } + if (action === 'generate-img-policy-test5') { + // ?action=generate-img-policy-test5&policy=b64-encoded-string&name=name + var policy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + + response.write(createTest5(policy, name)); + return; + } + + if (action === 'generate-setAttribute-test1') { + // ?action=generate-setAttribute-test1&policy=b64-encoded-string&name=name + var imgPolicy = unescape(params[1].split('=')[1]); + var policy = unescape(params[2].split('=')[1]); + var name = unescape(params[3].split('=')[1]); + + response.write(createSetAttributeTest1(policy, imgPolicy, name)); + return; + } + + if (action === 'generate-setAttribute-test2') { + // ?action=generate-setAttribute-test2&policy=b64-encoded-string&name=name + var imgPolicy = unescape(params[1].split('=')[1]); + var policy = unescape(params[2].split('=')[1]); + var name = unescape(params[3].split('=')[1]); + + response.write(createSetAttributeTest2(policy, imgPolicy, name)); + return; + } + + response.write("I don't know action "+action); + return; +} diff --git a/dom/base/test/intersectionobserver_iframe.html b/dom/base/test/intersectionobserver_iframe.html new file mode 100644 index 0000000000..8a4098e743 --- /dev/null +++ b/dom/base/test/intersectionobserver_iframe.html @@ -0,0 +1,23 @@ +<!DOCTYPE HTML> +<html> +<head> +<style> +#target5 { + position: absolute; + top: 0px; + left: 0px; + width: 20px; + height: 20px; + background: #f00; +} +</style> +<body> +<div id="target5"></div> +<script> + var io = new IntersectionObserver(function (records) { + window.parent.postMessage(records[0].rootBounds == null, 'http://mochi.test:8888'); + }, {}); + io.observe(document.getElementById("target5")); +</script> +</body> +</html> diff --git a/dom/base/test/intersectionobserver_window.html b/dom/base/test/intersectionobserver_window.html new file mode 100644 index 0000000000..c2b1b023ab --- /dev/null +++ b/dom/base/test/intersectionobserver_window.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> +<style> +#target5 { + position: absolute; + top: 0px; + left: 0px; + width: 20px; + height: 20px; + background: #f00; +} +</style> +<body> +<div id="target"></div> +<script> + var io = new IntersectionObserver(function(records) { + var viewportWidth = + document.documentElement.clientWidth || document.body.clientWidth; + var viewportHeight = + document.documentElement.clientHeight || document.body.clientHeight; + var passed = records.length === 1 && + records[0].rootBounds.top === 0 && + records[0].rootBounds.left === 0 && + records[0].rootBounds.right === viewportWidth && + records[0].rootBounds.width === viewportWidth && + records[0].rootBounds.bottom === viewportHeight && + records[0].rootBounds.height === viewportHeight; + window.opener.postMessage(passed, '*'); + }); + io.observe(document.getElementById("target")); +</script> +</body> +</html> diff --git a/dom/base/test/invalid_accesscontrol.resource b/dom/base/test/invalid_accesscontrol.resource new file mode 100644 index 0000000000..aca66f6f8d --- /dev/null +++ b/dom/base/test/invalid_accesscontrol.resource @@ -0,0 +1,7 @@ +:this file must be enconded in utf8 +:and its Content-Type must be equal to text/event-stream + +event: message +data: 1 + + diff --git a/dom/base/test/invalid_accesscontrol.resource^headers^ b/dom/base/test/invalid_accesscontrol.resource^headers^ new file mode 100644 index 0000000000..d5bed552cb --- /dev/null +++ b/dom/base/test/invalid_accesscontrol.resource^headers^ @@ -0,0 +1,4 @@ +Access-Control-Allow-Origin: http://an.accesscrontrol.domain:80 +Content-Type: text/event-stream +Cache-Control: no-cache, must-revalidate + diff --git a/dom/base/test/jsmodules/chrome.ini b/dom/base/test/jsmodules/chrome.ini new file mode 100644 index 0000000000..02a37a0ecf --- /dev/null +++ b/dom/base/test/jsmodules/chrome.ini @@ -0,0 +1,51 @@ +[DEFAULT] +support-files = + module_setRan.js + module_testSyntax.js + module_badSyntax.js + module_simpleImport.js + module_simpleExport.js + module_badImport.js + module_simple1.js + module_simple2.js + module_simple3.js + module_cyclic1.js + module_cyclic2.js + module_cyclic3.js + module_multiImports.js + module_multiLargeImports.js + script_simple2.js + module_large1.js + module_large2.js + module_large3.js + module_extractIntroType.js + iframe_extractIntroType.html + module_missingImport.js + +[test_moduleScriptsRun.html] +[test_moduleParsedAsModule.html] +[test_scriptNotParsedAsModule.html] +[test_typeAttrCaseInsensitive.html] +[test_moduleNotFound.html] +[test_importNotFound.html] +[test_syntaxError.html] +[test_syntaxErrorAsync.html] +[test_syntaxErrorInline.html] +[test_syntaxErrorInlineAsync.html] +[test_simpleImport.html] +[test_cyclicImport.html] +[test_importResolveFailed.html] +[test_multiTopLevelImports.html] +[test_multiModuleImports.html] +[test_multiAsyncImports.html] +[test_scriptModuleOrder.html] +[test_toplevelModuleMemoization.html] +[test_importedModuleMemoization.html] +[test_multiTopLevelLargeImports.html] +[test_multiModuleLargeImports.html] +[test_asyncInlineModules.html] +[test_scriptInsertedModule.html] +[test_linkErrorInCommon1.html] +[test_linkErrorInCommon2.html] +[test_topLevelIntroType.html] +[test_importIntroType.html] diff --git a/dom/base/test/jsmodules/iframe_extractIntroType.html b/dom/base/test/jsmodules/iframe_extractIntroType.html new file mode 100644 index 0000000000..692da0c5fc --- /dev/null +++ b/dom/base/test/jsmodules/iframe_extractIntroType.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + // Hook up the debugger statement to extract the calling script's + // introductionType and set it in a property on the parent global. + Components.utils.import("resource://gre/modules/jsdebugger.jsm"); + addDebuggerToGlobal(this); + var dbg = new Debugger; + dbg.addDebuggee(parent); + dbg.onDebuggerStatement = function (frame) { + parent.introType = frame.script.source.introductionType; + } +</script> diff --git a/dom/base/test/jsmodules/mochitest.ini b/dom/base/test/jsmodules/mochitest.ini new file mode 100644 index 0000000000..aa2b8652c0 --- /dev/null +++ b/dom/base/test/jsmodules/mochitest.ini @@ -0,0 +1,5 @@ +[DEFAULT] +support-files = + module_setRan.js + +[test_moduleScriptsNotRun.html] diff --git a/dom/base/test/jsmodules/module_badImport.js b/dom/base/test/jsmodules/module_badImport.js new file mode 100644 index 0000000000..ab18249156 --- /dev/null +++ b/dom/base/test/jsmodules/module_badImport.js @@ -0,0 +1 @@ +import "invalid specifier"; diff --git a/dom/base/test/jsmodules/module_badSyntax.js b/dom/base/test/jsmodules/module_badSyntax.js new file mode 100644 index 0000000000..744158108c --- /dev/null +++ b/dom/base/test/jsmodules/module_badSyntax.js @@ -0,0 +1,3 @@ +// Module with a syntax error. +some invalid js syntax; +wasRun = true; diff --git a/dom/base/test/jsmodules/module_cyclic1.js b/dom/base/test/jsmodules/module_cyclic1.js new file mode 100644 index 0000000000..efcfb9a4ea --- /dev/null +++ b/dom/base/test/jsmodules/module_cyclic1.js @@ -0,0 +1,7 @@ +import { func2 } from "./module_cyclic2.js"; + +export function func1(x, y) { + if (x <= 0) + return y; + return func2(x - 1, y + "1"); +} diff --git a/dom/base/test/jsmodules/module_cyclic2.js b/dom/base/test/jsmodules/module_cyclic2.js new file mode 100644 index 0000000000..68a9c6124d --- /dev/null +++ b/dom/base/test/jsmodules/module_cyclic2.js @@ -0,0 +1,7 @@ +import { func3 } from "./module_cyclic3.js"; + +export function func2(x, y) { + if (x <= 0) + return y; + return func3(x - 1, y + "2"); +} diff --git a/dom/base/test/jsmodules/module_cyclic3.js b/dom/base/test/jsmodules/module_cyclic3.js new file mode 100644 index 0000000000..9649493998 --- /dev/null +++ b/dom/base/test/jsmodules/module_cyclic3.js @@ -0,0 +1,7 @@ +import { func1 } from "./module_cyclic1.js"; + +export function func3(x, y) { + if (x <= 0) + return y; + return func1(x - 1, y + "3"); +} diff --git a/dom/base/test/jsmodules/module_extractIntroType.js b/dom/base/test/jsmodules/module_extractIntroType.js new file mode 100644 index 0000000000..be56857704 --- /dev/null +++ b/dom/base/test/jsmodules/module_extractIntroType.js @@ -0,0 +1,5 @@ +// Extract the introductionType for this module in conjunction with +// iframe_extractIntroType.html. +extractIntroType = function() { + debugger; +} diff --git a/dom/base/test/jsmodules/module_large1.js b/dom/base/test/jsmodules/module_large1.js new file mode 100644 index 0000000000..d6933d298d --- /dev/null +++ b/dom/base/test/jsmodules/module_large1.js @@ -0,0 +1,78 @@ +/* + * Scripts larger than 5KB may be compiled off main thread. This is such a + * script. + * + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + */ + +results.push(1); diff --git a/dom/base/test/jsmodules/module_large2.js b/dom/base/test/jsmodules/module_large2.js new file mode 100644 index 0000000000..e1b6da4c91 --- /dev/null +++ b/dom/base/test/jsmodules/module_large2.js @@ -0,0 +1,78 @@ +/* + * Scripts larger than 5KB may be compiled off main thread. This is such a + * script. + * + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + */ + +results.push(2); diff --git a/dom/base/test/jsmodules/module_large3.js b/dom/base/test/jsmodules/module_large3.js new file mode 100644 index 0000000000..c966a8eb20 --- /dev/null +++ b/dom/base/test/jsmodules/module_large3.js @@ -0,0 +1,78 @@ +/* + * Scripts larger than 5KB may be compiled off main thread. This is such a + * script. + * + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + * large large large large large large large large large large large large + */ + +results.push(3); diff --git a/dom/base/test/jsmodules/module_missingImport.js b/dom/base/test/jsmodules/module_missingImport.js new file mode 100644 index 0000000000..28cf608de8 --- /dev/null +++ b/dom/base/test/jsmodules/module_missingImport.js @@ -0,0 +1 @@ +import { missing } from "./module_simple1.js"; diff --git a/dom/base/test/jsmodules/module_multiImports.js b/dom/base/test/jsmodules/module_multiImports.js new file mode 100644 index 0000000000..0587ac5ca0 --- /dev/null +++ b/dom/base/test/jsmodules/module_multiImports.js @@ -0,0 +1,4 @@ +import "./module_simple1.js"; +import "./module_simple2.js"; +import "./module_simple3.js"; +results.push(4); diff --git a/dom/base/test/jsmodules/module_multiLargeImports.js b/dom/base/test/jsmodules/module_multiLargeImports.js new file mode 100644 index 0000000000..ddc5792d0d --- /dev/null +++ b/dom/base/test/jsmodules/module_multiLargeImports.js @@ -0,0 +1,4 @@ +import "./module_large1.js"; +import "./module_large2.js"; +import "./module_large3.js"; +results.push(4); diff --git a/dom/base/test/jsmodules/module_setRan.js b/dom/base/test/jsmodules/module_setRan.js new file mode 100644 index 0000000000..4804382fdd --- /dev/null +++ b/dom/base/test/jsmodules/module_setRan.js @@ -0,0 +1,2 @@ +// Set a global flag to indicate that this module was executed. +moduleRan = true; diff --git a/dom/base/test/jsmodules/module_simple1.js b/dom/base/test/jsmodules/module_simple1.js new file mode 100644 index 0000000000..7594ac699e --- /dev/null +++ b/dom/base/test/jsmodules/module_simple1.js @@ -0,0 +1 @@ +results.push(1); diff --git a/dom/base/test/jsmodules/module_simple2.js b/dom/base/test/jsmodules/module_simple2.js new file mode 100644 index 0000000000..f92a1c9d6e --- /dev/null +++ b/dom/base/test/jsmodules/module_simple2.js @@ -0,0 +1 @@ +results.push(2); diff --git a/dom/base/test/jsmodules/module_simple3.js b/dom/base/test/jsmodules/module_simple3.js new file mode 100644 index 0000000000..71979926e6 --- /dev/null +++ b/dom/base/test/jsmodules/module_simple3.js @@ -0,0 +1 @@ +results.push(3); diff --git a/dom/base/test/jsmodules/module_simpleExport.js b/dom/base/test/jsmodules/module_simpleExport.js new file mode 100644 index 0000000000..9714d6d0ab --- /dev/null +++ b/dom/base/test/jsmodules/module_simpleExport.js @@ -0,0 +1 @@ +export let x = 42; diff --git a/dom/base/test/jsmodules/module_simpleImport.js b/dom/base/test/jsmodules/module_simpleImport.js new file mode 100644 index 0000000000..cfc12bb726 --- /dev/null +++ b/dom/base/test/jsmodules/module_simpleImport.js @@ -0,0 +1,2 @@ +import { x } from "./module_simpleExport.js" +result = x; diff --git a/dom/base/test/jsmodules/module_testSyntax.js b/dom/base/test/jsmodules/module_testSyntax.js new file mode 100644 index 0000000000..3d647ae0b4 --- /dev/null +++ b/dom/base/test/jsmodules/module_testSyntax.js @@ -0,0 +1,3 @@ +// Module that throws a syntax error if parsed as a script. +export default 1; +wasRun = true; diff --git a/dom/base/test/jsmodules/moz.build b/dom/base/test/jsmodules/moz.build new file mode 100644 index 0000000000..f16b6dd80e --- /dev/null +++ b/dom/base/test/jsmodules/moz.build @@ -0,0 +1,13 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MOCHITEST_MANIFESTS += [ + 'mochitest.ini' +] + +MOCHITEST_CHROME_MANIFESTS += [ + 'chrome.ini' +] diff --git a/dom/base/test/jsmodules/script_simple2.js b/dom/base/test/jsmodules/script_simple2.js new file mode 100644 index 0000000000..f92a1c9d6e --- /dev/null +++ b/dom/base/test/jsmodules/script_simple2.js @@ -0,0 +1 @@ +results.push(2); diff --git a/dom/base/test/jsmodules/test_asyncInlineModules.html b/dom/base/test/jsmodules/test_asyncInlineModules.html new file mode 100644 index 0000000000..62e411bfe7 --- /dev/null +++ b/dom/base/test/jsmodules/test_asyncInlineModules.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test async inline modules</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results.sort(), [1, 2, 3]), 'Check modules imported'); + SimpleTest.finish(); + } +</script> +<script type="module" async> + results.push(1); +</script> +<script type="module" async> + import "./module_simple2.js"; +</script> +<script type="module" async> + results.push(3); +</script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_cyclicImport.html b/dom/base/test/jsmodules/test_cyclicImport.html new file mode 100644 index 0000000000..f70ae1d6bc --- /dev/null +++ b/dom/base/test/jsmodules/test_cyclicImport.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test cyclic module imports</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var result; + + SimpleTest.waitForExplicitFinish(); + + function testLoaded() { + SimpleTest.finish(); + } +</script> +<script type="module"> + import { func1 } from "./module_cyclic1.js"; + ok(func1(5, "") == "12312"); +</script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_importIntroType.html b/dom/base/test/jsmodules/test_importIntroType.html new file mode 100644 index 0000000000..3f85382829 --- /dev/null +++ b/dom/base/test/jsmodules/test_importIntroType.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test introduction type of an imported module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var introType; + var extractIntroType; + + info('start'); + SimpleTest.waitForExplicitFinish(); + + function testIntroductionType() { + extractIntroType(); + ok(introType == "importedModule", 'Check introduction type'); + SimpleTest.finish(); + } +</script> +<iframe src="iframe_extractIntroType.html"></iframe> +<script type="module"> +import "./module_extractIntroType.js"; +</script> +<body onload='testIntroductionType()'></body> diff --git a/dom/base/test/jsmodules/test_importNotFound.html b/dom/base/test/jsmodules/test_importNotFound.html new file mode 100644 index 0000000000..f4e12dfe7e --- /dev/null +++ b/dom/base/test/jsmodules/test_importNotFound.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test what happens when a module import is not found</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var errorCount = 0; + var eventCount = 0; + + SimpleTest.waitForExplicitFinish(); + + window.onerror = function(message, url, line, column, error) { + errorCount++; + } + + function testError() { + ok(!wasRun, 'Check script was not run'); + ok(eventCount == 1, 'Check that an error event was fired'); + ok(errorCount == 0, 'Check that no error was reported'); + SimpleTest.finish(); + } +</script> +<script type="module" onerror="eventCount++"> +import "./nonExistentModule.js"; +wasRun = true; +</script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_importResolveFailed.html b/dom/base/test/jsmodules/test_importResolveFailed.html new file mode 100644 index 0000000000..7df521d052 --- /dev/null +++ b/dom/base/test/jsmodules/test_importResolveFailed.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test error thrown when an import cannot be resolved</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var hadTypeError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + hadTypeError = error instanceof TypeError; + } + + function testError() { + ok(hadTypeError, 'Check that a TypeError was thrown'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_badImport.js"></script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_importedModuleMemoization.html b/dom/base/test/jsmodules/test_importedModuleMemoization.html new file mode 100644 index 0000000000..56c1188af4 --- /dev/null +++ b/dom/base/test/jsmodules/test_importedModuleMemoization.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test imported modules are momoized and only loaded once</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results, [1, 2, 3, 4]), 'Check modules only evaluated once'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_multiImports.js"></script> +<script type="module" src="module_multiImports.js"></script> +<script type="module" src="module_multiImports.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_linkErrorInCommon1.html b/dom/base/test/jsmodules/test_linkErrorInCommon1.html new file mode 100644 index 0000000000..3d1cb172f3 --- /dev/null +++ b/dom/base/test/jsmodules/test_linkErrorInCommon1.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test handling of a link error in a common module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var runCount = 0; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + if (error instanceof SyntaxError) { + hadSyntaxError = true; + } + } + + function testError() { + ok(runCount == 0, 'Check no modules were executed'); + ok(hadSyntaxError, 'Check that an error was reported'); + SimpleTest.finish(); + } +</script> +<script type="module"> + import { missing } from "./module_simple1.js"; + runCount++; +</script> +<script type="module"> + import { missing } from "./module_simple1.js"; + runCount++; +</script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_linkErrorInCommon2.html b/dom/base/test/jsmodules/test_linkErrorInCommon2.html new file mode 100644 index 0000000000..4bf10b1d0b --- /dev/null +++ b/dom/base/test/jsmodules/test_linkErrorInCommon2.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test handling of a link error in a common module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var runCount = 0; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + if (error instanceof SyntaxError) { + hadSyntaxError = true; + } + } + + function testError() { + ok(runCount == 0, 'Check no modules were executed'); + ok(hadSyntaxError, 'Check that an error was reported'); + SimpleTest.finish(); + } +</script> +<script type="module"> + import "./module_missingImport.js"; + runCount++; +</script> +<script type="module"> + import "./module_missingImport.js"; + runCount++; +</script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_moduleNotFound.html b/dom/base/test/jsmodules/test_moduleNotFound.html new file mode 100644 index 0000000000..448292968f --- /dev/null +++ b/dom/base/test/jsmodules/test_moduleNotFound.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test what happens when a top-level module is not found</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var errorCount = 0; + var eventCount = 0; + + SimpleTest.waitForExplicitFinish(); + + window.onerror = function(message, url, line, column, error) { + errorCount++; + } + + function testError() { + ok(eventCount == 1, 'Check that an error event was fired'); + ok(errorCount == 0, 'Check that no error was reported'); + SimpleTest.finish(); + } +</script> +<script type="module" src="./nonExistentModule.js" onerror="eventCount++"> +</script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_moduleParsedAsModule.html b/dom/base/test/jsmodules/test_moduleParsedAsModule.html new file mode 100644 index 0000000000..72eb1149ea --- /dev/null +++ b/dom/base/test/jsmodules/test_moduleParsedAsModule.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test module script parsed as module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + hadSyntaxError = error instanceof SyntaxError; + } + + function testError() { + ok(wasRun, 'Check module was run'); + ok(!hadSyntaxError, 'Check that no SyntaxError was thrown'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_testSyntax.js"></script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_moduleScriptsNotRun.html b/dom/base/test/jsmodules/test_moduleScriptsNotRun.html new file mode 100644 index 0000000000..1ce5377d95 --- /dev/null +++ b/dom/base/test/jsmodules/test_moduleScriptsNotRun.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test script elements with type="module" are not run for content HTML</title> +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<script> + var inlineModuleRan = false; + var moduleRan = false; + + SimpleTest.waitForExplicitFinish(); + + function testLoaded() { + ok(!moduleRan, "Check module script was not run"); + ok(!inlineModuleRan, "Check inline module script was not run"); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_setRan.js"></script> +<script type="module">inlineModuleRan = true;</script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_moduleScriptsRun.html b/dom/base/test/jsmodules/test_moduleScriptsRun.html new file mode 100644 index 0000000000..be2cbb2af0 --- /dev/null +++ b/dom/base/test/jsmodules/test_moduleScriptsRun.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test script elements with type="module" are run for chrome HTML</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var inlineModuleRan = false; + var moduleRan = false; + + SimpleTest.waitForExplicitFinish(); + + function testLoaded() { + ok(moduleRan, 'Check module script was run'); + ok(inlineModuleRan, 'Check inline module script was run'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_setRan.js"></script> +<script type="module">inlineModuleRan = true;</script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_multiAsyncImports.html b/dom/base/test/jsmodules/test_multiAsyncImports.html new file mode 100644 index 0000000000..d2f5e42ab6 --- /dev/null +++ b/dom/base/test/jsmodules/test_multiAsyncImports.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test a loading multiple modules with the async attribute from top level</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results.sort(), [1, 2, 3]), 'Check modules imported'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_simple1.js" async></script> +<script type="module" src="module_simple2.js" async></script> +<script type="module" src="module_simple3.js" async></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_multiModuleImports.html b/dom/base/test/jsmodules/test_multiModuleImports.html new file mode 100644 index 0000000000..f7abd7cee3 --- /dev/null +++ b/dom/base/test/jsmodules/test_multiModuleImports.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test a importing multiple modules from a module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results, [1, 2, 3, 4]), 'Check modules imported'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_multiImports.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_multiModuleLargeImports.html b/dom/base/test/jsmodules/test_multiModuleLargeImports.html new file mode 100644 index 0000000000..14f6c76c3d --- /dev/null +++ b/dom/base/test/jsmodules/test_multiModuleLargeImports.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test importing multiple large modules which may be compiled off main thread from a module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results, [1, 2, 3, 4]), 'Check modules imported'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_multiLargeImports.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_multiTopLevelImports.html b/dom/base/test/jsmodules/test_multiTopLevelImports.html new file mode 100644 index 0000000000..583087b4f0 --- /dev/null +++ b/dom/base/test/jsmodules/test_multiTopLevelImports.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test importing multiple modules from top level</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results, [1, 2, 3]), 'Check modules imported'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_simple1.js"></script> +<script type="module" src="module_simple2.js"></script> +<script type="module" src="module_simple3.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_multiTopLevelLargeImports.html b/dom/base/test/jsmodules/test_multiTopLevelLargeImports.html new file mode 100644 index 0000000000..6fd237c860 --- /dev/null +++ b/dom/base/test/jsmodules/test_multiTopLevelLargeImports.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test a importing large modules which may be compiled off main thread</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results, [1, 2, 3]), 'Check modules imported'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_large1.js"></script> +<script type="module" src="module_simple2.js"></script> +<script type="module" src="module_large3.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_scriptInsertedModule.html b/dom/base/test/jsmodules/test_scriptInsertedModule.html new file mode 100644 index 0000000000..0afc259f8c --- /dev/null +++ b/dom/base/test/jsmodules/test_scriptInsertedModule.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test a script-inserted module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var result; + + let script = document.createElement("script"); + script.type = "module"; + script.src = "./module_simpleImport.js"; + document.head.appendChild(script); + + SimpleTest.waitForExplicitFinish(); + + function testLoaded() { + ok(result == 42); + SimpleTest.finish(); + } +</script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_scriptModuleOrder.html b/dom/base/test/jsmodules/test_scriptModuleOrder.html new file mode 100644 index 0000000000..ffc1350068 --- /dev/null +++ b/dom/base/test/jsmodules/test_scriptModuleOrder.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test execution order of deferred scripts and modules </title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results, [1, 2, 3]), 'Check execution order'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_simple1.js"></script> +<script defer src="script_simple2.js"></script> +<script type="module" src="module_simple3.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_scriptNotParsedAsModule.html b/dom/base/test/jsmodules/test_scriptNotParsedAsModule.html new file mode 100644 index 0000000000..c832907768 --- /dev/null +++ b/dom/base/test/jsmodules/test_scriptNotParsedAsModule.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test classic script not parsed as module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + hadSyntaxError = error instanceof SyntaxError; + } + + function testError() { + ok(!wasRun, 'Check script was not run'); + ok(hadSyntaxError, 'Check that a SyntaxError was thrown'); + SimpleTest.finish(); + } +</script> +<script src="module_testSyntax.js"></script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_simpleImport.html b/dom/base/test/jsmodules/test_simpleImport.html new file mode 100644 index 0000000000..4c836cd318 --- /dev/null +++ b/dom/base/test/jsmodules/test_simpleImport.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test a simple module import</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var result; + + SimpleTest.waitForExplicitFinish(); + + function testLoaded() { + ok(result == 42, 'Check imported value'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_simpleImport.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_syntaxError.html b/dom/base/test/jsmodules/test_syntaxError.html new file mode 100644 index 0000000000..53f95c96cc --- /dev/null +++ b/dom/base/test/jsmodules/test_syntaxError.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test syntax errors parsing a module are reported</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + hadSyntaxError = error instanceof SyntaxError; + } + + function testError() { + ok(!wasRun, 'Check script was not run'); + ok(hadSyntaxError, 'Check that a SyntaxError was thrown'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_badSyntax.js"></script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_syntaxErrorAsync.html b/dom/base/test/jsmodules/test_syntaxErrorAsync.html new file mode 100644 index 0000000000..35d9237553 --- /dev/null +++ b/dom/base/test/jsmodules/test_syntaxErrorAsync.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test syntax errors parsing an async module are reported</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + hadSyntaxError = error instanceof SyntaxError; + } + + function testError() { + ok(!wasRun, 'Check script was not run'); + ok(hadSyntaxError, 'Check that a SyntaxError was thrown'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_badSyntax.js" async></script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_syntaxErrorInline.html b/dom/base/test/jsmodules/test_syntaxErrorInline.html new file mode 100644 index 0000000000..705bc5902e --- /dev/null +++ b/dom/base/test/jsmodules/test_syntaxErrorInline.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test syntax errors parsing an inline module are reported</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + hadSyntaxError = error instanceof SyntaxError; + } + + function testError() { + ok(!wasRun, 'Check script was not run'); + ok(hadSyntaxError, 'Check that a SyntaxError was thrown'); + SimpleTest.finish(); + } +</script> +<script type="module"> +// Module with a syntax error. +some invalid js syntax; +wasRun = true; +</script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_syntaxErrorInlineAsync.html b/dom/base/test/jsmodules/test_syntaxErrorInlineAsync.html new file mode 100644 index 0000000000..5e79928234 --- /dev/null +++ b/dom/base/test/jsmodules/test_syntaxErrorInlineAsync.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test syntax errors parsing an inline async module are reported</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var wasRun = false; + var hadSyntaxError = false; + + SimpleTest.waitForExplicitFinish(); + window.onerror = handleError; + + function handleError(message, url, line, column, error) { + hadSyntaxError = error instanceof SyntaxError; + } + + function testError() { + ok(!wasRun, 'Check script was not run'); + ok(hadSyntaxError, 'Check that a SyntaxError was thrown'); + SimpleTest.finish(); + } +</script> +<script type="module" async> +// Module with a syntax error. +some invalid js syntax; +wasRun = true; +</script> +<body onload='testError()'></body> diff --git a/dom/base/test/jsmodules/test_topLevelIntroType.html b/dom/base/test/jsmodules/test_topLevelIntroType.html new file mode 100644 index 0000000000..ab4c80815b --- /dev/null +++ b/dom/base/test/jsmodules/test_topLevelIntroType.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test introduction type of a top-level module</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var introType; + var extractIntroType; + + info('start'); + SimpleTest.waitForExplicitFinish(); + + function testIntroductionType() { + extractIntroType(); + ok(introType == "scriptElement", 'Check introduction type'); + SimpleTest.finish(); + } +</script> +<iframe src="iframe_extractIntroType.html"></iframe> +<script type="module" src="module_extractIntroType.js"> +</script> +<body onload='testIntroductionType()'></body> diff --git a/dom/base/test/jsmodules/test_toplevelModuleMemoization.html b/dom/base/test/jsmodules/test_toplevelModuleMemoization.html new file mode 100644 index 0000000000..0e1ee728e4 --- /dev/null +++ b/dom/base/test/jsmodules/test_toplevelModuleMemoization.html @@ -0,0 +1,30 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test toplevel modules are momoized and only loaded once</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var results = []; + + SimpleTest.waitForExplicitFinish(); + + function arrayEquals(a, b) { + if (a.length != b.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + return true; + } + } + + function testLoaded() { + ok(arrayEquals(results, [1]), 'Check execution order'); + SimpleTest.finish(); + } +</script> +<script type="module" src="module_simple1.js"></script> +<script type="module" src="module_simple1.js"></script> +<script type="module" src="module_simple1.js"></script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/jsmodules/test_typeAttrCaseInsensitive.html b/dom/base/test/jsmodules/test_typeAttrCaseInsensitive.html new file mode 100644 index 0000000000..7a3f937406 --- /dev/null +++ b/dom/base/test/jsmodules/test_typeAttrCaseInsensitive.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test script element's type attribute comparision is case-insensitive</title> +<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> +<script> + var inlineModuleRan = false; + var moduleRan = false; + + SimpleTest.waitForExplicitFinish(); + + function testLoaded() { + ok(moduleRan, 'Check module script was run'); + ok(inlineModuleRan, 'Check inline module script was run'); + SimpleTest.finish(); + } +</script> +<script type="MODULE" src="module_setRan.js"></script> +<script type="mOdUlE">inlineModuleRan = true;</script> +<body onload='testLoaded()'></body> diff --git a/dom/base/test/mochitest.ini b/dom/base/test/mochitest.ini new file mode 100644 index 0000000000..ea86290d97 --- /dev/null +++ b/dom/base/test/mochitest.ini @@ -0,0 +1,820 @@ +[DEFAULT] +support-files = + audio.ogg + audioEndedDuringPlaying.webm + iframe_bug962251.html + iframe_bug976673.html + iframe_main_bug1022229.html + iframe_sandbox_bug1022229.html + file_empty.html + iframe_postMessage_solidus.html + file_setname.html + 345339_iframe.html + Ahem.ttf + accesscontrol.resource + accesscontrol.resource^headers^ + badContentType.eventsource + badContentType.eventsource^headers^ + badHTTPResponseCode.eventsource + badHTTPResponseCode.eventsource^headers^ + badMessageEvent.eventsource + badMessageEvent.eventsource^headers^ + badMessageEvent2.eventsource + badMessageEvent2.eventsource^headers^ + bug282547.sjs + bug298064-subframe.html + bug313646.txt + bug382113_object.html + bug403852_fileOpener.js + bug419132.html + bug426308-redirect.sjs + bug435425.sjs + bug435425_redirect.sjs + bug444322.js + bug444322.txt + bug455629-helper.svg + bug457746.sjs + bug461735-post-redirect.js + bug461735-redirect1.sjs + bug461735-redirect2.sjs + bug466080.sjs + bug466409-empty.css + bug466409-page.html + bug475156.sjs + bug482935.sjs + bug540854.sjs + bug578096LoadChromeScript.js + bug638112-response.txt + bug638112.sjs + bug696301-script-1.js + bug696301-script-1.js^headers^ + bug696301-script-2.js + bug704320.sjs + bug704320_counter.sjs + bug819051.sjs + chrome/bug418986-1.js + copypaste.js + create_file_objects.js + delayedServerEvents.sjs + eventsource.resource + eventsource.resource^headers^ + eventsource_redirect.resource + eventsource_redirect.resource^headers^ + eventsource_redirect_to.resource + eventsource_redirect_to.resource^headers^ + file_base_xbl.xml + file_bug1091883_frame.html + file_bug1091883_subframe.html + file_bug1091883_target.html + file_bug28293.sjs + file_bug326337.xml + file_bug326337_inner.html + file_bug326337_outer.html + file_bug416317.xhtml + file_bug426646-1.html + file_bug426646-2.html + file_bug428847-1.xhtml + file_bug428847-2.xhtml + file_bug498897.css + file_bug498897.html + file_bug498897.html^headers^ + file_bug503481.sjs + file_bug503481b_inner.html + file_bug541937.html + file_bug541937.xhtml + file_bug557892.html + file_bug562137.txt + file_bug590812-ref.xhtml + file_bug590812.xml + file_bug590870.html + file_bug601803a.html + file_bug601803b.html + file_bug604660-1.xml + file_bug604660-2.xsl + file_bug604660-3.js + file_bug604660-4.js + file_bug604660-5.xml + file_bug604660-6.xsl + file_bug622088.sjs + file_bug622088_inner.html + file_bug675121.sjs + file_bug687859-16.js + file_bug687859-16.js^headers^ + file_bug687859-bom.js + file_bug687859-bom.js^headers^ + file_bug687859-charset.js + file_bug687859-http.js + file_bug687859-http.js^headers^ + file_bug687859-inherit.js + file_bug692434.xml + file_bug704320_preload_common.js + file_bug704320_preload_reuse.html + file_bug704320_preload_noreuse.html + file_bug704320_redirect.html + file_bug707142_baseline.json + file_bug707142_bom.json + file_bug707142_utf-16.json + file_bug708620-2.html + file_bug708620.html + file_bug769117.html + file_bug782342.txt + file_bug787778.sjs + file_bug804395.jar + file_bug869432.eventsource + file_bug869432.eventsource^headers^ + file_bug902350.html + file_bug902350_frame.html + file_bug907892.html + file_bug945152.jar + file_bug1263696_frame_pass.html + file_bug1263696_frame_fail.html + file_bug1274806.html + file_general_document.html + file_htmlserializer_1.html + file_htmlserializer_1_bodyonly.html + file_htmlserializer_1_format.html + file_htmlserializer_1_linebreak.html + file_htmlserializer_1_links.html + file_htmlserializer_1_nested_body.html + file_htmlserializer_1_no_body.html + file_htmlserializer_1_noflag.html + file_htmlserializer_1_noformatpre.html + file_htmlserializer_1_raw.html + file_htmlserializer_1_sibling_body.html + file_htmlserializer_1_sibling_body_only_body.html + file_htmlserializer_1_wrap.html + file_htmlserializer_2.html + file_htmlserializer_2_basic.html + file_htmlserializer_2_enthtml.html + file_htmlserializer_2_entw3c.html + file_htmlserializer_2_latin1.html + file_htmlserializer_ipv6.html + file_htmlserializer_ipv6_out.html + file_lock_orientation.html + file_mozfiledataurl_audio.ogg + file_mozfiledataurl_doc.html + file_mozfiledataurl_img.jpg + file_mozfiledataurl_inner.html + file_mozfiledataurl_text.txt + file_record_orientation.html + file_restrictedEventSource.sjs + file_simplecontentpolicy.js + file_timer_flood.html + file_websocket_basic_wsh.py + file_websocket_hello_wsh.py + file_websocket_http_resource.txt + file_websocket_permessage_deflate_wsh.py + file_websocket_permessage_deflate_disabled_wsh.py + file_websocket_permessage_deflate_rejected_wsh.py + file_websocket_permessage_deflate_params_wsh.py + file_websocket_wsh.py + file_x-frame-options_main.html + file_x-frame-options_page.sjs + file_xhtmlserializer_1.xhtml + file_xhtmlserializer_1_bodyonly.xhtml + file_xhtmlserializer_1_format.xhtml + file_xhtmlserializer_1_linebreak.xhtml + file_xhtmlserializer_1_links.xhtml + file_xhtmlserializer_1_nested_body.xhtml + file_xhtmlserializer_1_no_body.xhtml + file_xhtmlserializer_1_noflag.xhtml + file_xhtmlserializer_1_noformatpre.xhtml + file_xhtmlserializer_1_raw.xhtml + file_xhtmlserializer_1_sibling_body.xhtml + file_xhtmlserializer_1_sibling_body_only_body.xhtml + file_xhtmlserializer_1_wrap.xhtml + file_xhtmlserializer_2.xhtml + file_xhtmlserializer_2_basic.xhtml + file_xhtmlserializer_2_enthtml.xhtml + file_xhtmlserializer_2_entw3c.xhtml + file_xhtmlserializer_2_latin1.xhtml + file_youtube_flash_embed.html + fileapi_chromeScript.js + fileutils.js + forRemoval.resource + forRemoval.resource^headers^ + formReset.html + invalid_accesscontrol.resource + invalid_accesscontrol.resource^headers^ + mutationobserver_dialog.html + orientationcommon.js + script-1_bug597345.sjs + script-2_bug597345.js + script_bug602838.sjs + send_gzip_content.sjs + somedatas.resource + somedatas.resource^headers^ + variable_style_sheet.sjs + viewport_helpers.js + w3element_traversal.svg + wholeTexty-helper.xml + file_nonascii_blob_url.html + referrerHelper.js + img_referrer_testserver.sjs + file_audioLoop.html + file_webaudioLoop.html + file_webaudioLoop2.html + file_pluginAudio.html + file_pluginAudioNonAutoStart.html + noaudio.webm + referrer_helper.js + referrer_testserver.sjs + script_postmessages_fileList.js + iframe_postMessages.html + test_anonymousContent_style_csp.html^headers^ + file_explicit_user_agent.sjs + referrer_change_server.sjs + file_change_policy_redirect.html + file_bug1198095.js + file_bug1250148.sjs + file_bug1268962.sjs + mozbrowser_api_utils.js + websocket_helpers.js + websocket_tests.js + !/dom/html/test/form_submit_server.sjs + !/dom/security/test/cors/file_CrossSiteXHR_server.sjs + !/image/test/mochitest/blue.png + !/dom/xhr/tests/file_XHRSendData.sjs + script_bug1238440.js + file_blobURL_expiring.html + intersectionobserver_iframe.html + intersectionobserver_window.html + +[test_anchor_area_referrer.html] +[test_anchor_area_referrer_changing.html] +[test_anchor_area_referrer_invalid.html] +[test_anchor_area_referrer_rel.html] +[test_anonymousContent_api.html] +[test_anonymousContent_append_after_reflow.html] +[test_anonymousContent_canvas.html] +[test_anonymousContent_insert.html] +[test_anonymousContent_manipulate_content.html] +[test_anonymousContent_style_csp.html] +[test_applet_alternate_content.html] +[test_appname_override.html] +[test_async_setTimeout_stack.html] +[test_async_setTimeout_stack_across_globals.html] +[test_audioWindowUtils.html] +[test_audioNotification.html] +tags = audiochannel +[test_audioNotificationSilent_audioFile.html] +tags = audiochannel +[test_audioNotificationSilent_webAudio.html] +tags = audiochannel +[test_audioNotificationStream.html] +tags = audiochannel +[test_audioNotificationStopOnNavigation.html] +tags = audiochannel +[test_audioNotificationWithEarlyPlay.html] +tags = audiochannel +[test_base.xhtml] +[test_blob_fragment_and_query.html] +[test_blobconstructor.html] +[test_blobURL_expiring.html] +[test_bug5141.html] +[test_bug28293.html] +[test_bug28293.xhtml] +[test_bug51034.html] +[test_bug116083.html] +subsuite = clipboard +[test_bug166235.html] +subsuite = clipboard +skip-if = toolkit == 'android' +[test_bug199959.html] +[test_bug218236.html] +[test_bug218277.html] +[test_bug238409.html] +[test_bug254337.html] +[test_bug270145.xhtml] +[test_bug276037-1.html] +[test_bug276037-2.xhtml] +[test_bug282547.html] +[test_bug298064.html] +[test_bug300992.html] +[test_bug311681.xml] +[test_bug313646.html] +[test_bug320799.html] +[test_bug322317.html] +[test_bug326337.html] +[test_bug330925.xhtml] +[test_bug331959.html] +[test_bug333064.html] +skip-if = toolkit == 'android' +[test_bug333198.html] +[test_bug333673.html] +[test_bug337631.html] +[test_bug338541.xhtml] +[test_bug338583.html] +skip-if = toolkit == 'android' +[test_bug338679.html] +[test_bug339494.html] +[test_bug339494.xhtml] +[test_bug340571.html] +[test_bug343596.html] +[test_bug345339.html] +[test_bug346485.html] +[test_bug352728.html] +[test_bug352728.xhtml] +[test_bug353334.html] +[test_bug355026.html] +[test_bug357450.html] +support-files = file_bug357450.js +[test_bug357450.xhtml] +[test_bug357450_svg.xhtml] +[test_bug357509.html] +[test_bug358660.html] +[test_bug362391.xhtml] +[test_bug364092.xhtml] +[test_bug364413.xhtml] +[test_bug366944.html] +[test_bug366946.html] +[test_bug367164.html] +[test_bug368972.html] +[test_bug371576-2.html] +[test_bug371576-3.html] +[test_bug371576-4.html] +[test_bug371576-5.html] +[test_bug372086.html] +[test_bug372964-2.html] +[test_bug372964.html] +[test_bug373181.xhtml] +[test_bug375314.html] +[test_bug378969.html] +[test_bug380418.html] +support-files = test_bug380418.html^headers^ +[test_bug382113.html] +[test_bug382871.html] +[test_bug384003.xhtml] +[test_bug390219.html] +[test_bug390735.html] +[test_bug392318.html] +[test_bug392511.html] +[test_bug393968.html] +[test_bug395915.html] +[test_bug397234.html] +[test_bug398243.html] +[test_bug401662.html] +[test_bug402150.html] +support-files = test_bug402150.html^headers^ +[test_bug403841.html] +[test_bug403852.html] +[test_bug403868.xml] +[test_bug405182.html] +[test_bug409380.html] +[test_bug410229.html] +[test_bug413974.html] +[test_bug414190.html] +[test_bug415860.html] +[test_bug416317-1.html] +[test_bug416317-2.html] +[test_bug416383.html] +[test_bug417255.html] +[test_bug417384.html] +[test_bug418214.html] +[test_bug418986-1.html] +[test_bug419132.html] +[test_bug419527.xhtml] +[test_bug420609.xhtml] +[test_bug420700.html] +[test_bug421602.html] +[test_bug422403-1.html] +[test_bug422403-2.xhtml] +[test_bug422537.html] +[test_bug424212.html] +[test_bug424359-1.html] +[test_bug424359-2.html] +[test_bug426308.html] +[test_bug426646.html] +[test_bug428847.html] +[test_bug429157.html] +[test_bug431082.html] +[test_bug431701.html] +[test_bug431833.html] +[test_bug433533.html] +[test_bug433662.html] +[test_bug435425.html] +[test_bug444030.xhtml] +[test_bug444322.html] +[test_bug444546.html] +disabled = Disabled for now. Mochitest isn't reliable enough for these. +support-files = bug444546.sjs +[test_bug444722.html] +[test_bug448993.html] +[test_bug450160.html] +[test_bug451376.html] +[test_bug453521.html] +[test_bug453736.html] +[test_bug454325.html] +[test_bug454326.html] +[test_bug455472.html] +[test_bug455629.html] +[test_bug456262.html] +[test_bug457746.html] +[test_bug459424.html] +[test_bug461555.html] +[test_bug461735.html] +[test_bug465767.html] +[test_bug466080.html] +[test_bug466409.html] +[test_bug466751.xhtml] +[test_bug469020.html] +[test_bug469304.html] +[test_bug473162-1.html] +[test_bug473162-2.html] +[test_bug475156.html] +skip-if = toolkit == 'android' #bug 855762 +[test_bug482935.html] +skip-if = toolkit == 'android' #bug 855762 +[test_bug484396.html] +[test_bug493881.html] +support-files = test_bug493881.js +[test_bug498240.html] +[test_bug498433.html] +[test_bug498897.html] +[test_bug499656.html] +[test_bug499656.xhtml] +[test_bug500937.html] +[test_bug503473.html] +disabled = Disabled due to making the harness time out +support-files = file_bug503473-frame.sjs +[test_bug503481.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_bug503481b.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_bug505783.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_bug513194.html] +[test_bug514487.html] +[test_bug515401.html] +[test_bug518104.html] +[test_bug527896.html] +[test_bug540854.html] +[test_bug541937.html] +[test_bug544642.html] +[test_bug545644.html] +[test_bug545644.xhtml] +[test_bug548463.html] +[test_bug553896.xhtml] +[test_bug557892.html] +[test_bug558726.html] +[test_bug559526.html] +[test_bug560780.html] +skip-if = (os == "android") # Failure with AccessibleCarets on Android, bug 1230229 +[test_bug562137.html] +[test_bug562169-1.html] +[test_bug562169-2.html] +[test_bug562652.html] +[test_bug564047.html] +[test_bug564863.xhtml] +[test_bug567350.html] +[test_bug574596.html] +skip-if = toolkit == 'android' +[test_bug578096.html] +[test_bug585978.html] +[test_bug587931.html] +[test_bug588990.html] +[test_bug590812.html] +skip-if = toolkit == 'android' #bug 687032 +[test_bug590870.html] +[test_bug592366.html] +[test_bug592829.html] +[test_bug597345.html] +[test_bug599295.html] +[test_bug599588.html] +[test_bug601803.html] +[test_bug602838.html] +[test_bug604592.html] +[test_bug604660.html] +[test_bug605982.html] +[test_bug606729.html] +[test_bug614058.html] +[test_bug614583.html] +[test_bug622088.html] +[test_bug622117.html] +[test_bug622246.html] +[test_bug625722.html] +[test_bug626262.html] +[test_bug628938.html] +[test_bug631615.html] +[test_bug638112.html] +[test_bug647518.html] +[test_bug650001.html] +[test_bug650776.html] +[test_bug650784.html] +[test_bug656283.html] +[test_bug664916.html] +[test_bug666604.html] +[test_bug675121.html] +[test_bug675166.html] +[test_bug682463.html] +[test_bug682554.html] +[test_bug682592.html] +[test_bug684671.html] +[test_bug685798.html] +[test_bug686449.xhtml] +[test_bug687859.html] +[test_bug690056.html] +[test_bug692434.html] +[test_bug693615.html] +[test_bug693875.html] +[test_bug694754.xhtml] +[test_bug696301-1.html] +[test_bug696301-2.html] +[test_bug698381.html] +[test_bug698384.html] +[test_bug704063.html] +[test_bug704320.html] +[test_bug704320_policyset.html] +[test_bug704320_policyset2.html] +[test_bug704320_preload.html] +[test_bug707142.html] +[test_bug708620.html] +[test_bug711047.html] +[test_bug711180.html] +[test_bug719533.html] +[test_bug726364.html] +[test_bug737087.html] +[test_bug737565.html] +[test_bug737612.html] +[test_bug738108.html] +[test_bug744830.html] +[test_bug749367.html] +[test_bug750096.html] +[test_bug753278.html] +[test_bug761120.html] +[test_bug769117.html] +[test_bug782342.html] +[test_bug787778.html] +[test_bug789315.html] +[test_bug789856.html] +[test_bug793311.html] +[test_bug804395.html] +[test_bug809003.html] +[test_bug810494.html] +[test_bug811701.html] +[test_bug811701.xhtml] +[test_bug813919.html] +[test_bug814576.html] +[test_bug819051.html] +[test_bug820909.html] +[test_bug840098.html] +[test_bug864595.html] +[test_bug868999.html] +[test_bug869000.html] +[test_bug869002.html] +[test_bug869006.html] +[test_bug876282.html] +[test_bug890580.html] +[test_bug891952.html] +[test_bug894874.html] +[test_bug895239.html] +[test_bug895974.html] +[test_bug902847.html] +[test_bug907892.html] +[test_bug913761.html] +[test_bug922681.html] +[test_bug927196.html] +[test_bug962251.html] +[test_bug976673.html] +[test_bug982153.html] +[test_bug999456.html] +[test_bug1022229.html] +[test_bug1025933.html] +[test_bug1037687.html] +[test_bug1043106.html] +[test_bug1057176.html] +[test_bug1060938.html] +[test_bug1064481.html] +[test_bug1070015.html] +[test_bug1075702.html] +[test_bug1081686.html] +skip-if = toolkit == 'android' +[test_bug1091883.html] +[test_bug1101364.html] +skip-if = toolkit == 'android' +[test_bug1118689.html] +[test_bug1126851.html] +[test_bug1163743.html] +[test_bug1165501.html] +[test_bug1187157.html] +[test_bug1198095.html] +[test_bug1238440.html] +[test_bug1250148.html] +[test_bug1259588.html] +[test_bug1263696.html] +[test_bug1268962.html] +[test_bug1274806.html] +[test_bug1281963.html] +[test_bug1295852.html] +[test_bug1307730.html] +[test_bug1308069.html] +[test_bug1314032.html] +[test_caretPositionFromPoint.html] +[test_change_policy.html] +[test_classList.html] +[test_clearTimeoutIntervalNoArg.html] +[test_constructor-assignment.html] +[test_constructor.html] +[test_copyimage.html] +subsuite = clipboard +skip-if = toolkit == 'android' #bug 904183 +[test_copypaste.html] +subsuite = clipboard +skip-if = toolkit == 'android' #bug 904183 +[test_copypaste.xhtml] +subsuite = clipboard +skip-if = toolkit == 'android' #bug 904183 +[test_createHTMLDocument.html] +[test_declare_stylesheet_obsolete.html] +[test_dialogArguments.html] +tags = openwindow +skip-if = toolkit == 'android' || e10s # showmodaldialog +[test_document.all_iteration.html] +[test_document.all_unqualified.html] +[test_document_constructor.html] +[test_document_importNode_document.html] +[test_document_register.html] +[test_domcursor.html] +[test_domparser_null_char.html] +[test_domparsing.html] +[test_domrequest.html] +[test_domwindowutils.html] +[test_e4x_for_each.html] +[test_element.matches.html] +[test_element_closest.html] +[test_elementTraversal.html] +[test_encodeToStringWithMaxLength.html] +[test_error.html] +[test_EventSource_redirects.html] +[test_explicit_user_agent.html] +[test_file_from_blob.html] +[test_file_negative_date.html] +[test_fileapi.html] +[test_fileapi_slice.html] +skip-if = (toolkit == 'android') # Android: Bug 775227 +[test_getAttribute_after_createAttribute.html] +[test_getElementById.html] +[test_getTranslationNodes.html] +[test_getTranslationNodes_limit.html] +[test_gsp-qualified.html] +[test_gsp-quirks.html] +[test_gsp-standards.html] +[test_history_document_open.html] +[test_history_state_null.html] +[test_html_colors_quirks.html] +[test_html_colors_standards.html] +[test_htmlcopyencoder.html] +[test_htmlcopyencoder.xhtml] +[test_iframe_referrer.html] +[test_iframe_referrer_changing.html] +[test_iframe_referrer_invalid.html] +[test_Image_constructor.html] +[test_img_referrer.html] +[test_innersize_scrollport.html] +[test_integer_attr_with_leading_zero.html] +[test_intersectionobservers.html] +skip-if = true # Track Bug 1320704 +[test_ipc_messagemanager_blob.html] +[test_link_prefetch.html] +skip-if = !e10s # Track Bug 1281415 +[test_link_stylesheet.html] +[test_messagemanager_targetchain.html] +[test_meta_viewport0.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_meta_viewport1.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_meta_viewport2.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_meta_viewport3.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_meta_viewport4.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_meta_viewport5.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_meta_viewport6.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_meta_viewport7.html] +skip-if = (os != 'android') # meta-viewport tag support is mobile-only +[test_mozbrowser_apis_blocked.html] +[test_mozfiledataurl.html] +skip-if = toolkit == 'android' #TIMED_OUT +[test_mozMatchesSelector.html] +[test_mutationobserver_anonymous.html] +[test_mutationobservers.html] +[test_named_frames.html] +[test_navigator_hardwareConcurrency.html] +[test_navigator_language.html] +[test_navigatorPrefOverride.html] +[test_noAudioNotification.html] +tags = audiochannel +[test_noAudioNotificationOnMutedElement.html] +tags = audiochannel +[test_noAudioNotificationOnMutedOrVolume0Element.html] +tags = audiochannel +[test_noAudioNotificationOnVolume0Element.html] +tags = audiochannel +[test_NodeIterator_basics_filters.xhtml] +[test_NodeIterator_mutations_1.xhtml] +[test_NodeIterator_mutations_2.html] +[test_NodeIterator_mutations_3.html] +[test_nodelist_holes.html] +[test_nonascii_blob_url.html] +[test_noWebAudioNotification.html] +tags = audiochannel +[test_open_null_features.html] +[test_openDialogChromeOnly.html] +tags = openwindow +[test_orientation_alternate.html] +skip-if = true # bug 1312417 +[test_orientation_frame.html] +skip-if = true # bug 1312417 +[test_orientation_frame_lock.html] +skip-if = true # bug 1312417 +[test_orientation_sandbox_no_lock.html] +skip-if = true # bug 1312417 +[test_plugin_freezing.html] +skip-if = toolkit == 'android' #CLICK_TO_PLAY +[test_pluginAudioNotification.html] +tags = audiochannel +skip-if = toolkit == 'android' # Plugins don't work on Android +[test_pluginMutedBeforePlay.html] +tags = audiochannel +skip-if = toolkit == 'android' # Plugins don't work on Android +[test_postMessage_solidus.html] +[test_postMessages.html] +support-files = worker_postMessages.js +[test_postMessage_originAttributes.html] +support-files = file_receiveMessage.html +[test_processing_instruction_update_stylesheet.xhtml] +[test_progress_events_for_gzip_data.html] +[test_range_bounds.html] +skip-if = toolkit == 'android' +[test_reentrant_flush.html] +skip-if = toolkit == 'android' +[test_referrer_redirect.html] +[test_root_iframe.html] +[test_screen_orientation.html] +[test_script_loader_crossorigin_data_url.html] +[test_setInterval_uncatchable_exception.html] +skip-if = debug == false +[test_settimeout_extra_arguments.html] +[test_settimeout_inner.html] +[test_setTimeoutWith0.html] +[test_setting_opener.html] +[test_simplecontentpolicy.html] +skip-if = e10s # Bug 1156489. +[test_text_wholeText.html] +[test_textnode_normalize_in_selection.html] +[test_textnode_split_in_selection.html] +[test_timer_flood.html] +[test_title.html] +[test_treewalker_nextsibling.xml] +[test_user_select.html] +skip-if = toolkit == 'android' +[test_viewport_scroll.html] +[test_viewsource_forbidden_in_object.html] +[test_w3element_traversal.html] +[test_w3element_traversal.xhtml] +[test_w3element_traversal_svg.html] +[test_warning_for_blocked_cross_site_request.html] +[test_webaudioNotification.html] +tags = audiochannel +[test_webaudioNotificationStopOnNavigation.html] +tags = audiochannel +[test_websocket_basic.html] +skip-if = toolkit == 'android' +[test_websocket_hello.html] +skip-if = toolkit == 'android' +[test_websocket_permessage_deflate.html] +skip-if = toolkit == 'android' +[test_webSocket_sandbox.html] +skip-if = toolkit == 'android' +support-files = iframe_webSocket_sandbox.html +[test_websocket1.html] +skip-if = toolkit == 'android' +[test_websocket2.html] +skip-if = toolkit == 'android' +[test_websocket3.html] +skip-if = toolkit == 'android' +[test_websocket4.html] +skip-if = toolkit == 'android' +[test_websocket5.html] +skip-if = toolkit == 'android' +[test_window_constructor.html] +[test_window_cross_origin_props.html] +[test_window_define_nonconfigurable.html] +skip-if = release_or_beta +[test_window_define_symbol.html] +[test_window_element_enumeration.html] +[test_window_enumeration.html] +[test_window_extensible.html] +[test_window_indexing.html] +[test_window_named_frame_enumeration.html] +[test_window_orientation.html] +skip-if = true # bug 1312417 +[test_window_proto.html] +[test_writable-replaceable.html] +[test_x-frame-options.html] +[test_xbl_userdata.xhtml] +[test_youtube_flash_embed.html] +# Please keep alphabetical order. diff --git a/dom/base/test/moz.build b/dom/base/test/moz.build new file mode 100644 index 0000000000..5e60632e47 --- /dev/null +++ b/dom/base/test/moz.build @@ -0,0 +1,37 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +XPCSHELL_TESTS_MANIFESTS += [ + 'unit/xpcshell.ini', + 'unit_ipc/xpcshell.ini', +] + +MOCHITEST_MANIFESTS += [ + 'mochitest.ini', + 'websocket_hybi/mochitest.ini', +] + +MOCHITEST_CHROME_MANIFESTS += [ + 'chrome.ini', + 'chrome/chrome.ini', +] + +BROWSER_CHROME_MANIFESTS += [ + 'browser.ini', +] + +TEST_DIRS += [ + 'gtest', + 'jsmodules' +] + +TEST_HARNESS_FILES.testing.mochitest.tests.dom.base.test.chrome += [ + 'chrome/bug421622-referer.sjs', + 'chrome/bug884693.sjs', + 'chrome/nochrome_bug765993.html', + 'chrome/nochrome_bug765993.js', + 'chrome/nochrome_bug765993.js^headers^', +] diff --git a/dom/base/test/mozbrowser_api_utils.js b/dom/base/test/mozbrowser_api_utils.js new file mode 100644 index 0000000000..92b0809390 --- /dev/null +++ b/dom/base/test/mozbrowser_api_utils.js @@ -0,0 +1,72 @@ +const FRAME_URL = "http://example.org/"; + +const METHODS = { + setVisible: {}, + getVisible: {}, + setActive: {}, + getActive: {}, + addNextPaintListener: {}, + removeNextPaintListener: {}, + sendMouseEvent: {}, + sendTouchEvent: {}, + goBack: {}, + goForward: {}, + reload: {}, + stop: {}, + download: {}, + purgeHistory: {}, + getScreenshot: {}, + zoom: {}, + getCanGoBack: {}, + getCanGoForward: {}, + getContentDimensions: {}, + setInputMethodActive: {}, + findAll: {}, + findNext: {}, + clearMatch: {}, + executeScript: {}, + getWebManifest: {}, + mute: {}, + unmute: {}, + getMuted: {}, + setVolume: {}, + getVolume: {}, +}; + +const ATTRIBUTES = [ + "allowedAudioChannels", +]; + +function once(target, eventName, useCapture = false) { + info("Waiting for event: '" + JSON.stringify(eventName) + "' on " + target + "."); + + return new Promise(resolve => { + for (let [add, remove] of [ + ["addEventListener", "removeEventListener"], + ["addMessageListener", "removeMessageListener"], + ]) { + if ((add in target) && (remove in target)) { + eventName.forEach(evName => { + target[add](evName, function onEvent(...aArgs) { + info("Got event: '" + evName + "' on " + target + "."); + target[remove](evName, onEvent, useCapture); + resolve(aArgs); + }, useCapture); + }); + break; + } + } + }); +} + +function* loadFrame(attributes = {}) { + let iframe = document.createElement("iframe"); + iframe.setAttribute("src", FRAME_URL); + for (let key in attributes) { + iframe.setAttribute(key, attributes[key]); + } + let loaded = once(iframe, [ "load", "mozbrowserloadend" ]); + document.body.appendChild(iframe); + yield loaded; + return iframe; +} diff --git a/dom/base/test/mutationobserver_dialog.html b/dom/base/test/mutationobserver_dialog.html new file mode 100644 index 0000000000..2cc8153099 --- /dev/null +++ b/dom/base/test/mutationobserver_dialog.html @@ -0,0 +1,62 @@ +<html> + <head> + <title></title> + <script> + + var div = document.createElement("div"); + + var M; + if ("MozMutationObserver" in window) { + M = window.MozMutationObserver; + } else if ("WebKitMutationObserver" in window) { + M = window.WebKitMutationObserver; + } else { + M = window.MutationObserver; + } + + var didCall1 = false; + var didCall2 = false; + function testMutationObserverInDialog() { + div.innerHTML = "<span>1</span><span>2</span>"; + m = new M(function(records, observer) { + opener.is(records[0].type, "childList", "Should have got childList"); + opener.is(records[0].removedNodes.length, 2, "Should have got removedNodes"); + opener.is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + observer.disconnect(); + m = null; + didCall1 = true; + }); + m.observe(div, { childList: true }); + div.innerHTML = "<span><span>foo</span></span>"; + } + + function testMutationObserverInDialog2() { + div.innerHTML = "<span>1</span><span>2</span>"; + m = new M(function(records, observer) { + opener.is(records[0].type, "childList", "Should have got childList"); + opener.is(records[0].removedNodes.length, 2, "Should have got removedNodes"); + opener.is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + observer.disconnect(); + m = null; + didCall2 = true; + }); + m.observe(div, { childList: true }); + div.innerHTML = "<span><span>foo</span></span>"; + } + + window.addEventListener("load", testMutationObserverInDialog); + window.addEventListener("load", testMutationObserverInDialog2); + window.addEventListener("load", + function() { + opener.ok(didCall1, "Should have called 1st mutation callback"); + opener.ok(didCall2, "Should have called 2nd mutation callback"); + window.close(); + }); + </script> + <style> + </style> + </head> + <body> + <input type="button" onclick="window.close()" value="close"> + </body> +</html> diff --git a/dom/base/test/noaudio.webm b/dom/base/test/noaudio.webm Binary files differnew file mode 100644 index 0000000000..9207017fb6 --- /dev/null +++ b/dom/base/test/noaudio.webm diff --git a/dom/base/test/orientationcommon.js b/dom/base/test/orientationcommon.js new file mode 100644 index 0000000000..2d87cf7207 --- /dev/null +++ b/dom/base/test/orientationcommon.js @@ -0,0 +1,21 @@ +function specialPowersLock(orientation) { + return new Promise(function(resolve, reject) { + SpecialPowers.pushPrefEnv({ + 'set': [ ["dom.screenorientation.testing.non_fullscreen_lock_allow", true] ] + }, function() { + var p = screen.orientation.lock(orientation); + resolve(p); + }); + }); +} + +function specialPowersUnlock() { + return new Promise(function(resolve, reject) { + SpecialPowers.pushPrefEnv({ + 'set': [ ["dom.screenorientation.testing.non_fullscreen_lock_allow", true] ] + }, function() { + screen.orientation.unlock(); + resolve(); + }); + }); +} diff --git a/dom/base/test/referrerHelper.js b/dom/base/test/referrerHelper.js new file mode 100644 index 0000000000..207bf5f15f --- /dev/null +++ b/dom/base/test/referrerHelper.js @@ -0,0 +1,286 @@ +/** + * Listen for notifications from the child. + * These are sent in case of error, or when the loads we await have completed. + */ +window.addEventListener("message", function(event) { + if (event.data == "childLoadComplete") { + // all loads happen, continue the test. + advance(); + } else if (event.data == "childOverload") { + // too many loads happened in a test frame, abort. + ok(false, "Too many load handlers called in test."); + SimpleTest.finish(); + } else if (event.data.indexOf("fail-") == 0) { + // something else failed in the test frame, abort. + ok(false, "Child failed the test with error " + event.data.substr(5)); + SimpleTest.finish(); + }}); + + +/** + * helper to perform an XHR. + */ +function doXHR(url, onSuccess, onFail) { + var xhr = new XMLHttpRequest(); + xhr.onload = function () { + if (xhr.status == 200) { + onSuccess(xhr); + } else if (xhr.status == 418) { + // Ignore HSTS priming responses + return; + } else { + onFail(xhr); + } + }; + xhr.open('GET', url, true); + xhr.send(null); +} + + + +/** + * This triggers state-resetting on the counter server. + */ +function resetCounter() { + doXHR('/tests/dom/base/test/bug704320_counter.sjs?reset', + advance, + function(xhr) { + ok(false, "Need to be able to reset the request counter"); + SimpleTest.finish(); + }); +} + +/** + * Grabs the results via XHR and passes to checker. + */ +function checkIndividualResults(testname, expected) { + doXHR('/tests/dom/base/test/bug704320_counter.sjs?results', + function(xhr) { + var results = JSON.parse(xhr.responseText); + info(xhr.responseText); + + ok('img' in results, + testname + " test: some image loads required in results object."); + is(results['img'].count, 2, + testname + " Test: Expected 2 loads for image requests."); + + expected.forEach(function (ref) { + ok(results['img'].referrers.indexOf(ref) >= 0, + testname + " Test: Expected " + ref + " referrer policy in test, results were " + + JSON.stringify(results['img'].referrers) +"."); + }); + advance(); + }, + function(xhr) { + ok(false, "Can't get results from the counter server."); + SimpleTest.finish(); + }); +} + +/** + * Grabs the results via XHR and checks them + */ +function checkExpectedGlobalResults() { + var url = 'bug704320.sjs?action=get-test-results'; + doXHR(url, + function(xhr) { + var response = JSON.parse(xhr.response); + + for (type in response) { + for (scheme in response[type]) { + for (policy in response[type][scheme]) { + var expectedResult = EXPECTED_RESULTS[type] === undefined ? + EXPECTED_RESULTS['default'][scheme][policy] : + EXPECTED_RESULTS[type][scheme][policy]; + is(response[type][scheme][policy], expectedResult, type + ' ' + scheme + ' ' + policy); + } + } + } + advance(); + }, + function(xhr) { + ok(false, "Can't get results from the counter server."); + SimpleTest.finish(); + }); +} + + +var EXPECTED_RESULTS = { + // From docshell/base/nsDocShell.cpp: + // "If the document containing the hyperlink being audited was not retrieved + // over an encrypted connection and its address does not have the same + // origin as "ping URL", send a referrer." + 'link-ping': { + // Same-origin + 'http-to-http': { + 'no-referrer': '', + 'unsafe-url': '', + 'origin': '', + 'origin-when-cross-origin': '', + 'no-referrer-when-downgrade': '', + 'same-origin': '', + 'strict-origin': '', + 'strict-origin-when-cross-origin':'' + }, + 'http-to-https': { + 'no-referrer': '', + 'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url', + 'origin': 'http://example.com/', + 'origin-when-cross-origin': 'http://example.com/', + 'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade', + 'same-origin': '', + 'strict-origin': 'http://example.com/', + 'strict-origin-when-cross-origin':'http://example.com/' + }, + // Encrypted and not same-origin + 'https-to-http': { + 'no-referrer': '', + 'unsafe-url': '', + 'origin': '', + 'origin-when-cross-origin': '', + 'no-referrer-when-downgrade': '', + 'same-origin': '', + 'strict-origin': '', + 'strict-origin-when-cross-origin':'' + }, + // Encrypted + 'https-to-https': { + 'no-referrer': '', + 'unsafe-url': '', + 'origin': '', + 'origin-when-cross-origin': '', + 'no-referrer-when-downgrade': '', + 'same-origin': '', + 'strict-origin': '', + 'strict-origin-when-cross-origin':'' + } + }, + // form is tested in a 2nd level iframe. + 'form': { + 'http-to-http': { + 'no-referrer': '', + 'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=form', + 'origin': 'http://example.com/', + 'origin-when-cross-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin&type=form', + 'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=form', + 'same-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin&type=form', + 'strict-origin': 'http://example.com/', + 'strict-origin-when-cross-origin':'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin&type=form' + }, + 'http-to-https': { + 'no-referrer': '', + 'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=form', + 'origin': 'http://example.com/', + 'origin-when-cross-origin': 'http://example.com/', + 'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=form', + 'same-origin': '', + 'strict-origin': 'http://example.com/', + 'strict-origin-when-cross-origin':'http://example.com/' + }, + 'https-to-http': { + 'no-referrer': '', + 'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=form', + 'origin': 'https://example.com/', + 'origin-when-cross-origin': 'https://example.com/', + 'no-referrer-when-downgrade': '', + 'same-origin': '', + 'strict-origin': '', + 'strict-origin-when-cross-origin':'' + }, + 'https-to-https': { + 'no-referrer': '', + 'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=form', + 'origin': 'https://example.com/', + 'origin-when-cross-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin&type=form', + 'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=form', + 'same-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin&type=form', + 'strict-origin': 'https://example.com/', + 'strict-origin-when-cross-origin':'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin&type=form' + } + }, + // window.location is tested in a 2nd level iframe. + 'window.location': { + 'http-to-http': { + 'no-referrer': '', + 'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=window.location', + 'origin': 'http://example.com/', + 'origin-when-cross-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin&type=window.location', + 'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=window.location', + 'same-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin&type=window.location', + 'strict-origin': 'http://example.com/', + 'strict-origin-when-cross-origin':'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin&type=window.location' + }, + 'http-to-https': { + 'no-referrer': '', + 'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=window.location', + 'origin': 'http://example.com/', + 'origin-when-cross-origin': 'http://example.com/', + 'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location', + 'same-origin': '', + 'strict-origin': 'http://example.com/', + 'strict-origin-when-cross-origin':'http://example.com/' + }, + 'https-to-http': { + 'no-referrer': '', + 'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=window.location', + 'origin': 'https://example.com/', + 'origin-when-cross-origin': 'https://example.com/', + 'no-referrer-when-downgrade': '', + 'same-origin': '', + 'strict-origin': '', + 'strict-origin-when-cross-origin':'' + }, + 'https-to-https': { + 'no-referrer': '', + 'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=window.location', + 'origin': 'https://example.com/', + 'origin-when-cross-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin&type=window.location', + 'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location', + 'same-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin&type=window.location', + 'strict-origin': 'https://example.com/', + 'strict-origin-when-cross-origin':'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin&type=window.location' + } + }, + 'default': { + 'http-to-http': { + 'no-referrer': '', + 'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url', + 'origin': 'http://example.com/', + 'origin-when-cross-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=origin-when-cross-origin', + 'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade', + 'same-origin': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=same-origin', + 'strict-origin': 'http://example.com/', + 'strict-origin-when-cross-origin':'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=strict-origin-when-cross-origin' + }, + 'http-to-https': { + 'no-referrer': '', + 'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url', + 'origin': 'http://example.com/', + 'origin-when-cross-origin': 'http://example.com/', + 'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade', + 'same-origin': '', + 'strict-origin': 'http://example.com/', + 'strict-origin-when-cross-origin':'http://example.com/' + }, + 'https-to-http': { + 'no-referrer': '', + 'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url', + 'origin': 'https://example.com/', + 'origin-when-cross-origin': 'https://example.com/', + 'no-referrer-when-downgrade': '', + 'same-origin': '', + 'strict-origin': '', + 'strict-origin-when-cross-origin':'' + }, + 'https-to-https': { + 'no-referrer': '', + 'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url', + 'origin': 'https://example.com/', + 'origin-when-cross-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=origin-when-cross-origin', + 'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade', + 'same-origin': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=same-origin', + 'strict-origin': 'https://example.com/', + 'strict-origin-when-cross-origin':'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=strict-origin-when-cross-origin' + } + } +}; diff --git a/dom/base/test/referrer_change_server.sjs b/dom/base/test/referrer_change_server.sjs new file mode 100644 index 0000000000..527d1c31ab --- /dev/null +++ b/dom/base/test/referrer_change_server.sjs @@ -0,0 +1,139 @@ +var BASE_URL = 'example.com/tests/dom/base/test/referrer_change_server.sjs'; + +function createTestUrl(aPolicy, aAction, aName) { + return 'http://' + BASE_URL + '?' + + 'action=' + aAction + '&' + + 'policy=' + aPolicy + '&' + + 'name=' + aName + '&' + + 'type=link'; +} + +function createTest(aMetaPolicy, aReferrerPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + '<meta name="referrer" content="' + aMetaPolicy + '">' + + '<body>' + + '<a href="' + createTestUrl(aReferrerPolicy, 'test', aName + aReferrerPolicy) + '" id="link">' + aReferrerPolicy + '</a>' + + '<script>' + + + // LOAD EVENT (of the test) + // fires when the page is loaded, then click link + // first change meta referrer, then click link + 'window.addEventListener("load", function() {\n\ + document.getElementsByName("referrer")[0].content = "'+aReferrerPolicy+'";\n\ + document.getElementById("link").click();\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function createTest2(aMetaPolicy, aReferrerPolicy, aName) { + return '<!DOCTYPE HTML>\n\ + <html>'+ + '<meta name="referrer" content="' + aMetaPolicy + '">' + + '<body>' + + '<a href="' + createTestUrl(aReferrerPolicy, 'test', aName + aReferrerPolicy) + '" id="link">' + aReferrerPolicy + '</a>' + + '<script>' + + + // LOAD EVENT (of the test) + // fires when the page is loaded, then click link + // first change meta referrer, then click link + 'window.addEventListener("load", function() {\n\ + document.getElementsByName("referrer")[0].setAttribute("content", "'+aReferrerPolicy+'");\n\ + document.getElementById("link").click();\n\ + }.bind(window), false);' + + + '</script>\n\ + </body>\n\ + </html>'; +} + +function handleRequest(request, response) { + var sharedKey = 'referrer_change_server.sjs'; + var params = request.queryString.split('&'); + var action = params[0].split('=')[1]; + + if (action === 'resetState') { + var state = getSharedState(sharedKey); + state = {}; + setSharedState(sharedKey, JSON.stringify(state)); + response.write(""); + return; + } else if (action === 'test') { + // ?action=test&policy=origin&name=name + var policy = params[1].split('=')[1]; + var name = params[2].split('=')[1]; + var type = params[3].split('=')[1]; + var result = getSharedState(sharedKey); + + if (result === '') { + result = {}; + } else { + result = JSON.parse(result); + } + + if (!result["tests"]) { + result["tests"] = {}; + } + + var referrerLevel = "none"; + var test = {} + if (request.hasHeader('Referer')) { + let referrer = request.getHeader('Referer'); + if (referrer.indexOf("referrer_change_server") > 0) { + referrerLevel = "full"; + } else if (referrer == "http://mochi.test:8888") { + referrerLevel = "origin"; + } + test.referrer = request.getHeader('Referer'); + } else { + test.referrer = ''; + } + test.policy = referrerLevel; + test.expected = policy; + + result["tests"][name] = test; + + setSharedState(sharedKey, JSON.stringify(result)); + + // forward link click to redirect URL to finish test + if (type === 'link') { + var loc = 'https://example.com/tests/dom/base/test/file_change_policy_redirect.html'; + response.setStatusLine('1.1', 302, 'Found'); + response.setHeader('Location', loc, false); + } + + return; + } else if (action === 'get-test-results') { + // ?action=get-result + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/plain', false); + response.write(getSharedState(sharedKey)); + return; + } else if (action === 'generate-policy-test') { + // ?action=generate-policy-test&referrerPolicy=b64-encoded-string&name=name&newPolicy=b64-encoded-string + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/html; charset=utf-8', false); + var referrerPolicy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + var newPolicy = params[3].split('=')[1]; + + response.write(createTest(referrerPolicy, newPolicy, name)); + return; + } else if (action === 'generate-policy-test2') { + // ?action=generate-policy-test2&referrerPolicy=b64-encoded-string&name=name&newPolicy=b64-encoded-string + response.setHeader('Cache-Control', 'no-cache', false); + response.setHeader('Content-Type', 'text/html; charset=utf-8', false); + var referrerPolicy = unescape(params[1].split('=')[1]); + var name = unescape(params[2].split('=')[1]); + var newPolicy = params[3].split('=')[1]; + + response.write(createTest2(referrerPolicy, newPolicy, name)); + return; + } else { + response.write("I don't know action "+action); + return; + } +} diff --git a/dom/base/test/referrer_helper.js b/dom/base/test/referrer_helper.js new file mode 100644 index 0000000000..c46bdea7a4 --- /dev/null +++ b/dom/base/test/referrer_helper.js @@ -0,0 +1,102 @@ +/* + * common functionality for iframe, anchor, and area referrer attribute tests + */ +const GET_RESULT = SJS + 'ACTION=get-test-results'; +const RESET_STATE = SJS + 'ACTION=resetState'; + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * Listen for notifications from the child. + * These are sent in case of error, or when the loads we await have completed. + */ +window.addEventListener("message", function(event) { + if (event.data == "childLoadComplete") { + // all loads happen, continue the test. + advance(); + } +}); + +/** + * helper to perform an XHR + * to do checkIndividualResults and resetState + */ +function doXHR(aUrl, onSuccess, onFail) { + // The server is at http[s]://example.com so we need cross-origin XHR. + var xhr = new XMLHttpRequest({mozSystem: true}); + xhr.responseType = "json"; + xhr.onload = function () { + onSuccess(xhr); + }; + xhr.onerror = function () { + onFail(xhr); + }; + xhr.open('GET', "http" + aUrl, true); + xhr.send(null); +} + +/** + * Grabs the results via XHR and passes to checker. + */ +function checkIndividualResults(aTestname, aExpectedReferrer, aName) { + var onload = xhr => { + var results = xhr.response; + info(JSON.stringify(xhr.response)); + ok(aName in results, aName + " tests have to be performed."); + is(results[aName].policy, aExpectedReferrer, aTestname + ' --- ' + results[aName].policy + ' (' + results[aName].referrer + ')'); + advance(); + }; + var onerror = xhr => { + ok(false, "Can't get results from the counter server."); + SimpleTest.finish(); + }; + doXHR(GET_RESULT, onload, onerror); +} + +function resetState() { + doXHR(RESET_STATE, + advance, + function(xhr) { + ok(false, "error in reset state"); + SimpleTest.finish(); + }); +} + +/** + * testing if anchor and area referrer attributes are honoured (1174913) + */ +var tests = (function() { + + // enable referrer attribute + yield SpecialPowers.pushPrefEnv({"set": [['network.http.enablePerElementReferrer', true]]}, advance); + yield SpecialPowers.pushPrefEnv({"set": [['security.mixed_content.block_active_content', false]]}, advance); + yield SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], advance); + + var iframe = document.getElementById("testframe"); + + for (var j = 0; j < testCases.length; j++) { + var actions = testCases[j].ACTION; + var tests = testCases[j].TESTS; + for (var k = 0; k < actions.length; k++) { + var actionString = actions[k]; + for (var i = 0; i < tests.length; i++) { + yield resetState(); + var searchParams = new URLSearchParams(); + searchParams.append("ACTION", actionString); + searchParams.append("NAME", tests[i].NAME); + for (var l of PARAMS) { + if (tests[i][l]) { + searchParams.append(l, tests[i][l]); + } + } + var schemeFrom = tests[i].SCHEME_FROM || "http"; + yield iframe.src = schemeFrom + SJS + searchParams.toString(); + yield checkIndividualResults(tests[i].DESC, tests[i].RESULT, tests[i].NAME); + }; + }; + }; + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})();
\ No newline at end of file diff --git a/dom/base/test/referrer_testserver.sjs b/dom/base/test/referrer_testserver.sjs new file mode 100644 index 0000000000..484680a157 --- /dev/null +++ b/dom/base/test/referrer_testserver.sjs @@ -0,0 +1,391 @@ +/* +* Test server for iframe, anchor, and area referrer attributes. +* https://bugzilla.mozilla.org/show_bug.cgi?id=1175736 +* Also server for further referrer tests such as redirecting tests +* bug 1174913, bug 1175736, bug 1184781 +*/ + +Components.utils.importGlobalProperties(["URLSearchParams"]); +const SJS = "referrer_testserver.sjs?"; +const BASE_URL = "example.com/tests/dom/base/test/" + SJS; +const SHARED_KEY = SJS; +const SAME_ORIGIN = "mochi.test:8888/tests/dom/base/test/" + SJS; +const CROSS_ORIGIN = "test1.example.com/tests/dom/base/test/" + SJS; + +const IMG_BYTES = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" + + "P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="); + +function createTestUrl(aPolicy, aAction, aName, aType, aSchemeFrom, aSchemeTo) { + var schemeTo = aSchemeTo || "http"; + var schemeFrom = aSchemeFrom || "http"; + return schemeTo + "://" + BASE_URL + + "ACTION=" + aAction + "&" + + "policy=" + aPolicy + "&" + + "NAME=" + aName + "&" + + "type=" + aType + "&" + + "SCHEME_FROM=" + schemeFrom; +} + +// test page using iframe referrer attribute +// if aParams are set this creates a test where the iframe url is a redirect +function createIframeTestPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aParams, + aSchemeFrom, aSchemeTo, aChangingMethod) { + var metaString = ""; + if (aMetaPolicy) { + metaString = `<meta name="referrer" content="${aMetaPolicy}">`; + } + var changeString = ""; + if (aChangingMethod === "setAttribute") { + changeString = `document.getElementById("myframe").setAttribute("referrerpolicy", "${aNewAttributePolicy}")`; + } else if (aChangingMethod === "property") { + changeString = `document.getElementById("myframe").referrerPolicy = "${aNewAttributePolicy}"`; + } + var iFrameString = `<iframe src="" id="myframe" ${aAttributePolicy ? ` referrerpolicy="${aAttributePolicy}"` : ""}>iframe</iframe>`; + var iframeUrl = ""; + if (aParams) { + aParams.delete("ACTION"); + aParams.append("ACTION", "redirectIframe"); + iframeUrl = "http://" + CROSS_ORIGIN + aParams.toString(); + } else { + iframeUrl = createTestUrl(aAttributePolicy, "test", aName, "iframe", aSchemeFrom, aSchemeTo); + } + + return `<!DOCTYPE HTML> + <html> + <head> + ${metaString} + </head> + <body> + ${iFrameString} + <script> + window.addEventListener("load", function() { + ${changeString} + document.getElementById("myframe").onload = function(){ + parent.postMessage("childLoadComplete", "http://mochi.test:8888"); + }; + document.getElementById("myframe").src = "${iframeUrl}"; + }.bind(window), false); + </script> + </body> + </html>`; +} + +function buildAnchorString(aMetaPolicy, aReferrerPolicy, aName, aRelString, aSchemeFrom, aSchemeTo){ + if (aReferrerPolicy) { + return `<a href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link', aSchemeFrom, aSchemeTo)}" referrerpolicy="${aReferrerPolicy}" id="link" ${aRelString}>${aReferrerPolicy}</a>`; + } + return `<a href="${createTestUrl(aMetaPolicy, 'test', aName, 'link', aSchemeFrom, aSchemeTo)}" id="link" ${aRelString}>link</a>`; +} + +function buildAreaString(aMetaPolicy, aReferrerPolicy, aName, aRelString, aSchemeFrom, aSchemeTo){ + var result = `<img src="file_mozfiledataurl_img.jpg" alt="image" usemap="#imageMap">`; + result += `<map name="imageMap">`; + if (aReferrerPolicy) { + result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link', aSchemeFrom, aSchemeTo)}" alt="theArea" referrerpolicy="${aReferrerPolicy}" id="link" ${aRelString}>`; + } else { + result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(aMetaPolicy, 'test', aName, 'link', aSchemeFrom, aSchemeTo)}" alt="theArea" id="link" ${aRelString}>`; + } + result += `</map>`; + + return result; +} + +// test page using anchor or area referrer attribute +function createAETestPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aRel, aStringBuilder, aSchemeFrom, aSchemeTo, aChangingMethod) { + var metaString = ""; + if (aMetaPolicy) { + metaString = `<head><meta name="referrer" content="${aMetaPolicy}"></head>`; + } + var changeString = ""; + if (aChangingMethod === "setAttribute") { + changeString = `document.getElementById("link").setAttribute("referrerpolicy", "${aNewAttributePolicy}")`; + } else if (aChangingMethod === "property") { + changeString = `document.getElementById("link").referrerPolicy = "${aNewAttributePolicy}"`; + } + var relString = ""; + if (aRel) { + relString = `rel="noreferrer"`; + } + var elementString = aStringBuilder(aMetaPolicy, aAttributePolicy, aName, relString, aSchemeFrom, aSchemeTo); + + return `<!DOCTYPE HTML> + <html> + ${metaString} + <body> + ${elementString} + <script> + window.addEventListener("load", function() { + ${changeString} + document.getElementById("link").click(); + }.bind(window), false); + </script> + </body> + </html>`; +} + +// creates test page with img that is a redirect +function createRedirectImgTestCase(aParams, aAttributePolicy) { + var metaString = ""; + if (aParams.has("META_POLICY")) { + metaString = `<meta name="referrer" content="${aParams.get('META_POLICY')}">`; + } + aParams.delete("ACTION"); + aParams.append("ACTION", "redirectImg"); + var imgUrl = "http://" + CROSS_ORIGIN + aParams.toString(); + + return `<!DOCTYPE HTML> + <html> + <head> + <meta charset="utf-8"> + ${metaString} + <title>Test referrer policies on redirect (img)</title> + </head> + <body> + <img id="testImg" src="${imgUrl}" ${aAttributePolicy ? ` referrerpolicy="${aAttributePolicy}"` : ""}> + <script> + window.addEventListener("load", function() { + parent.postMessage("childLoadComplete", "http://mochi.test:8888"); + }.bind(window), false); + </script> + </body> + </html>`; +} + +// test page using link referrer attribute +function createLinkPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aRel, aStringBuilder, aSchemeFrom, aSchemeTo, aTestType) { + var metaString = ""; + if (aMetaPolicy) { + metaString = `<meta name="referrer" content="${aMetaPolicy}">`; + } + var relString = ""; + if (aRel) { + relString = `rel=${aRel}`; + } + + var changeString = ""; + var policy = aAttributePolicy ? aAttributePolicy : aMetaPolicy; + var elementString = aStringBuilder(policy, aName, relString, aSchemeFrom, aSchemeTo, aTestType); + + if (aTestType === "setAttribute") { + changeString = `var link = document.getElementById("test_link"); + link.setAttribute("referrerpolicy", "${aNewAttributePolicy}"); + link.href = "${createTestUrl(policy, "test", aName, "link_element", aSchemeFrom, aSchemeTo)}";`; + } else if (aTestType === "property") { + changeString = `var link = document.getElementById("test_link"); + link.referrerPolicy = "${aNewAttributePolicy}"; + link.href = "${createTestUrl(policy, "test", aName, "link_element", aSchemeFrom, aSchemeTo)}";`; + } + + return `<!DOCTYPE HTML> + <html> + <head> + ${metaString} + ${elementString} + </head> + <body> + <script> + ${changeString} + </script> + </body> + </html>`; +} + +function buildLinkString(aPolicy, aName, aRelString, aSchemeFrom, aSchemeTo, aTestType) { + var result; + var href = ''; + var onChildComplete = `window.parent.postMessage("childLoadComplete", "http://mochi.test:8888");` + if (!aTestType) { + href = `href=${createTestUrl(aPolicy, "test", aName, "link_element", aSchemeFrom, aSchemeTo)}`; + } + if (!aPolicy) { + result = `<link ${aRelString} ${href} id="test_link" onload='${onChildComplete}' onerror='${onChildComplete}'>`; + } else { + result = `<link ${aRelString} ${href} referrerpolicy=${aPolicy} id="test_link" onload='${onChildComplete}' onerror='${onChildComplete}'>`; + } + + return result; +} + +function handleRequest(request, response) { + var params = new URLSearchParams(request.queryString); + var action = params.get("ACTION"); + var schemeFrom = params.get("SCHEME_FROM") || "http"; + var schemeTo = params.get("SCHEME_TO") || "http"; + + if (action === "resetState") { + setSharedState(SHARED_KEY, "{}"); + response.write(""); + return; + } + if (action === "get-test-results") { + // ?action=get-result + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/plain", false); + response.write(getSharedState(SHARED_KEY)); + return; + } + if (action === "redirect") { + response.write('<script>parent.postMessage("childLoadComplete", "http://mochi.test:8888");</script>'); + return; + } + if (action === "redirectImg"){ + params.delete("ACTION"); + params.append("ACTION", "test"); + params.append("type", "img"); + // 302 found, 301 Moved Permanently, 303 See Other, 307 Temporary Redirect + response.setStatusLine("1.1", 302, "found"); + response.setHeader("Location", "http://" + CROSS_ORIGIN + params.toString(), false); + return; + } + if (action === "redirectIframe"){ + params.delete("ACTION"); + params.append("ACTION", "test"); + params.append("type", "iframe"); + // 302 found, 301 Moved Permanently, 303 See Other, 307 Temporary Redirect + response.setStatusLine("1.1", 302, "found"); + response.setHeader("Location", "http://" + CROSS_ORIGIN + params.toString(), false); + return; + } + if (action === "test") { + // ?action=test&policy=origin&name=name + var policy = params.get("policy"); + var name = params.get("NAME"); + var type = params.get("type"); + var result = getSharedState(SHARED_KEY); + + result = result ? JSON.parse(result) : {}; + + var referrerLevel = "none"; + var test = {} + if (request.hasHeader("Referer")) { + var referrer = request.getHeader("Referer"); + if (referrer.indexOf("referrer_testserver") > 0) { + referrerLevel = "full"; + } else if (referrer.indexOf(schemeFrom + "://example.com") == 0) { + referrerLevel = "origin"; + } else { + // this is never supposed to happen + referrerLevel = "other-origin"; + } + test.referrer = referrer; + } else { + test.referrer = ""; + } + test.policy = referrerLevel; + test.expected = policy; + + result[name] = test; + + setSharedState(SHARED_KEY, JSON.stringify(result)); + + if (type === "img") { + // return image + response.setHeader("Content-Type", "image/png"); + response.write(IMG_BYTES); + return; + } + if (type === "iframe") { + // return iframe page + response.write("<html><body>I am the iframe</body></html>"); + return; + } + if (type === "link") { + // forward link click to redirect URL to finish test + var loc = "http://" + BASE_URL + "ACTION=redirect"; + response.setStatusLine("1.1", 302, "Found"); + response.setHeader("Location", loc, false); + } + return; + } + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html; charset=utf-8", false); + + // parse test arguments and start test + var attributePolicy = params.get("ATTRIBUTE_POLICY") || ""; + var newAttributePolicy = params.get("NEW_ATTRIBUTE_POLICY") || ""; + var metaPolicy = params.get("META_POLICY") || ""; + var rel = params.get("REL") || ""; + var name = params.get("NAME"); + + // anchor & area + var _getPage = createAETestPageUsingRefferer.bind(null, metaPolicy, attributePolicy, newAttributePolicy, name, rel); + var _getAnchorPage = _getPage.bind(null, buildAnchorString, schemeFrom, schemeTo); + var _getAreaPage = _getPage.bind(null, buildAreaString, schemeFrom, schemeTo); + + // aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aChangingMethod, aStringBuilder + if (action === "generate-anchor-policy-test") { + response.write(_getAnchorPage()); + return; + } + if (action === "generate-anchor-changing-policy-test-set-attribute") { + response.write(_getAnchorPage("setAttribute")); + return; + } + if (action === "generate-anchor-changing-policy-test-property") { + response.write(_getAnchorPage("property")); + return; + } + if (action === "generate-area-policy-test") { + response.write(_getAreaPage()); + return; + } + if (action === "generate-area-changing-policy-test-set-attribute") { + response.write(_getAreaPage("setAttribute")); + return; + } + if (action === "generate-area-changing-policy-test-property") { + response.write(_getAreaPage("property")); + return; + } + + // iframe + _getPage = createIframeTestPageUsingRefferer.bind(null, metaPolicy, attributePolicy, newAttributePolicy, name, "", + schemeFrom, schemeTo); + + // aMetaPolicy, aAttributePolicy, aNewAttributePolicy, aName, aChangingMethod + if (action === "generate-iframe-policy-test") { + response.write(_getPage()); + return; + } + if (action === "generate-iframe-changing-policy-test-set-attribute") { + response.write(_getPage("setAttribute")); + return; + } + if (action === "generate-iframe-changing-policy-test-property") { + response.write(_getPage("property")); + return; + } + + // redirect tests with img and iframe + if (action === "generate-img-redirect-policy-test") { + response.write(createRedirectImgTestCase(params, attributePolicy)); + return; + } + if (action === "generate-iframe-redirect-policy-test") { + response.write(createIframeTestPageUsingRefferer(metaPolicy, attributePolicy, newAttributePolicy, name, params, + schemeFrom, schemeTo)); + return; + } + + var _getPage = createLinkPageUsingRefferer.bind(null, metaPolicy, attributePolicy, newAttributePolicy, name, rel); + var _getLinkPage = _getPage.bind(null, buildLinkString, schemeFrom, schemeTo); + + // link + if (action === "generate-link-policy-test") { + response.write(_getLinkPage()); + return; + } + if (action === "generate-link-policy-test-set-attribute") { + response.write(_getLinkPage("setAttribute")); + return; + } + if (action === "generate-link-policy-test-property") { + response.write(_getLinkPage("property")); + return; + } + + response.write("I don't know action " + action); + return; +} diff --git a/dom/base/test/reftest/mixed-bmp-png.ico b/dom/base/test/reftest/mixed-bmp-png.ico Binary files differnew file mode 100644 index 0000000000..32e2c4995c --- /dev/null +++ b/dom/base/test/reftest/mixed-bmp-png.ico diff --git a/dom/base/test/reftest/reftest-stylo.list b/dom/base/test/reftest/reftest-stylo.list new file mode 100644 index 0000000000..8fd85a02f9 --- /dev/null +++ b/dom/base/test/reftest/reftest-stylo.list @@ -0,0 +1,2 @@ +# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing +== test_bug920877.html test_bug920877.html diff --git a/dom/base/test/reftest/reftest.list b/dom/base/test/reftest/reftest.list new file mode 100644 index 0000000000..f8a7a81d5f --- /dev/null +++ b/dom/base/test/reftest/reftest.list @@ -0,0 +1 @@ +== test_bug920877.html test_bug920877-ref.html diff --git a/dom/base/test/reftest/test_bug920877-ref.html b/dom/base/test/reftest/test_bug920877-ref.html new file mode 100644 index 0000000000..1a593e5849 --- /dev/null +++ b/dom/base/test/reftest/test_bug920877-ref.html @@ -0,0 +1,20 @@ +<html> +<body> +<script> +var img = document.createElement("img"); +img.id = "img-ori"; +img.src = "mixed-bmp-png.ico"; +document.body.appendChild(img); + +img = document.createElement("img"); +img.id = "img-res32"; +img.src = "mixed-bmp-png.ico#-moz-resolution=32,32"; +document.body.appendChild(img); + +img = document.createElement("img"); +img.id = "img-res48"; +img.src = "mixed-bmp-png.ico#-moz-resolution=48,48"; +document.body.appendChild(img); +</script> +</body> +</html> diff --git a/dom/base/test/reftest/test_bug920877.html b/dom/base/test/reftest/test_bug920877.html new file mode 100644 index 0000000000..18bae4009e --- /dev/null +++ b/dom/base/test/reftest/test_bug920877.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +</head> +<body> +<script> +var dataURL = "data:image/vnd.microsoft.icon;base64,AAABAAQAMDAAAAEAIACoJQAARgAAACAgAAABACAAqBAAAO4lAAAYGAAAAQAgAIgJAACWNgAAEBAAAAEAIABoBAAAHkAAACgAAAAwAAAAYAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmAEDQZgCA0GYAv9BmAN/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgDf0GYAv9BmAIDQZgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmAEDQZgCf0GYA79BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA79BmAJ/QZgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQZgBA0GYAv9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYAv9BmAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAINBmAK/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgCv0GYAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQZgBQ0GYA79BmAP/QZgD/0GYA/9BmAL/QZgC/0GYAv9BmAL/QZgC/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA79BmAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmAI/QZgDv0GYAn9BmAFDQZgAQAAAAAAAAAAAAAAAAIB8jECAfI0AgHyNAIB8jINBmABDQZgBA0GYAgNBmAK/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgCPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAgNBmAGAAAAAAAAAAAAAAAAAAAAAAIB8jQCAfI58gHyPvIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyPPIB8jjyAfIzAAAAAA0GYAUNBmAJ/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYAnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfIxAgHyO/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyPPIB8jYAAAAADQZgAQ0GYAcNBmAN/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAJ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jMCAfI+8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI78gHyNAAAAAAAAAAADQZgBg0GYA39BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgCPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMQIB8j7yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jjwAAAAAAAAAAAAAAANBmAIDQZgDv0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOfIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyOAIB8jgCAfI4AgHyOAIB8jgCAfI4AgHyOAIB8jgCAfI4AgHyOAIB8jgCAfI4AgHyOAIB8jgCAfI0AAAAAAAAAAAAAAAADQZgAg0GYAv9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA79BmACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfIyAgHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyNgIB8jEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmAHDQZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAK8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI48gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI68gHyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyNgIB8jzyAfIzAAAAAAAAAAAAAAAADQZgAw0GYA39BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI78gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jvyAfIyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jICAfI78gHyP/IB8j/yAfI+8gHyMwAAAAAAAAAAAAAAAA0GYAENBmAM/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI+8gHyMwAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyNQIB8j7yAfI/8gHyP/IB8j/yAfI/8gHyPvIB8jIAAAAAAAAAAAAAAAANBmABDQZgDP0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyPfIB8jEAAAAAAAAAAAAAAAACAfI2AgHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jzyAfIxAAAAAAAAAAAAAAAADQZgAQ0GYAz9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYAnwAAAAAAAAAAIhvgEAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jQCAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jzyAfI4AgHyNAIB8jgCAfI78gHyP/IB8jcAAAAAAAAAAAIB8jICAfI/8gHyPfIB8jcCAfI0AgHyNQIB8jjyAfI+8gHyP/IB8j/yAfI58AAAAAAAAAAAAAAAAAAAAA0GYAENBmAM/QZgD/0GYA/9BmAP/QZgD/0GYA7wAAAAAiG+BAIhvgQAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jMCAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI+8gHyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOfIB8jvwAAAAAAAAAAIB8jcCAfI88gHyMQAAAAAAAAAAAAAAAAAAAAACAfIxAgHyOfIB8j/yAfI/8gHyNQAAAAAAAAAAAAAAAAAAAAANBmACDQZgDv0GYA/9BmAP/QZgD/0GYA/9BmAEAiG+CAIhvgQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j7yAfIzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMQIB8j3wAAAAAAAAAAIB8jgCAfI0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jnyAfI/8gHyPvIB8jEAAAAAAAAAAAAAAAAAAAAADQZgBA0GYA/9BmAP/QZgD/0GYA/9BmAIAiG+C/IhvgcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jjwAAAAAAAAAAIB8jYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI98gHyP/IB8jgAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAj9BmAP/QZgD/0GYA/9BmAL8iG+DfIhvgjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI78gHyP/IB8j/yAfI/8gHyPPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jEAAAAAAAAAAAIB8jEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI2AgHyP/IB8j7yAfIyAAAAAAAAAAAAAAAAAAAAAA0GYAENBmAN/QZgD/0GYA/9BmAN8iG+D/Ihvg3wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI58gHyP/IB8j/yAfI/8gHyOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfIxAgHyP/IB8j/yAfI4AAAAAAAAAAAAAAAAAAAAAAAAAAANBmAGDQZgD/0GYA/9BmAP8iG+D/Ihvg/yIb4CAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI2AgHyP/IB8j/yAfI/8gHyNQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyP/IB8j/yAfI+8gHyMQAAAAAAAAAAAAAAAAAAAAAAAAAADQZgDf0GYA/9BmAP8iG+D/Ihvg/yIb4I8AAAAAAAAAAAAAAAAAAAAAAAAAACAfIxAgHyP/IB8j/yAfI/8gHyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyP/IB8j/yAfI/8gHyNgAAAAAAAAAAAAAAAAAAAAAAAAAADQZgBg0GYA/9BmAP8iG+D/Ihvg/yIb4O8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOvIB8j/yAfI/8gHyNwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyP/IB8j/yAfI/8gHyOvAAAAAAAAAAAAAAAAAAAAAAAAAADQZgAQ0GYA79BmAP8iG+D/Ihvg/yIb4P8iG+BwAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyNQIB8j/yAfI/8gHyOfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI0AgHyP/IB8j/yAfI/8gHyPvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAn9BmAP8iG+D/Ihvg/yIb4P8iG+DvIhvgEAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8j3yAfI/8gHyPvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI48gHyP/IB8j/yAfI/8gHyP/IB8jQAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAYNBmAP8iG+DfIhvg/yIb4P8iG+D/IhvgjwAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jYCAfI/8gHyP/IB8jYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI+8gHyP/IB8j/yAfI/8gHyP/IB8jcAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAINBmAN8iG+C/Ihvg/yIb4P8iG+D/Ihvg/yIb4EAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI98gHyP/IB8jvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jYCAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmAK8iG+CAIhvg/yIb4P8iG+D/Ihvg/yIb4N8iG+AQAAAAAAAAAAAAAAAAAAAAACAfI0AgHyP/IB8j/yAfI1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMQIB8j3yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmADAiG+BAIhvg/yIb4P8iG+D/Ihvg/yIb4P8iG+C/AAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOPIB8j/yAfI98gHyMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOAIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvg7yIb4P8iG+D/Ihvg/yIb4P8iG+D/IhvgnwAAAAAAAAAAAAAAAAAAAAAgHyMQIB8jzyAfI/8gHyOfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfIzAgHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgnyIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4J8AAAAAAAAAAAAAAAAAAAAAIB8jMCAfI+8gHyP/IB8jYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jECAfI98gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgQCIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+CfAAAAAAAAAAAAAAAAAAAAACAfI1AgHyP/IB8j/yAfIzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jvyAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4L8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/IhvgnwAAAAAAAAAAAAAAAAAAAAAgHyNgIB8j/yAfI+8gHyMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOfIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4EAiG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4M8iG+AgAAAAAAAAAAAAAAAAIB8jYCAfI/8gHyPvIB8jMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI58gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+CvIhvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+DvIhvgUAAAAAAAAAAAAAAAACAfI1AgHyPvIB8j7yAfI1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMQIB8jnyAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyOfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+AgIhvg7yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4K8iG+AQAAAAAAAAAAAgHyMwIB8jzyAfI/8gHyNwAAAAAAAAAAAAAAAAAAAAACAfIxAgHyPPIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgUCIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+DvIhvgcAAAAAAAAAAAIB8jECAfI48gHyP/IB8jnyAfIxAAAAAAIB8jMCAfI98gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4I8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4N8iG+BgAAAAAAAAAAAgHyNAIB8jvyAfI88gHyOAIB8j7yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+CfIhvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg7yIb4IAiG+AgAAAAACAfI2AgHyO/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgnyIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/IhvgzyIb4HAiG+AgIB8jICAfI4AgHyO/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyPPIB8jjyAfIyAAAAAAAAAAAAAAAAAiG+AwIhvgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4I8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg3yIb4K8iG+CAIhvgQCIb4DAgHyNAIB8jIAAAAAAAAAAAAAAAACIb4DAiG+BQIhvgjyIb4M8iG+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+BQIhvg7yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg7yIb4FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgICIb4K8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+CvIhvgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+BAIhvgvyIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/IhvgvyIb4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4EAiG+CfIhvg7yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg7yIb4J8iG+AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4EAiG+CAIhvgvyIb4N8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+DfIhvgvyIb4IAiG+BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AB//+nbP/8AAA//6ds//AAAA//p2z/wAAAA/+nbP+AAAAB/6ds/wcAAAD/p2z+eACAAH+nbP/gACAAP6ds/8AADAAfp2z/gAAHAA+nbP+AAAOAB6ds/wB//+AHp2z/AB/8cAOnbP8AB/A4A6ds/wAD4BwBp2z/AAHADgGnbL4AAYAPAadsPgD5jweAp2w/Afmfw8CnbD8D/b/j4KdsPwf9v+Hgp2w/B///4fCnbB8H///w+KdsHwf///D4p2wfh///8PinbA+H///g/KdsB8f//+B8p2wHw///4HynbAPj///AfqdsAeH//4B+p2wB8P//gH+nbIDw//8Af6dsgHh//gB/p2yAPD/+AH+nbMAeH/wAf6dswAcP+AB/p2zgA4fgAP+nbOAAw8AA/6ds8ABggAH/p2z4ABgAA/+nbPwAAgAH/6ds/gAAAA5/p2z/AAAA4P+nbP+AAAAB/6ds/8AAAAP/p2z/8AAAD/+nbP/8AAA//6ds//+AAf//p2woAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmADDQZgCA0GYAv9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAL/QZgCA0GYAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmAFDQZgDP0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYAz9BmAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmACDQZgC/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAL/QZgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQZgBQ0GYA39BmAJ/QZgBw0GYAQNBmAECFSA9weEMSgNBmAHDQZgCP0GYAz9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAO/QZgBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAINBmAGAAAAAAAAAAACAfI1AgHyO/IB8j/yAfI/8gHyP/IB8j/yAfI98gHyOPZjsVUNBmAHDQZgDP0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOfIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jryAfIyDQZgBA0GYAv9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jgCAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j7yAfI2AAAAAA0GYAQNBmAN/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAO/QZgAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfIyAgHyP/IB8j/yAfI/8gHyP/IB8jUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAENBmAI/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAL8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jcCAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j3yAfI4AgHyMQAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMgIB8jvyAfI58AAAAAAAAAANBmAFDQZgDv0GYA/9BmAP/QZgD/0GYA/9BmAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOvIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI88gHyMQAAAAAAAAAAAAAAAAIB8jYCAfI+8gHyP/IB8j/yAfI58AAAAAAAAAANBmADDQZgDv0GYA/9BmAP/QZgD/0GYAzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI78gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI78AAAAAAAAAACAfI4AgHyP/IB8j/yAfI/8gHyP/IB8j/yAfI3AAAAAAAAAAANBmADDQZgDv0GYA/9BmAP/QZgD/0GYAMCIb4EAAAAAAAAAAAAAAAAAAAAAAIB8jvyAfI/8gHyP/IB8j/yAfI/8gHyOAIB8jEAAAAAAgHyMwIB8j3yAfIzAAAAAAIB8j3yAfI0AAAAAAAAAAACAfI1AgHyPfIB8j/yAfIzAAAAAAAAAAANBmAEDQZgD/0GYA/9BmAP/QZgCAIhvgvwAAAAAAAAAAAAAAAAAAAAAgHyO/IB8j/yAfI/8gHyP/IB8jYAAAAAAAAAAAAAAAAAAAAAAgHyNAIB8jQAAAAAAgHyOAAAAAAAAAAAAAAAAAAAAAACAfIxAgHyPvIB8jzwAAAAAAAAAAAAAAANBmAIDQZgD/0GYA/9BmAL8iG+D/IhvgEAAAAAAAAAAAAAAAACAfI58gHyP/IB8j/yAfI58AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMgAAAAACAfIyAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI2AgHyP/IB8jYAAAAAAAAAAAAAAAANBmAM/QZgD/0GYA/yIb4P8iG+BQAAAAAAAAAAAAAAAAIB8jcCAfI/8gHyP/IB8jUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jECAfI/8gHyPfAAAAAAAAAAAAAAAA0GYAQNBmAP/QZgD/Ihvg/yIb4K8AAAAAAAAAAAAAAAAgHyMgIB8j/yAfI/8gHyNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8j/yAfI/8gHyMwAAAAAAAAAAAAAAAA0GYAv9BmAP8iG+D/Ihvg/yIb4CAAAAAAAAAAAAAAAAAgHyPPIB8j/yAfI2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfIxAgHyP/IB8j/yAfI48AAAAAAAAAAAAAAADQZgBQ0GYA/yIb4P8iG+D/IhvgnwAAAAAAAAAAAAAAACAfI2AgHyP/IB8jnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jYCAfI/8gHyP/IB8jzwAAAAAAAAAAAAAAAAAAAADQZgD/Ihvg/yIb4P8iG+D/IhvgQAAAAAAAAAAAAAAAACAfI98gHyPvIB8jEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyO/IB8j/yAfI/8gHyP/AAAAAAAAAAAAAAAAAAAAANBmAL8iG+C/Ihvg/yIb4P8iG+DfIhvgEAAAAAAAAAAAIB8jUCAfI/8gHyOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jQCAfI/8gHyP/IB8j/yAfI/8gHyMQAAAAAAAAAAAAAAAA0GYAQCIb4IAiG+D/Ihvg/yIb4P8iG+CvAAAAAAAAAAAAAAAAIB8jryAfI/8gHyMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyPPIB8j/yAfI/8gHyP/IB8j/yAfI0AAAAAAAAAAAAAAAAAAAAAAIhvgMCIb4P8iG+D/Ihvg/yIb4P8iG+CfAAAAAAAAAAAgHyMQIB8j3yAfI88gHyMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jjyAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jIAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgzyIb4P8iG+D/Ihvg/yIb4P8iG+CfAAAAAAAAAAAgHyMwIB8j7yAfI68AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI2AgHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+BgIhvg/yIb4P8iG+D/Ihvg/yIb4P8iG+C/IhvgEAAAAAAgHyMwIB8j7yAfI58AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyNgIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+C/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+DvIhvgQAAAAAAgHyMwIB8j3yAfI78gHyMQAAAAAAAAAAAAAAAAIB8jYCAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4CAiG+DvIhvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/IhvgryIb4CAgHyMQIB8jryAfI88gHyMwAAAAACAfI58gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8jzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4FAiG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4J8iG+AgIB8jUCAfI88gHyPPIB8j/yAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI98gHyMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4GAiG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+C/IhvgYCEeWXAgHyOvIB8j7yAfI/8gHyP/IB8j/yAfI98gHyOAIB8jEAAAAAAiG+AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4FAiG+DvIhvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4N8iG+CvIhvggCEcm68iG+BAIhvgYCIb4IAiG+CfIhvgzyIb4FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4CAiG+C/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4L8iG+AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+BgIhvgzyIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4M8iG+BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgMCIb4IAiG+C/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/IhvgvyIb4IAiG+AwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AA///AAD//AAAP/gAAB/zAAAP/gAAB/wACAP4H/wD+APjAfgBwYH4AYDAeAiYYHg8vHA4fr44OH/+ODh//xwcf/4cHH/+Hg4//h4GP/wOBx/8DwMP+A+Bj/AfgEfgH8AhwB/AAIA/4AAAP/AAAF/4AAAf/AAAP/8AAP//wAP/KAAAABgAAAAwAAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQZgBQ0GYAn9BmAN/QZgD/0GYA/9BmAP/QZgD/0GYA39BmAJ/QZgBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAQNBmAN/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA39BmAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQZgCP0GYAz9BmAI/QZgCAoFMKr6BTCq/QZgCv0GYA39BmAP/QZgD/0GYA/9BmAP/QZgD/0GYA/9BmAP/QZgCPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANBmADDQZgAgIB8jECAfI58gHyPvIB8j/yAfI/8gHyP/IB8jz0wxGoDQZgCA0GYA39BmAP/QZgD/0GYA/9BmAP/QZgD/0GYAnwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMQIB8jzyAfI/8gHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyPPIB8jMNBmAGDQZgDv0GYA/9BmAP/QZgD/0GYA/9BmAI8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOAIB8j/yAfI/8gHyO/IB8jUCAfI0AgHyNAIB8jQCAfI0AgHyNAIB8jMAAAAADQZgAQ0GYAr9BmAP/QZgD/0GYA/9BmAP/QZgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyPvIB8j/yAfI/8gHyP/IB8j/yAfI58gHyMQAAAAAAAAAAAAAAAAIB8jUCAfI98gHyNgAAAAANBmAGDQZgD/0GYA/9BmAP/QZgDfAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyP/IB8j/yAfI/8gHyP/IB8j/yAfI/8gHyPPIB8jEAAAAAAgHyOPIB8j/yAfI/8gHyP/IB8jYAAAAADQZgBg0GYA/9BmAP/QZgD/0GYAUCIb4FAAAAAAAAAAACAfI0AgHyP/IB8j/yAfI/8gHyPfIB8jYCAfI0AgHyOvIB8jYCAfIzAgHyPPIB8jQCAfI1AgHyO/IB8j7yAfIyAAAAAA0GYAYNBmAP/QZgD/0GYAnyIb4J8AAAAAAAAAAAAAAAAgHyP/IB8j/yAfI98gHyMQAAAAAAAAAAAgHyMQIB8jcCAfI0AgHyMgAAAAAAAAAAAAAAAAIB8jryAfI78AAAAAAAAAANBmAI/QZgD/0GYA3yIb4O8AAAAAAAAAAAAAAAAgHyPvIB8j/yAfI2AAAAAAAAAAAAAAAAAAAAAAIB8jECAfIxAAAAAAAAAAAAAAAAAAAAAAIB8jMCAfI/8gHyNAAAAAANBmABDQZgDf0GYA/yIb4P8iG+BAAAAAAAAAAAAgHyOvIB8j/yAfI0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI/8gHyOfAAAAAAAAAADQZgBg0GYA/yIb4P8iG+CvAAAAAAAAAAAgHyNgIB8j/yAfI1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jICAfI/8gHyP/AAAAAAAAAADQZgAQ0GYA7yIb4P8iG+D/IhvgQAAAAAAAAAAAIB8j3yAfI58AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jcCAfI/8gHyP/IB8jQAAAAAAAAAAA0GYAryIb4N8iG+D/Ihvg3yIb4BAAAAAAIB8jYCAfI/8gHyMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMQIB8j3yAfI/8gHyP/IB8jUAAAAAAAAAAA0GYAYCIb4J8iG+D/Ihvg/yIb4K8AAAAAAAAAACAfI78gHyO/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyOAIB8j/yAfI/8gHyP/IB8jgAAAAAAAAAAAAAAAACIb4FAiG+D/Ihvg/yIb4P8iG+CfAAAAACAfIxAgHyPfIB8jgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI1AgHyP/IB8j/yAfI/8gHyP/IB8jQAAAAAAAAAAAAAAAAAAAAAAiG+DfIhvg/yIb4P8iG+D/IhvgryIb4BAgHyMwIB8j7yAfI2AAAAAAAAAAAAAAAAAAAAAAIB8jMCAfI+8gHyP/IB8j/yAfI/8gHyP/IB8jMAAAAAAAAAAAAAAAAAAAAAAiG+BAIhvg/yIb4P8iG+D/Ihvg/yIb4N8iG+BAIB8jICAfI88gHyOPAAAAAAAAAAAgHyNgIB8j7yAfI/8gHyP/IB8j/yAfI/8gHyO/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgjyIb4P8iG+D/Ihvg/yIb4P8iG+D/IhvgryEcoTAgHyOPIB8jvyAfI4AgHyP/IB8j/yAfI/8gHyP/IB8j/yAfI+8gHyMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIb4J8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+C/IhyxgCAfNp8gHyPfIB8j/yAfI/8gHyP/IB8jvyAfIzAiG+AgIhvgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+CPIhvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+DfIhvgvyEcrK8iG+CAIhvgnyIb4M8iG+CPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvgQCIb4N8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg/yIb4P8iG+D/Ihvg3yIb4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiG+BQIhvgnyIb4N8iG+D/Ihvg/yIb4P8iG+D/Ihvg3yIb4J8iG+BQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP4Af0H4AB9B8AAPQeAAB0HwAANB8AEBQfAcQUHwCCBBYAAQQXDDmEFx54hBMf/MQTH/jEEZ/4ZBCP8GQQz/B0EEfgdBgDwHQYAYD0HAAA9B4AAHQfAAD0H4AB9B/gB/QSgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0GYAQNBmAKXQZgDm0GYA/9BmAP/QZgDm0GYApdBmAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQZgAQ0GYAjNBmAKWkVAieqFYHr9BmANPQZgD/0GYA/9BmAP/QZgD/0GYArNBmABAAAAAAAAAAAAAAAAAAAAAA0GYAGSAfIyIgHyO8IB8j/SAfI/8gHyPWUjMZirZbBIPQZgDq0GYA/9BmAP/QZgDN0GYAEAAAAAAAAAAAAAAAACAfIwQgHyPYIB8j/yAfI4wgHyOAIB8jgCAfI4AgHyNQ0GYADtBmAJXQZgD/0GYA/9BmAKwAAAAAAAAAAAAAAAAgHyNBIB8j/yAfI/8gHyP2IB8jjyAfIwUAAAAAIB8jWSAfI88gHyMj0GYAVdBmAPrQZgD/0GYAQCIb3xAAAAAAIB8jYSAfI/8gHyP9IB8jniAfI4AgHyNqIB8jTiAfI4MgHyOKIB8jyiAfIwnQZgBR0GYA/dBmAKUiG99gAAAAACAfI04gHyP/IB8jeAAAAAAAAAAAIB8jLCAfIyIAAAAAAAAAACAfI1EgHyOBAAAAANBmAIfQZgDmIhvfugAAAAAgHyMeIB8j/yAfIx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgHyMCIB8j7yAfIwzQZgAL0GYA6iIb3/0iG98pAAAAACAfI8MgHyM5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIB8jFyAfI/8gHyNRAAAAANBmAI4iG9/mIhvfvSIb3wIgHyNHIB8jmgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfI3ggHyP/IB8jgQAAAADQZgA1IhvfpSIb3/8iG9+OAAAAACAfI5ogHyM6AAAAAAAAAAAAAAAAAAAAACAfIyAgHyPxIB8j/yAfI44AAAAAAAAAACIb30AiG9//Ihvf/yIb348hHIEMIB8jpyAfIyUAAAAAAAAAACAfIxIgHyPRIB8j/yAfI/8gHyNsAAAAAAAAAAAAAAAAIhvfrCIb3/8iG9//IhvfxSEbsDIgHyOIIB8jPCAfIyAgHyPUIB8j/yAfI/8gHyPxIB8jFQAAAAAAAAAAAAAAACIb3xAiG9/NIhvf/yIb3/8iG9/7IhvfpSEdgYEgHjioIB8j+CAfI/8gHyPUIB8jPCIb3wkAAAAAAAAAAAAAAAAAAAAAIhvfECIb36wiG9//Ihvf/yIb3/8iG9//Ihvf8yIb38UhHLC1IhvfryIb34UiG98OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIhvfQCIb36UiG9/mIhvf/yIb3/8iG9/mIhvfpSIb3z4AAAAAAAAAAAAAAAAAAAAA8A+sQcADrEHAAaxBwAGsQcCArEFAAKxBRmSsQUfgrEEn4qxBB+KsQRPDrEEBg6xBgAOsQYADrEHAA6xB8A+sQQ=="; + +var data = atob(dataURL.substring( "data:image/vnd.microsoft.icon;base64,".length ) ); +var asArray = new Uint8Array(data.length); +for( var i = 0, len = data.length; i < len; ++i ) { + asArray[i] = data.charCodeAt(i); +} +var blob = new Blob( [ asArray.buffer ], {type: 'image/vnd.microsoft.icon'}); +var url = URL.createObjectURL(blob); + +//create img +var img = document.createElement("img"); +img.id = "img-ori"; +img.src = url; +document.body.appendChild(img); + +img = document.createElement("img"); +img.id = "img-res32"; +img.src = url + '#-moz-resolution=32,32'; +document.body.appendChild(img); + +img = document.createElement("img"); +img.id = "img-res48"; +img.src = url + '#-moz-resolution=48,48'; +document.body.appendChild(img); + +window.URL.revokeObjectURL(url); + +</script> +</body> +</html> diff --git a/dom/base/test/script-1_bug597345.sjs b/dom/base/test/script-1_bug597345.sjs new file mode 100644 index 0000000000..50d23b7127 --- /dev/null +++ b/dom/base/test/script-1_bug597345.sjs @@ -0,0 +1,16 @@ +// timer has to be alive so it can't be eaten by the GC. +var timer; + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/javascript", false); + // The "stray" open comment at the end of the write is important! + response.write("document.write(\"<script charset='utf-8' src='script-2_bug597345.js'></script><!--\")"); + response.processAsync(); + timer = Components.classes["@mozilla.org/timer;1"] + .createInstance(Components.interfaces.nsITimer); + timer.initWithCallback(function() { + response.finish(); + }, 200, Components.interfaces.nsITimer.TYPE_ONE_SHOT); +} diff --git a/dom/base/test/script-2_bug597345.js b/dom/base/test/script-2_bug597345.js new file mode 100644 index 0000000000..54d33e6544 --- /dev/null +++ b/dom/base/test/script-2_bug597345.js @@ -0,0 +1 @@ +document.write("Räksmörgås");
\ No newline at end of file diff --git a/dom/base/test/script_bug1238440.js b/dom/base/test/script_bug1238440.js new file mode 100644 index 0000000000..3499cd2ced --- /dev/null +++ b/dom/base/test/script_bug1238440.js @@ -0,0 +1,31 @@ +var { classes: Cc, interfaces: Ci, utils: Cu } = Components; +Cu.importGlobalProperties(["File"]); + +var tmpFile; + +function writeFile(text, answer) { + var stream = Cc["@mozilla.org/network/file-output-stream;1"] + .createInstance(Ci.nsIFileOutputStream); + stream.init(tmpFile, 0x02 | 0x08 | 0x10, 0o600, 0); + stream.write(text, text.length); + stream.close(); + + sendAsyncMessage(answer, { + file: File.createFromNsIFile(tmpFile) + }); +} + +addMessageListener("file.open", function (e) { + tmpFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIDirectoryService) + .QueryInterface(Ci.nsIProperties) + .get('TmpD', Ci.nsIFile) + tmpFile.append('foo.txt'); + tmpFile.createUnique(Ci.nsIFile.FILE_TYPE, 0o600); + + writeFile("hello world", "file.opened"); +}); + +addMessageListener("file.change", function (e) { + writeFile("hello world---------------", "file.changed"); +}); diff --git a/dom/base/test/script_bug602838.sjs b/dom/base/test/script_bug602838.sjs new file mode 100644 index 0000000000..c60c3ebab7 --- /dev/null +++ b/dom/base/test/script_bug602838.sjs @@ -0,0 +1,37 @@ +function setOurState(data) { + x = { data: data, QueryInterface: function(iid) { return this } }; + x.wrappedJSObject = x; + setObjectState("bug602838", x); +} + +function getOurState() { + var data; + getObjectState("bug602838", function(x) { + // x can be null if no one has set any state yet + if (x) { + data = x.wrappedJSObject.data; + } + }); + return data; +} + +function handleRequest(request, response) +{ + if (request.queryString) { + let blockedResponse = getOurState(); + if (typeof(blockedResponse) == "object") { + blockedResponse.finish(); + setOurState(null); + } else { + setOurState("unblocked"); + } + return; + } + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/javascript", false); + response.write("ok(asyncRan, 'Async script should have run first.'); firstRan = true;"); + if (getOurState() != "unblocked") { + response.processAsync(); + setOurState(response); + } +} diff --git a/dom/base/test/script_postmessages_fileList.js b/dom/base/test/script_postmessages_fileList.js new file mode 100644 index 0000000000..05b4d9d1ba --- /dev/null +++ b/dom/base/test/script_postmessages_fileList.js @@ -0,0 +1,25 @@ +var { classes: Cc, interfaces: Ci, utils: Cu } = Components; +Cu.importGlobalProperties(["File"]); + +addMessageListener("file.open", function () { + var testFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIDirectoryService) + .QueryInterface(Ci.nsIProperties) + .get("ProfD", Ci.nsIFile); + testFile.append("prefs.js"); + + sendAsyncMessage("file.opened", { + file: File.createFromNsIFile(testFile) + }); +}); + +addMessageListener("dir.open", function () { + var testFile = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIDirectoryService) + .QueryInterface(Ci.nsIProperties) + .get("ProfD", Ci.nsIFile); + + sendAsyncMessage("dir.opened", { + dir: testFile.path + }); +}); diff --git a/dom/base/test/send_gzip_content.sjs b/dom/base/test/send_gzip_content.sjs new file mode 100644 index 0000000000..6a13440e67 --- /dev/null +++ b/dom/base/test/send_gzip_content.sjs @@ -0,0 +1,48 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; + +function gzipCompressString(string, obs) { + + let scs = Cc["@mozilla.org/streamConverters;1"] + .getService(Ci.nsIStreamConverterService); + let listener = Cc["@mozilla.org/network/stream-loader;1"] + .createInstance(Ci.nsIStreamLoader); + listener.init(obs); + let converter = scs.asyncConvertData("uncompressed", "gzip", + listener, null); + let stringStream = Cc["@mozilla.org/io/string-input-stream;1"] + .createInstance(Ci.nsIStringInputStream); + stringStream.data = string; + converter.onStartRequest(null, null); + converter.onDataAvailable(null, null, stringStream, 0, string.length); + converter.onStopRequest(null, null, null); +} + +function produceData() { + var chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+"; + var result = ''; + for (var i = 0; i < 100000; ++i) { + result += chars; + } + return result; +} + +function handleRequest(request, response) +{ + response.processAsync(); + + // Generate data + var strings_to_send = produceData(); + response.setHeader("Content-Type", "text/plain", false); + response.setHeader("Content-Encoding", "gzip", false); + + let observer = { + onStreamComplete: function(loader, context, status, length, result) { + buffer = String.fromCharCode.apply(this, result); + response.setHeader("Content-Length", ""+buffer.length, false); + response.write(buffer); + response.finish(); + } + }; + gzipCompressString(strings_to_send, observer); +} diff --git a/dom/base/test/somedatas.resource b/dom/base/test/somedatas.resource new file mode 100644 index 0000000000..bc277681d2 --- /dev/null +++ b/dom/base/test/somedatas.resource @@ -0,0 +1,16 @@ + + +retry: 500 + +data:123456789 +data: 123456789123456789 +data:123456789123456789123456789123456789 +data: 123456789123456789123456789123456789123456789123456789123456789123456789 +:some utf-8 characteres +data:çãá"'@`~Ý Ḿyyyy + +:test if the character ":"(which is used for comments) isn't misunderstood +data: :xxabcdefghij +data:çãá"'@`~Ý Ḿyyyy : zz + + diff --git a/dom/base/test/somedatas.resource^headers^ b/dom/base/test/somedatas.resource^headers^ new file mode 100644 index 0000000000..6a63b5341d --- /dev/null +++ b/dom/base/test/somedatas.resource^headers^ @@ -0,0 +1,3 @@ +Content-Type: text/event-stream +Cache-Control: no-cache, must-revalidate + diff --git a/dom/base/test/test_EventSource_redirects.html b/dom/base/test/test_EventSource_redirects.html new file mode 100644 index 0000000000..8d73fedba4 --- /dev/null +++ b/dom/base/test/test_EventSource_redirects.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=716841 +--> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Test for Bug 338583</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +</head> +<body bgColor=white> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=716841">Mozilla Bug 716841</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + function doTest(test_id) { + source = new EventSource("eventsource_redirect.resource"); + ok(source.url == "http://mochi.test:8888/tests/dom/base/test/eventsource_redirect.resource", "Test failed."); + ok(source.readyState == 0 || source.readyState == 1, "Test failed."); + + source.onopen = function (event) { + ok(true, "opened"); + }; + + source.onmessage = function (event) { + ok(true, "event received"); + source.close(); + SimpleTest.finish(); + }; + + source.onerror = function (event) { + ok(false, "received onError: " + event); + source.close(); + SimpleTest.finish(); + }; + + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(doTest); +</script> +</pre> + +</body> +</html> + diff --git a/dom/base/test/test_Image_constructor.html b/dom/base/test/test_Image_constructor.html new file mode 100644 index 0000000000..d17634b32d --- /dev/null +++ b/dom/base/test/test_Image_constructor.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=862702 +--> +<head> + <meta charset="utf-8"> + <!-- Make sure our script runs before anything else --> + <script> + var img = new Image; + </script> + <title>Test for Bug 862702</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 862702 **/ + is(Object.getPrototypeOf(img), HTMLImageElement.prototype, + "Wrong prototype object"); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=862702">Mozilla Bug 862702</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_NodeIterator_basics_filters.xhtml b/dom/base/test/test_NodeIterator_basics_filters.xhtml new file mode 100644 index 0000000000..5d4a11ad39 --- /dev/null +++ b/dom/base/test/test_NodeIterator_basics_filters.xhtml @@ -0,0 +1,178 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- NodeIterator basics and filters tests. + Originally written by Ian Hickson, Mochi-ified by Zack Weinberg. + This file based on 001.xml, 002.xml, and 010.xml from + http://hixie.ch/tests/adhoc/dom/traversal/node-iterator/ + with some additional cases. + --> +<head> + <title>DOM Traversal: NodeIterator: Basics and Filters</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +<!-- comment --> +<?body processing instruction?> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"><![CDATA[ + function compare_arrays(e, f, label) { + var length = (e.length > f.length) ? e.length : f.length; + for (var i = 0; i < length; i += 1) { + if (e[i] > 0) + is(f[i], e[i], label + " - index " + i + ": "); + else + todo_is(f[i], -e[i], label + " - index " + i + ": "); + } + } + + /** DOM Traversal: NodeIterator: Basics **/ + // NOTE: If you change the document structure, you have to make sure + // the magic numbers in this array (and 'expected_f', below) match. + var expected = new Array(9, // document + 1, // html + 3, 8, // leading comment + 3, 1, // head + 3, 1, 3, // title + 3, 1, // first script tag + 3, 1, // stylesheet tag + 3, // close head + 3, 1, // body + 3, 1, // p#display + 3, 1, // div#content + 3, 8, // comment + 3, 7, // processing instruction + 3, // close div + 3, 1, // pre#test + 3, 1, 4, // script and CDATA block + -3, -3, -3); // close close close + // these aren't there + // not sure why + var found = new Array(); + + var iterator = document.createNodeIterator(document, + NodeFilter.SHOW_ALL, + null); + var node; + + // forwards + while (node = iterator.nextNode()) + found.push(node.nodeType); + compare_arrays(expected, found, 'basics forward'); + + // backwards + found.length = 0; + while (node = iterator.previousNode()) + found.unshift(node.nodeType); + compare_arrays(expected, found, 'basics backward'); + + /** DOM Traversal: NodeIterator: Filters **/ + function filter(n) { + if (n.nodeType == 3) { + return NodeFilter.FILTER_SKIP; + } else if (n.nodeName == 'body') { + return NodeFilter.FILTER_REJECT; // same as _SKIP + } + return 1; // FILTER_ACCEPT + } + + // Same warning applies to this array as to 'expected'. + var expect_f = new Array(9, // document + 1, // html + 8, // leading comment + 1, // head + 1, // title + 1, // first script tag + 1, // stylesheet tag + // body skipped + 1, // p#display + 1, // div#content + 8, // comment + // processing instruction skipped + 1, // pre#test + 1, 4); // script and CDATA block + + found.length = 0; + iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, + filter); + + // forwards + while (node = iterator.nextNode()) + found.push(node.nodeType); + compare_arrays(expect_f, found, 'filtered forward'); + + // backwards + found.length = 0; + while (node = iterator.previousNode()) + found.unshift(node.nodeType); + compare_arrays(expect_f, found, 'filtered backward'); + + function checkBadFilter(method, n) { + var iterator = + document.createNodeIterator(document, NodeFilter.SHOW_ALL, + function() { + if (n < 0) + iterator.detach(); + return NodeFilter.FILTER_ACCEPT; + }); + while (--n >= 0) + iterator.nextNode(); + try { + iterator[method](); + ok(true, "Able to call " + method + " on a NodeIterator after calling no-op detach()"); + } catch (x) { ok(false, x) } + } + checkBadFilter("nextNode", 2); + checkBadFilter("previousNode", 3); + + (function() { + // Implementing the scenario outlined in + // http://bugzilla.mozilla.org/show_bug.cgi?id=552110#c4 + + var iterator = (function(filter) { + var grandparent = document.createElement("div"), + parent = document.createElement("span"); + + grandparent.appendChild(parent); + parent.appendChild(document.createElement("img")); + parent.appendChild(document.createElement("p")); + + return document.createNodeIterator(grandparent, + NodeFilter.SHOW_ALL, + filter); + })(function filter(n) { + if (n.nodeName != "img") + return NodeFilter.FILTER_ACCEPT; + + iterator.detach(); + + n.parentNode.parentNode.removeChild(n.parentNode); + // Drop any node references passed into this function. + for (var i = 0; i < arguments.length; ++i) + arguments[i] = null; + ok(!n, "arguments[0] = null should have nulled out n"); + + // Try to trigger GC. + var xhr = new XMLHttpRequest(); + xhr.open("GET", location.href, false); + xhr.send(); + + return NodeFilter.FILTER_SKIP; + }); + + is(iterator.nextNode().nodeName, "div", + "iterator.nextNode() returned the wrong node"); + is(iterator.nextNode().nodeName, "span", + "iterator.nextNode() returned the wrong node"); + try { + var p = iterator.nextNode(); + ok(false, "iterator.nextNode() should have thrown, but instead it returned <" + p.nodeName + ">"); + } catch (x) { ok(true, x) } + })(); + +]]></script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_NodeIterator_mutations_1.xhtml b/dom/base/test/test_NodeIterator_mutations_1.xhtml new file mode 100644 index 0000000000..028734b6aa --- /dev/null +++ b/dom/base/test/test_NodeIterator_mutations_1.xhtml @@ -0,0 +1,204 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- NodeIterator mutation tests. + Originally written by Ian Hickson, Mochi-ified by Zack Weinberg. + This file based on 00[3-9].xml from + http://hixie.ch/tests/adhoc/dom/traversal/node-iterator/ + --> +<head> + <title>DOM Traversal: NodeIterator: Mutations (1/x)</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +<span id="X"></span><span id="Y"><span id="root1"><span id="A"><span id="B"><span id="C"><span id="D"><span id="E"></span></span></span></span></span></span></span> +<span id="root2"><span id="F"><span id="FF"></span></span><span id="G"></span><span id="H"><span id="HH"></span></span></span> +<span id="root3"><span id="I"><span id="II"></span></span><span id="J"></span><span id="K"><span id="KK"></span></span></span> +<span id="root4"><span id="L"></span><span id="M"><span id="MM"></span></span><span id="N"></span></span> +<span id="root5"><span id="O"></span><span id="P"><span id="PP"></span></span><span id="Q"></span></span> +<span id="root6"><span id="R"></span><span id="S"><span id="SS"></span></span><span id="T"></span></span> +<span id="root7"><span id="U"></span><span id="V"><span id="VV"></span></span><span id="W"></span></span> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"><![CDATA[ + /** Originally written by Ian Hickson. **/ + + function check(f, e, label) { + var eid = e.id; + var fid = f ? f.id : 'null'; + is(f, e, label + ': expected ' + eid + ' have ' + fid); + } + + var childid = 0; + function addChildTo(a) { + var x = document.createElementNS('http://www.w3.org/1999/xhtml', 'span'); + x.id = 'X' + childid; + childid++; + ok(a, 'parent ' + (a?a.id:'undefined') + ' for child ' + x.id); + if (a) + a.appendChild(x); + return x; + } + function remove(a) { + var p = a.parentNode; + ok(a && p, + 'removing ' + ( a?(a.id?a.id:'(no id)'):'undefined' ) + + ' with parent ' + ( p?(p.id?p.id:'(no id)'):'undefined' )); + if (a && p) + p.removeChild(a); + } + + /** Removal of nodes that should have no effect **/ + (function () { + var root = $('root1'); + var A = $('A'); + var B = $('B'); + var C = $('C'); + var D = $('D'); + var E = $('E'); + + var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ALL, + null); + check(iterator.nextNode(), root, '1.0'); + + // 1. Remove a node unrelated to the reference node + remove($('X')); + check(iterator.nextNode(), A, '1.1'); + + // 2. Remove an ancestor of the root node + remove($('Y')); + check(iterator.nextNode(), B, '1.2'); + + // 3. Remove the root node itself + remove(root); + check(iterator.nextNode(), C, '1.3'); + + // 4. Remove a descendant of the reference node + remove(E); + check(iterator.nextNode(), D, '1.4'); + })(); + + /** Removal of the reference node **/ + (function () { + var root = $('root2'); + var F = $('F'); + var FF = $('FF'); + var G = $('G'); + var H = $('H'); + var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ALL, + null); + + check(iterator.nextNode(), root, '2.0'); + check(iterator.nextNode(), F, '2.1'); + check(iterator.nextNode(), FF, '2.2'); + check(iterator.nextNode(), G, '2.3'); + remove(G); + check(iterator.previousNode(), FF, '2.4'); + remove(FF); + check(iterator.nextNode(), H, '2.5'); + })(); + + /** Removal of the reference node (deep check) **/ + (function () { + var root = $('root3'); + var I = $('I'); + var II = $('II'); + var J = $('J'); + var K = $('K'); + var KK = $('KK'); + + var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ALL, + null); + check(iterator.nextNode(), root, '3.0'); + check(iterator.nextNode(), I, '3.1'); + check(iterator.nextNode(), II, '3.2'); + check(iterator.nextNode(), J, '3.3'); + remove(J); + var X = addChildTo(II); + check(iterator.nextNode(), X, '3.4'); + check(iterator.previousNode(), X, '3.5'); + remove(X); + var Y = addChildTo(II); + check(iterator.previousNode(), Y, '3.6'); + check(iterator.nextNode(), Y, '3.7'); + check(iterator.nextNode(), K, '3.8'); + check(iterator.nextNode(), KK, '3.9'); + })(); + + /** Removal of an ancestor of the Reference Node (forwards) **/ + (function () { + var root = $('root4'); + var L = $('L'); + var M = $('M'); + var MM = $('MM'); + var N = $('N'); + + var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ALL, + null); + check(iterator.nextNode(), root, '4.1'); + check(iterator.nextNode(), L, '4.2'); + check(iterator.nextNode(), M, '4.3'); + check(iterator.nextNode(), MM, '4.4'); + remove(M); + check(iterator.previousNode(), L, '4.5'); + })(); + + /** Removal of an ancestor of the Reference Node (forwards) (deep check) **/ + (function () { + var root = $('root5'); + var O = $('O'); + var P = $('P'); + var PP = $('PP'); + var Q = $('Q'); + + var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ALL, + null); + check(iterator.nextNode(), root, '5.1'); + check(iterator.nextNode(), O, '5.2'); + check(iterator.nextNode(), P, '5.3'); + check(iterator.nextNode(), PP, '5.4'); + remove(P); + var X = addChildTo(O); + check(iterator.nextNode(), X, '5.5'); + })(); + + /** Removal of an ancestor of the Reference Node (backwards) **/ + (function () { + var root = $('root6'); + var R = $('R'); + var S = $('S'); + var SS = $('SS'); + var T = $('T'); + + var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ALL, + null); + check(iterator.nextNode(), root, '6.1'); + check(iterator.nextNode(), R, '6.2'); + check(iterator.nextNode(), S, '6.3'); + check(iterator.nextNode(), SS, '6.4'); + check(iterator.previousNode(), SS, '6.5'); + remove(S); + check(iterator.nextNode(), T, '6.6'); + })(); + + /** Removal of an ancestor of the Reference Node (backwards) (deep check) **/ + (function () { + var root = $('root7'); + var U = $('U'); + var V = $('V'); + var VV = $('VV'); + var W = $('W'); + + var iterator = document.createNodeIterator(root, NodeFilter.SHOW_ALL, + null); + check(iterator.nextNode(), root, '7.1'); + check(iterator.nextNode(), U, '7.2'); + check(iterator.nextNode(), V, '7.3'); + check(iterator.nextNode(), VV, '7.4'); + check(iterator.previousNode(), VV, '7.5'); + remove(V); + var X = addChildTo(U); + check(iterator.previousNode(), X, '7.6'); + })(); +]]></script></pre></body></html> diff --git a/dom/base/test/test_NodeIterator_mutations_2.html b/dom/base/test/test_NodeIterator_mutations_2.html new file mode 100644 index 0000000000..a032f8a5bc --- /dev/null +++ b/dom/base/test/test_NodeIterator_mutations_2.html @@ -0,0 +1,112 @@ +<!DOCTYPE HTML> +<html> +<!-- NodeIterator mutation tests, 2. + Originally part of WebKit, Mochi-ified by Zack Weinberg. + This file based on node-iterator-00[...].html from + http://svn.webkit.org/repository/webkit/trunk/LayoutTests/traversal/ + --> +<head> + <title>DOM Traversal: NodeIterator: Mutations (2/x)</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + function resetContent() { + var content = $('content'); + content.innerHTML = ('<span id="A"><\/span><span id="B"><\/span>' + + '<span id="C"><\/span><span id="D"><\/span>' + + '<span id="E"><\/span><span id="F"><\/span>' + + '<span id="G"><\/span><span id="H"><\/span>' + + '<span id="I"><\/span>'); + return content; + } + + function makeSpan(id) { + var e = document.createElement('span'); + e.id = id; + return e; + } + + function testNodeFilter(n) { + if (n.tagName == 'SPAN') + return NodeFilter.FILTER_ACCEPT; + return NodeFilter.FILTER_SKIP; + } + + function checkseq(it, root, expect) { + var checkIt = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + var printedPointer = (it.referenceNode == undefined); + var string = ''; + var node; + while ((node = checkIt.nextNode()) != null) { + if (!printedPointer && it.referenceNode == node) { + printedPointer = true; + var s = '[' + node.id + '] '; + if (it.pointerBeforeReferenceNode) + string += "* " + s; + else + string += s + "* "; + } else { + string += node.id + " "; + } + } + is(string.slice(0, -1), expect, "sequence check"); + } + + // first a basic sanity check [node-iterator-001] + (function(){ + var root = resetContent(); + var it = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + + checkseq(it, root, 'A B C D E F G H I'); + it.nextNode(); + checkseq(it, root, '[A] * B C D E F G H I'); + it.previousNode(); + checkseq(it, root, '* [A] B C D E F G H I'); + it.previousNode(); + checkseq(it, root, '* [A] B C D E F G H I'); + })(); + + // Mutations that should not move the iterator [node-iterator-002] + (function(){ + var root = resetContent(); + var it = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + + for (var i = 0; i < 4; i++) + it.nextNode(); + checkseq(it, root, 'A B C [D] * E F G H I'); + + root.removeChild($('E')); + checkseq(it, root, 'A B C [D] * F G H I'); + + var X = makeSpan('X'); + root.insertBefore(X, $('F')); + checkseq(it, root, 'A B C [D] * X F G H I'); + + var I = $('I'); + root.removeChild(I); + root.insertBefore(I, X); + checkseq(it, root, 'A B C [D] * I X F G H'); + })(); + + // 002 complete + + /* Template + (function(){ + var root = resetContent(); + var it = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + + })(); + */ +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_NodeIterator_mutations_3.html b/dom/base/test/test_NodeIterator_mutations_3.html new file mode 100644 index 0000000000..d3951541d0 --- /dev/null +++ b/dom/base/test/test_NodeIterator_mutations_3.html @@ -0,0 +1,160 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>DOM Traversal: NodeIterator: Mutations (3/x)</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<p id="display"></p> +<div id="content" style="display: none"> + <span id=root><span id=B></span><span id=C></span><span id=D></span><span id=E><span id=E1><span id=E11></span></span></span></span> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + function removeNode(n) { + n.parentNode.removeChild(n); + } + var initInner = $('content').innerHTML; + var content = $('content'); + + + function resetContent() { + content.innerHTML = initInner; + var checkIt = document.createNodeIterator(content, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + var node; + while ((node = checkIt.nextNode()) != null) { + if (node.id) { + window[node.id] = node; + } + } + } + + function makeSpan(id) { + var e = document.createElement('span'); + e.id = id; + return e; + } + + function testNodeFilter(n) { + if (n.tagName == 'SPAN') + return NodeFilter.FILTER_ACCEPT; + return NodeFilter.FILTER_SKIP; + } + + function checkseq(it, root, expect) { + var checkIt = document.createNodeIterator(root, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + var printedPointer = (it.referenceNode == undefined); + var string = ''; + var node; + while ((node = checkIt.nextNode()) != null) { + if (!printedPointer && it.referenceNode == node) { + printedPointer = true; + var s = '[' + node.id + '] '; + if (it.pointerBeforeReferenceNode) + string += "* " + s; + else + string += s + "* "; + } else { + string += node.id + " "; + } + } + is(string.slice(0, -1), expect, "sequence check"); + } + + resetContent(); + var it = document.createNodeIterator(E, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + checkseq(it, root, "root B C D * [E] E1 E11"); + + removeNode(C); + checkseq(it, root, "root B D * [E] E1 E11"); + + it.nextNode(); + removeNode(D); + checkseq(it, root, "root B [E] * E1 E11"); + + it.nextNode(); + removeNode(B); + checkseq(it, root, "root E [E1] * E11"); + + it.nextNode(); + checkseq(it, root, "root E E1 [E11] *"); + + it.nextNode(); + checkseq(it, root, "root E E1 [E11] *"); + + it.previousNode(); + it.previousNode(); + it.previousNode(); + it.previousNode(); + it.previousNode(); + checkseq(it, root, "root * [E] E1 E11"); + + resetContent(); + it = document.createNodeIterator(E, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + checkseq(it, root, "root B C D * [E] E1 E11"); + + it.nextNode(); + it.nextNode(); + checkseq(it, root, "root B C D E [E1] * E11"); + + it.previousNode(); + it.previousNode(); + checkseq(it, root, "root B C D * [E] E1 E11"); + + removeNode(D); + removeNode(B); + checkseq(it, root, "root C * [E] E1 E11"); + + n = makeSpan('n'); + root.insertBefore(n, E); + checkseq(it, root, "root C n * [E] E1 E11"); + + n2 = makeSpan('n2'); + root.insertBefore(n2, C); + checkseq(it, root, "root n2 C n * [E] E1 E11"); + + resetContent(); + it = document.createNodeIterator(E, NodeFilter.SHOW_ELEMENT, + testNodeFilter); + checkseq(it, root, "root B C D * [E] E1 E11"); + + removeNode(root); + checkseq(it, root, "root B C D * [E] E1 E11"); + + removeNode(B); + checkseq(it, root, "root C D * [E] E1 E11"); + + removeNode(D); + checkseq(it, root, "root C * [E] E1 E11"); + + it.nextNode(); + it.nextNode(); + it.nextNode(); + checkseq(it, root, "root C E E1 [E11] *"); + + removeNode(E1); + checkseq(it, root, "root C [E] *"); + + n = makeSpan('n'); + root.insertBefore(n, E); + checkseq(it, root, "root C n [E] *"); + + n2 = makeSpan('n2'); + E.appendChild(n2); + checkseq(it, root, "root C n [E] * n2"); + + it.nextNode(); + checkseq(it, root, "root C n E [n2] *"); + + removeNode(E); + checkseq(it, root, "root C n"); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_anchor_area_referrer.html b/dom/base/test/test_anchor_area_referrer.html new file mode 100644 index 0000000000..acf96080a8 --- /dev/null +++ b/dom/base/test/test_anchor_area_referrer.html @@ -0,0 +1,125 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test anchor and area policy attribute for Bug 1174913</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that anchor and area referrer attributes are honoured correctly + * anchor tag with referrer attribute (generate-anchor-policy-test) + https://bugzilla.mozilla.org/show_bug.cgi?id=1174913 + --> + + <script type="application/javascript;version=1.8"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL", "SCHEME_FROM", "SCHEME_TO"]; + + const testCases = [ + {ACTION: ["generate-anchor-policy-test", "generate-area-policy-test"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "unsafe-url (anchor) with origin in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin', + NAME: 'origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + DESC: "origin (anchor) with unsafe-url in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'no-referrer-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "no-referrer (anchor) with origin in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'same-origin-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "same-origin with origin in meta", + RESULT: 'full'}, + {NAME: 'no-referrer-in-meta', + META_POLICY: 'no-referrer', + DESC: "no-referrer in meta", + RESULT: 'none'}, + + // Test if element attr would override meta referr policy. + + // 1. Downgrade. + {ATTRIBUTE_POLICY: 'no-referrer-when-downgrade', + NAME: 'origin-in-meta-downgrade-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta downgrade in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin-when-cross-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + + // 2. No downgrade. + {ATTRIBUTE_POLICY: 'no-referrer-when-downgrade', + NAME: 'origin-in-meta-downgrade-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta downgrade in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin-when-cross-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'strict-origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + DESC: "strict-origin-when-cross-origin with origin in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'same-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + DESC: "same-origin with origin in meta", + RESULT: 'none'}, + + // End of element attr overriding test.. + + {ATTRIBUTE_POLICY: 'origin', + NAME: 'origin-with-no-meta', + META_POLICY: '', + DESC: "origin (anchor) with no meta", + RESULT: 'origin'}]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> + diff --git a/dom/base/test/test_anchor_area_referrer_changing.html b/dom/base/test/test_anchor_area_referrer_changing.html new file mode 100644 index 0000000000..167d2ef636 --- /dev/null +++ b/dom/base/test/test_anchor_area_referrer_changing.html @@ -0,0 +1,66 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test anchor and area policy attribute for Bug 1174913</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that anchor and area referrer attributes are honoured correctly + This test is split due to errors on b2g + * testing setAttribute and .referrer (generate-anchor-changing-test) + https://bugzilla.mozilla.org/show_bug.cgi?id=1174913 + --> + + <script type="application/javascript;version=1.8"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL"]; + + const testCases = [ + {ACTION: ["generate-anchor-changing-policy-test-set-attribute", "generate-area-changing-policy-test-set-attribute"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NEW_ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'no-referrer-unsafe-url-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "no-referrer (anchor, orginally unsafe-url) with origin in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'origin', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-origin-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + DESC: "unsafe-url (anchor, orginally origin) with no-referrer in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-origin-with-no-referrer-in-meta-rel', + META_POLICY: 'no-referrer', + DESC: "unsafe-url (anchor, orginally origin) with no-referrer in meta and rel=noreferrer", + RESULT: 'none', + REL: 'noreferrer'}]}, + {ACTION: ["generate-anchor-changing-policy-test-property", "generate-area-changing-policy-test-property"], + TESTS: [ + {ATTRIBUTE_POLICY: 'no-referrer', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-no-referrer-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "unsafe-url (anchor, orginally no-referrer) with origin in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'no-referrer', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-no-referrer-with-origin-in-meta-rel', + META_POLICY: 'origin', + DESC: "unsafe-url (anchor, orginally no-referrer) with origin in meta and rel=noreferrer", + RESULT: 'none', + REL: 'noreferrer'}]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> + diff --git a/dom/base/test/test_anchor_area_referrer_invalid.html b/dom/base/test/test_anchor_area_referrer_invalid.html new file mode 100644 index 0000000000..ed56aa3995 --- /dev/null +++ b/dom/base/test/test_anchor_area_referrer_invalid.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test anchor and area policy attribute for Bug 1174913</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that anchor and area referrer attributes are honoured correctly + * anchor tag with invalid referrer attributes + https://bugzilla.mozilla.org/show_bug.cgi?id=1174913 + --> + + <script type="application/javascript;version=1.8"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL", , "SCHEME_FROM", "SCHEME_TO"]; + + const testCases = [ + {ACTION: ["generate-anchor-policy-test", "generate-area-policy-test"], + TESTS: [ + // setting invalid refer values -> we expect either full referrer (default) + // or whatever is specified in the meta referrer policy + + // Note that for those test cases which require cross-origin test, we use different + // scheme to result in cross-origin request. + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-no-meta', + META_POLICY: '', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + DESC: "origin-when-cross-origin (anchor) with no meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'default', + NAME: 'default-with-no-meta', + META_POLICY: '', + DESC: "default (anchor) with no meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'something', + NAME: 'something-with-no-meta', + META_POLICY: '', + DESC: "something (anchor) with no meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + DESC: "origin-when-cross-origin (anchor) with no-referrer in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + DESC: "origin-when-cross-origin (anchor) with unsafe-url in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + DESC: "origin-when-cross-origin (anchor) with origin in meta", + RESULT: 'origin'}]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> + diff --git a/dom/base/test/test_anchor_area_referrer_rel.html b/dom/base/test/test_anchor_area_referrer_rel.html new file mode 100644 index 0000000000..859cf4eeeb --- /dev/null +++ b/dom/base/test/test_anchor_area_referrer_rel.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test anchor and area policy attribute for Bug 1174913</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that anchor and area referrer attributes are honoured correctly + * anchor tag with referrer attribute with rel=noreferrer + https://bugzilla.mozilla.org/show_bug.cgi?id=1174913 + --> + + <script type="application/javascript;version=1.8"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL"]; + + const testCases = [ + {ACTION: ["generate-anchor-policy-test", "generate-area-policy-test"], + TESTS: [ + // setting rel=noreferrer -> we expect no referrer + {ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-with-origin-in-meta-rel', + META_POLICY: 'origin', + DESC: "unsafe-url (anchor) with origin in meta and rel=noreferrer", + RESULT: 'none', + REL: 'noreferrer'}, + {ATTRIBUTE_POLICY: 'origin', + NAME: 'origin-with-unsafe-url-in-meta-rel', + META_POLICY: 'unsafe-url', + DESC: "origin (anchor) with unsafe-url in meta and rel=noreferrer", + RESULT: 'none', + REL: 'noreferrer'}, + {ATTRIBUTE_POLICY: 'origin', + NAME: 'origin-with-no-meta-rel', + META_POLICY: '', + DESC: "origin (anchor) with no meta and rel=noreferrer", + RESULT: 'none', + REL: 'noreferrer'}]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> + diff --git a/dom/base/test/test_anonymousContent_api.html b/dom/base/test/test_anonymousContent_api.html new file mode 100644 index 0000000000..4c6aa51ac2 --- /dev/null +++ b/dom/base/test/test_anonymousContent_api.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1020244 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1020244 - Test the chrome-only AnonymousContent API</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1020244">Mozilla Bug 1020244</a> + <script type="application/javascript;version=1.8"> + + // Testing the presence of the chrome-only API + ok(!document.insertAnonymousContent, + "Content document shouldn't have access to insertAnonymousContent"); + ok(!document.removeAnonymousContent, + "Content document shouldn't have access to removeAnonymousContent"); + + let chromeDocument = SpecialPowers.wrap(document); + ok(chromeDocument.insertAnonymousContent, + "Chrome document should have access to insertAnonymousContent"); + ok(chromeDocument.removeAnonymousContent, + "Chrome document should have access to removeAnonymousContent"); + + // Testing invalid inputs + let invalidNodes = [null, undefined, false, 1, "string"]; + for (let node of invalidNodes) { + let didThrow = false; + try { + chromeDocument.insertAnonymousContent(node); + } catch (e) { + didThrow = true; + } + ok(didThrow, "Passing an invalid node to insertAnonymousContent should throw"); + } + + // Testing the API of the returned object + let div = document.createElement("div"); + div.textContent = "this is a test element"; + let anonymousContent = chromeDocument.insertAnonymousContent(div); + ok(anonymousContent, "AnonymousContent object returned"); + + let members = ["getTextContentForElement", "setTextContentForElement", + "getAttributeForElement", "setAttributeForElement", + "removeAttributeForElement", "getCanvasContext", + "setAnimationForElement"]; + for (let member of members) { + ok(member in anonymousContent, "AnonymousContent object defines " + member); + } + chromeDocument.removeAnonymousContent(anonymousContent); + </script> +</body> +</html> diff --git a/dom/base/test/test_anonymousContent_append_after_reflow.html b/dom/base/test/test_anonymousContent_append_after_reflow.html new file mode 100644 index 0000000000..b88de89d50 --- /dev/null +++ b/dom/base/test/test_anonymousContent_append_after_reflow.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1020244 --> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1020244 - Make sure anonymous content still works after a reflow (after the canvasframe has been reconstructed)</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<div> + <div id="test-element" style="color:red;">text content</div> +</div> +<script type="application/javascript;version=1.8"> + info("Inserting anonymous content into the document frame"); + let chromeDocument = SpecialPowers.wrap(document); + let testElement = document.querySelector("div"); + let anonymousContent = chromeDocument.insertAnonymousContent(testElement); + + info("Modifying the style of an element in the anonymous content"); + let style = anonymousContent.setAttributeForElement("test-element", + "style", "color:green;"); + + info("Toggling the display style on the document element to force reframing"); + // Note that we force sync reflows to make sure the canvasframe is recreated + // synchronously. + document.documentElement.style.display = "none"; + let forceFlush = document.documentElement.offsetHeight; + document.documentElement.style.display = "block"; + forceFlush = document.documentElement.offsetHeight; + + info("Checking that the anonymous content can be retrieved still"); + style = anonymousContent.getAttributeForElement("test-element", "style"); + is(style, "color:green;", "The anonymous content still exists after reflow"); + + info("Removing the anonymous content"); + chromeDocument.removeAnonymousContent(anonymousContent); +</script> +</body> +</html> diff --git a/dom/base/test/test_anonymousContent_canvas.html b/dom/base/test/test_anonymousContent_canvas.html new file mode 100644 index 0000000000..9ee1eca200 --- /dev/null +++ b/dom/base/test/test_anonymousContent_canvas.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1212477 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1212477 - Needs a way to access to <canvas>'s context (2d, webgl) from Anonymous Content API</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1212477">Mozilla Bug 1212477</a> + <div> + <div id="id" class="test">text content</div> + <canvas id="canvas2d"></canvas> + <canvas id="canvas-webgl"></canvas> + <canvas id="canvas-foo"></canvas> + </div> + <script type="application/javascript;version=1.8"> + let chromeDocument = SpecialPowers.wrap(document); + let testElement = document.querySelector("div"); + + let anonymousContent = chromeDocument.insertAnonymousContent(testElement); + + is(anonymousContent.getCanvasContext("id", "2d"), null, + "Context is null for non-canvas elements"); + + let context2d = anonymousContent.getCanvasContext("canvas2d", "2d"); + + is(context2d.toString(), "[object CanvasRenderingContext2D]", + "2D Context is returned properly"); + + is(context2d.canvas, null, + "context's canvas property is null in anonymous content"); + + is (anonymousContent.getCanvasContext("canvas-foo", "foo"), null, + "Context is null for unknown context type"); + + SimpleTest.doesThrow( + () => anonymousContent.getCanvasContext("foo", "2d"), + "NS_ERROR_NOT_AVAILABLE", + "Get a context using unexisting id should throw" + ); + + let webgl = anonymousContent.getCanvasContext("canvas-webgl", "webgl"); + + is(webgl.toString(), "[object WebGLRenderingContext]", + "WebGL Context is returned properly"); + + is(webgl.canvas, null, + "WebGL context's canvas property is null in anonymous content"); + + chromeDocument.removeAnonymousContent(anonymousContent); + </script> +</body> +</html> diff --git a/dom/base/test/test_anonymousContent_insert.html b/dom/base/test/test_anonymousContent_insert.html new file mode 100644 index 0000000000..c502ed2544 --- /dev/null +++ b/dom/base/test/test_anonymousContent_insert.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1020244 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1020244 - Insert content using the AnonymousContent API, several times, and don't remove it</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1020244">Mozilla Bug 1020244</a> +<div> + <div id="id" class="test">text content</div> +</div> + <script type="application/javascript;version=1.8"> + const INSERTED_NB = 5; + + // Insert the same content several times + let chromeDocument = SpecialPowers.wrap(document); + let testElement = document.querySelector("div"); + + let anonymousContents = []; + for (let i = 0; i < INSERTED_NB; i ++) { + let content = chromeDocument.insertAnonymousContent(testElement); + // Adding an expando pointing to the document to make sure this doesn't + // cause leaks. + content.dummyExpando = testElement.ownerDocument; + anonymousContents.push(content); + } + + // Make sure that modifying one of the inserted elements does not modify the + // other ones. + anonymousContents[0].setAttributeForElement("id", "class", "updated"); + for (let i = 1; i < INSERTED_NB; i ++) { + is(anonymousContents[i].getAttributeForElement("id", "class"), + "test", + "Element " + i + " didn't change when element 0 was changed"); + } + + // Do not remove inserted elements on purpose to test for potential leaks too. + </script> +</body> +</html> diff --git a/dom/base/test/test_anonymousContent_manipulate_content.html b/dom/base/test/test_anonymousContent_manipulate_content.html new file mode 100644 index 0000000000..ef4c002879 --- /dev/null +++ b/dom/base/test/test_anonymousContent_manipulate_content.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1020244 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1020244 - Manipulate content created with the AnonymousContent API</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1020244">Mozilla Bug 1020244</a> +<div> + <div id="test-element" class="test-class" test="test">text content</div> +</div> + <script type="application/javascript;version=1.8"> + + // Insert content + let chromeDocument = SpecialPowers.wrap(document); + let testElement = document.querySelector("div"); + let anonymousContent = chromeDocument.insertAnonymousContent(testElement); + + // Test getting/setting text content. + is(anonymousContent.getTextContentForElement("test-element"), + "text content", "Textcontent for the test element is correct"); + + anonymousContent.setTextContentForElement("test-element", + "updated text content"); + is(anonymousContent.getTextContentForElement("test-element"), + "updated text content", + "Textcontent for the test element is correct after update"); + + // Test that modifying the original DOM element doesn't change the inserted + // element. + testElement.removeAttribute("test"); + is(anonymousContent.getAttributeForElement("test-element", "test"), + "test", + "Removing attributes on the original DOM node does not change the inserted node"); + + testElement.setAttribute("test", "test-updated"); + is(anonymousContent.getAttributeForElement("test-element", "test"), + "test", + "Setting attributes on the original DOM node does not change the inserted node"); + + // Test getting/setting/removing attributes on the inserted element and test + // that this doesn't change the original DOM element. + is(anonymousContent.getAttributeForElement("test-element", "class"), + "test-class", "Class attribute for the test element is correct"); + + anonymousContent.setAttributeForElement("test-element", "class", + "updated-test-class"); + is(anonymousContent.getAttributeForElement("test-element", "class"), + "updated-test-class", + "Class attribute for the test element is correct after update"); + ok(testElement.getAttribute("class") !== "updated-test-class", + "Class attribute change on the inserted node does not change the original DOM node"); + + anonymousContent.removeAttributeForElement("test-element", "class"); + is(anonymousContent.getAttributeForElement("test-element", "class"), null, + "Class attribute for the test element was removed"); + + let anim = anonymousContent.setAnimationForElement("test-element", [ + { transform: 'translateY(0px)' }, + { transform: 'translateY(-300px)' } + ], 2000); + is(anim.playState, "pending", "Animation should be running"); + anim.cancel(); + is(anim.playState, "idle", "Animation should have stopped immediately"); + + chromeDocument.removeAnonymousContent(anonymousContent); + </script> +</body> +</html> diff --git a/dom/base/test/test_anonymousContent_style_csp.html b/dom/base/test/test_anonymousContent_style_csp.html new file mode 100644 index 0000000000..6f41926996 --- /dev/null +++ b/dom/base/test/test_anonymousContent_style_csp.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1020244 --> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1185351 - Make sure that we don't enforce CSP on styles for AnonymousContent</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<div> + <div id="test-element" style="color:red;">text content</div> +</div> +<script type="application/javascript;version=1.8"> + let chromeDocument = SpecialPowers.wrap(document); + let testElement = document.querySelector("div"); + let anonymousContent = chromeDocument.insertAnonymousContent(testElement); + + let style = anonymousContent.setAttributeForElement("test-element", + "style", "color:green;"); + + style = anonymousContent.getAttributeForElement("test-element", "style"); + is(style, "color:green;", "The anonymous content exists with CSP"); + + chromeDocument.removeAnonymousContent(anonymousContent); +</script> +</body> +</html> diff --git a/dom/base/test/test_anonymousContent_style_csp.html^headers^ b/dom/base/test/test_anonymousContent_style_csp.html^headers^ new file mode 100644 index 0000000000..b7b3c8a4f9 --- /dev/null +++ b/dom/base/test/test_anonymousContent_style_csp.html^headers^ @@ -0,0 +1 @@ +Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' diff --git a/dom/base/test/test_anonymousContent_xul_window.xul b/dom/base/test/test_anonymousContent_xul_window.xul new file mode 100644 index 0000000000..1dcb2d201a --- /dev/null +++ b/dom/base/test/test_anonymousContent_xul_window.xul @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1020244 +Check that XUL windows aren't supported, that the API throws, but doesn't crash. +--> +<window title="Anonymous content in a XUL window" +xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"></body> + <box>This is a test box</box> + + <script type="application/javascript;version=1.8"> + // Insert content + let testElement = document.querySelector("box"); + + let didThrow = false; + try { + document.insertAnonymousContent(testElement); + } catch (e) { + didThrow = true; + } + + ok(didThrow, + "Inserting anonymous content in a XUL document did throw an exception") + </script> +</window> diff --git a/dom/base/test/test_applet_alternate_content.html b/dom/base/test/test_applet_alternate_content.html new file mode 100644 index 0000000000..88cb12f1fb --- /dev/null +++ b/dom/base/test/test_applet_alternate_content.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1200602 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1200602</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SpecialPowers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1200602">Mozilla Bug 1200602</a> +<pre id="test"> +<script type="application/javascript;version=1.8"> + +function test() { + "use strict"; + + const objLC = SpecialPowers.Ci.nsIObjectLoadingContent; + let obj = document.createElement("applet"); + obj.appendChild(document.createTextNode("alternate content")); + document.body.appendChild(obj); + + obj instanceof objLC; + obj = SpecialPowers.wrap(obj); + + // We expect this tag to simply go to alternate content, not get a + // pluginProblem binding or fire any events. + ok(obj.displayedType == objLC.TYPE_NULL, "expected null type"); + ok(obj.pluginFallbackType == objLC.PLUGIN_ALTERNATE, + "expected alternate fallback mode"); +} + +// Test all non-plugin types these tags can load to make sure none of them +// trigger plugin-specific fallbacks when loaded with no URI +test(); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_appname_override.html b/dom/base/test/test_appname_override.html new file mode 100644 index 0000000000..d94977a53f --- /dev/null +++ b/dom/base/test/test_appname_override.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=939445 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 939445 - general.appname.override</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=939445">Mozilla Bug 939445</a> + <script type="application/javascript"> + + function runTest() { + is(navigator.appName, "hello", "general.appname.override not working"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPrefEnv({"set": [["general.appname.override", "hello"]]}, runTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_async_setTimeout_stack.html b/dom/base/test/test_async_setTimeout_stack.html new file mode 100644 index 0000000000..fb3c74b291 --- /dev/null +++ b/dom/base/test/test_async_setTimeout_stack.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1142577 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1142577 - Async stacks for setTimeout</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1142577">Mozilla Bug 1142577</a> + <pre id="stack"></pre> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("Testing async stacks across setTimeout"); + + function getFunctionName(frame) { + return frame.slice(0, frame.indexOf("@")); + } + + function a() { b() } + function b() { c() } + function c() { setTimeout(d, 1) } + function d() { e() } + function e() { f() } + function f() { setTimeout(g, 1) } + function g() { h() } + function h() { i() } + function i() { + var stackString = Error().stack; + document.getElementById("stack").textContent = stackString; + + var frames = stackString + .split("\n") + .map(getFunctionName) + .filter(function (name) { return !!name; }); + + is(frames[0], "i"); + is(frames[1], "h"); + is(frames[2], "g"); + is(frames[3], "setTimeout handler*SimpleTest_setTimeoutShim"); + is(frames[4], "f"); + is(frames[5], "e"); + is(frames[6], "d"); + is(frames[7], "setTimeout handler*SimpleTest_setTimeoutShim"); + is(frames[8], "c"); + is(frames[9], "b"); + is(frames[10], "a"); + + SimpleTest.finish(); + } + + SpecialPowers.pushPrefEnv( + {"set": [['javascript.options.asyncstack', true]]}, + a); + </script> +</body> +</html> diff --git a/dom/base/test/test_async_setTimeout_stack_across_globals.html b/dom/base/test/test_async_setTimeout_stack_across_globals.html new file mode 100644 index 0000000000..5b44072d6f --- /dev/null +++ b/dom/base/test/test_async_setTimeout_stack_across_globals.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1142577 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1142577 - Async stacks for setTimeout</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1142577">Mozilla Bug 1142577</a> + <pre id="stack"></pre> + <iframe id="iframe"></iframe> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + + var otherGlobal = document.getElementById("iframe").contentWindow; + + function getFunctionName(frame) { + return frame.slice(0, frame.indexOf("@")); + } + + function a() { b() } + function b() { c() } + function c() { otherGlobal.setTimeout(d, 1) } + function d() { e() } + function e() { f() } + function f() { otherGlobal.setTimeout(g, 1) } + function g() { h() } + function h() { i() } + function i() { + var stackString = Error().stack; + document.getElementById("stack").textContent = stackString; + + var frames = stackString + .split("\n") + .map(getFunctionName) + .filter(function (name) { return !!name; }); + + is(frames[0], "i"); + is(frames[1], "h"); + is(frames[2], "g"); + is(frames[3], "setTimeout handler*f"); + is(frames[4], "e"); + is(frames[5], "d"); + is(frames[6], "setTimeout handler*c"); + is(frames[7], "b"); + is(frames[8], "a"); + + SimpleTest.finish(); + } + + SpecialPowers.pushPrefEnv( + {"set": [['javascript.options.asyncstack', true]]}, + a); + </script> +</body> +</html> diff --git a/dom/base/test/test_audioNotification.html b/dom/base/test/test_audioNotification.html new file mode 100644 index 0000000000..a7f42f106b --- /dev/null +++ b/dom/base/test/test_audioNotification.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var audio = new Audio(); +audio.src = "audio.ogg"; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-pause'; + audio.pause(); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_audioNotificationSilent_audioFile.html b/dom/base/test/test_audioNotificationSilent_audioFile.html new file mode 100644 index 0000000000..0b3b895801 --- /dev/null +++ b/dom/base/test/test_audioNotificationSilent_audioFile.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Audio-playback should be inactive when input file is silent</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); + +var generator = runTest(); +var expectedPlaybackActive = null; + +var audio = new Audio(); +audio.src = "audioEndedDuringPlaying.webm"; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedPlaybackActive, "Corrrect audible state"); + continueTest(); + } +}; + +function continueTest() { + try { + generator.next(); + } catch (e if e instanceof StopIteration) { + error("Stop test because of exception!"); + } +} + +function audioPlayingStart() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + + expectedPlaybackActive = 'active'; + + info("Audio playing start"); + audio.play(); +} + +function audioBecomeSilentDuringPlaying() { + info("Audio would become silent during playing"); + + expectedPlaybackActive = 'inactive-nonaudible'; +} + +function finish() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + + SimpleTest.finish(); +} + +function runTest() { + yield audioPlayingStart(); + + yield audioBecomeSilentDuringPlaying(); + + yield finish(); +} + +continueTest(); + +</script> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/test_audioNotificationSilent_webAudio.html b/dom/base/test/test_audioNotificationSilent_webAudio.html new file mode 100644 index 0000000000..de4165f8e4 --- /dev/null +++ b/dom/base/test/test_audioNotificationSilent_webAudio.html @@ -0,0 +1,103 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Audio-playback should be inactive when web-audio is silent</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); + +var generator = runTest(); +var expectedPlaybackActive = null; +var expectedPlaying = null; + +var ac = new AudioContext(); +var audibleDuration = 3; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedPlaybackActive, "Corrrect audible state"); + is(ac.state, expectedPlaying, "Corrrect playing state"); + continueTest(); + } +}; + +function continueTest() { + try { + generator.next(); + } catch (e if e instanceof StopIteration) { + error("Stop test because of exception!"); + } +} + +function playOscillatorNode() { + var dest = ac.destination; + var osc = ac.createOscillator(); + osc.connect(dest); + osc.start(0); + osc.stop(ac.currentTime + audibleDuration); +} + +function audioPlayingStart() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + + expectedPlaybackActive = 'active'; + expectedPlaying = "running"; + + info("Audio playing start"); + playOscillatorNode(); +} + +function audioBecomeSilentDuringPlaying() { + info("Audio would become silent during playing"); + + expectedPlaybackActive = 'inactive-pause'; + expectedPlaying = "running"; +} + +function finish() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + + SimpleTest.finish(); +} + +function startAudioContext() { + if (ac.state != "running") { + ac.resume(); + ac.onstatechange = function() { + if (ac.state == "running") { + ok(true, "AudioContext starts running!"); + ac.onstatechange = null; + continueTest(); + } + } + } else { + ok(true, "AudioContext is running!"); + continueTest(); + } +} + +function runTest() { + yield startAudioContext(); + + yield audioPlayingStart(); + + yield audioBecomeSilentDuringPlaying(); + + yield finish(); +} + +continueTest(); + +</script> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/test_audioNotificationStopOnNavigation.html b/dom/base/test/test_audioNotificationStopOnNavigation.html new file mode 100644 index 0000000000..2ca0d77784 --- /dev/null +++ b/dom/base/test/test_audioNotificationStopOnNavigation.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> +<iframe></iframe> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; +var iframe = null; + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var tests = [ + function() { + iframe = document.querySelector("iframe"); + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + expectedNotification = 'active'; + iframe.src = "file_audioLoop.html"; + }, + + function() { + expectedNotification = 'inactive-pause'; + iframe.src = "data:text/html,page without audio"; + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +onload = runTest; + +</script> +</body> +</html> + diff --git a/dom/base/test/test_audioNotificationStream.html b/dom/base/test/test_audioNotificationStream.html new file mode 100644 index 0000000000..f27f99316d --- /dev/null +++ b/dom/base/test/test_audioNotificationStream.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var audio = new Audio(); +audio.srcObject = (new AudioContext()).createMediaStreamDestination().stream; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-pause'; + audio.pause(); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_audioNotificationWithEarlyPlay.html b/dom/base/test/test_audioNotificationWithEarlyPlay.html new file mode 100644 index 0000000000..23b051250f --- /dev/null +++ b/dom/base/test/test_audioNotificationWithEarlyPlay.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var audio = new Audio(); +audio.loop = true; +audio.preload = "metadata"; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + expectedNotification = 'active'; + audio.src = "audio.ogg"; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-pause'; + audio.pause(); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_audioWindowUtils.html b/dom/base/test/test_audioWindowUtils.html new file mode 100644 index 0000000000..a6067cfd6b --- /dev/null +++ b/dom/base/test/test_audioWindowUtils.html @@ -0,0 +1,107 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<iframe src="about:blank" id="iframe"></iframe> +<script type="application/javascript"> + +function runTest() { + var utils = SpecialPowers.wrap(window). + QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor). + getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); + ok(utils, "nsIDOMWindowUtils"); + + is(utils.audioMuted, false, "By default utils.audioMuted is false"); + utils.audioMuted = true; + is(utils.audioMuted, true, "utils.audioMuted is true"); + utils.audioMuted = false; + is(utils.audioMuted, false, "utils.audioMuted is true"); + + is(utils.audioVolume, 1.0, "By default utils.audioVolume is 1.0"); + utils.audioVolume = 0.4; + is(utils.audioVolume.toFixed(2), "0.40", "utils.audioVolume is ok"); + utils.audioMuted = true; + is(utils.audioMuted, true, "utils.audioMuted is true"); + is(utils.audioVolume.toFixed(2), "0.40", "utils.audioVolume is ok"); + utils.audioMuted = false; + + utils.audioVolume = 2.0; + is(utils.audioVolume, 2.0, "utils.audioVolume is ok"); + + try { + utils.audioVolume = -42; + ok(false, "This should throw"); + } catch(e) { + ok(true, "This should throw"); + } + + utils.audioVolume = 0; + is(utils.audioVolume, 0.0, "utils.audioVolume is ok"); + utils.audioVolume = 1.0; + is(utils.audioVolume, 1.0, "utils.audioVolume is ok"); + + var iframe = document.getElementById("iframe"); + ok(iframe, "IFrame exists"); + + utils = SpecialPowers.wrap(iframe.contentWindow). + QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor). + getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); + ok(utils, "nsIDOMWindowUtils"); + + is(utils.audioMuted, false, "By default utils.audioMuted is false"); + utils.audioMuted = true; + is(utils.audioMuted, true, "utils.audioMuted is true"); + utils.audioMuted = false; + is(utils.audioMuted, false, "utils.audioMuted is true"); + + is(utils.audioVolume, 1.0, "By default utils.audioVolume is 1.0"); + utils.audioVolume = 0.4; + is(utils.audioVolume.toFixed(2), "0.40", "utils.audioVolume is ok"); + utils.audioMuted = true; + is(utils.audioMuted, true, "utils.audioMuted is true"); + is(utils.audioVolume.toFixed(2), "0.40", "utils.audioVolume is ok"); + utils.audioMuted = false; + + utils.audioVolume = 2.0; + is(utils.audioVolume, 2.0, "utils.audioVolume is ok"); + + try { + utils.audioVolume = -42; + ok(false, "This should throw"); + } catch(e) { + ok(true, "This should throw"); + } + + utils.audioVolume = 0; + is(utils.audioVolume, 0.0, "utils.audioVolume is ok"); + utils.audioVolume = 0.6; + is(utils.audioVolume.toFixed(2), "0.60", "utils.audioVolume is ok"); + utils.audioMuted = true; + + // Navigate the iframe to another URL, and verify that the volume and muted + // information is preserved. + iframe.onload = function() { + utils = SpecialPowers.wrap(iframe.contentWindow). + QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor). + getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); + ok(utils, "nsIDOMWindowUtils"); + + ok(utils.audioMuted, "Audio should still be muted"); + utils.audioMuted = false; + ok(utils.audioVolume.toFixed(2), "0.60", "Volume should be preserved"); + + SimpleTest.finish(); + }; + iframe.src = "data:text/html,page"; +} + +onload = runTest; +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> diff --git a/dom/base/test/test_base.xhtml b/dom/base/test/test_base.xhtml new file mode 100644 index 0000000000..e4aba6ebe1 --- /dev/null +++ b/dom/base/test/test_base.xhtml @@ -0,0 +1,55 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Test for base URIs</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <base href="/tests/dom/base/" /> + <style> + #bound { -moz-binding: url("test/file_base_xbl.xml#test"); } + </style> +</head> +<body> +<div id="1" xml:base="supercalifragilisticexpialidocious"><p><p xml:base="hello/"><p xml:base="world"><span xml:base="#iamtheverymodelofamodernmajorgeneral">text</span></p></p></p></div> +<div id="bound"/> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + is(document.baseURI, "http://mochi.test:8888/tests/dom/base/", + "document base"); + is(document.body.baseURI, "http://mochi.test:8888/tests/dom/base/", + "body base"); + + var expected = + ["http://mochi.test:8888/tests/dom/base/supercalifragilisticexpialidocious", + "http://mochi.test:8888/tests/dom/base/supercalifragilisticexpialidocious", + "http://mochi.test:8888/tests/dom/base/hello/", + "http://mochi.test:8888/tests/dom/base/hello/world", + "http://mochi.test:8888/tests/dom/base/hello/world#iamtheverymodelofamodernmajorgeneral", + "http://mochi.test:8888/tests/dom/base/hello/world#iamtheverymodelofamodernmajorgeneral", + ]; + var node = document.getElementById("1"); + while(node) { + is(node.baseURI, expected.shift(), "node base"); + node = node.firstChild; + } + is(expected.length, 0, "found all expected nodes"); + + var svgExpected = + ["http://mochi.test:8888/tests/dom/base/test/file_base_xbl.xml", + "http://mochi.test:8888/tests/dom/base/test/file_base_xbl.xml", + "http://mochi.test:8888/tests/dom/base/test/file_base_xbl.xml#shesellsseashellsbytheseashore", + ]; + node = SpecialPowers.wrap(document).getAnonymousNodes(document.getElementById("bound"))[0]; + while(node) { + is(node.baseURI, svgExpected.shift(), "node base"); + node = node.firstChild; + } + is(svgExpected.length, 0, "found all expected nodes"); + + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_blobURL_expiring.html b/dom/base/test/test_blobURL_expiring.html new file mode 100644 index 0000000000..a4a796849f --- /dev/null +++ b/dom/base/test/test_blobURL_expiring.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Blob URI expiration</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <script> + +onmessage = function(e) { + var blobURL = e.data; + + (new Promise(function(resolve, reject) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", blobURL); + xhr.send(); + xhr.onload = function() { + is(xhr.response, "123", "Response matches!"); + resolve(); + } + })).then(function() { + document.body.removeChild(iframe); + }).then(function() { + var xhr = new XMLHttpRequest(); + xhr.open("GET", blobURL); + try { + xhr.send(); + ok(false, "The URL should be done!"); + } catch(e) { + ok(true, "The URL should be done!"); + } + + SimpleTest.finish(); + }); +} + +var iframe = document.createElement('iframe'); +iframe.src = 'file_blobURL_expiring.html'; +document.body.appendChild(iframe); + +SimpleTest.waitForExplicitFinish(); + + </script> +</body> +</html> diff --git a/dom/base/test/test_blob_fragment_and_query.html b/dom/base/test/test_blob_fragment_and_query.html new file mode 100644 index 0000000000..bc454e69c9 --- /dev/null +++ b/dom/base/test/test_blob_fragment_and_query.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Blob URI with fragments</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <script> + +var blob = new Blob(['hello world']); +ok(blob, "We have a blob."); + +var tests = [ + { part: "", revoke: true }, + { part: "?aa", revoke: false }, + { part: "#bb", revoke: false }, + { part: "?cc#dd", revoke: false }, + { part: "#ee?ff", revoke: false } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var url = URL.createObjectURL(blob); + ok(url, "We have a URI"); + + var test = tests.shift(); + + URL.revokeObjectURL(url + test.part); + + var xhr = new XMLHttpRequest(); + xhr.open('GET', url + test.part); + + xhr.onload = function() { + is(xhr.responseText, 'hello world', 'URL: ' + url + test.part); + runTest(); + } + + try { + xhr.send(); + } catch(e) { + ok(test.revoke, "This should fail!"); + runTest(); + return; + } + ok(!test.revoke, "This should succeed!"); +} + +SimpleTest.waitForExplicitFinish(); +runTest(); + + </script> +</body> +</html> diff --git a/dom/base/test/test_blobconstructor.html b/dom/base/test/test_blobconstructor.html new file mode 100644 index 0000000000..1245d1e397 --- /dev/null +++ b/dom/base/test/test_blobconstructor.html @@ -0,0 +1,246 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=721569 +--> +<head> + <title>Test for Blob constructor (Bug 721569)</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="fileutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=721569">Mozilla Bug 721569</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript;version=1.7"> +"use strict"; +/** Test for Bug 721569 **/ +var blob = new Blob(); +ok(blob, "Blob should exist"); + +ok(blob.size !== undefined, "Blob should have a size property"); +ok(blob.type !== undefined, "Blob should have a type property"); +ok(blob.slice, "Blob should have a slice method"); + +blob = new Blob([], {type: null}); +ok(blob, "Blob should exist"); +is(blob.type, "null", "Blob type should be stringified"); + +blob = new Blob([], {type: undefined}); +ok(blob, "Blob should exist"); +is(blob.type, "", "Blob type should be treated as missing"); + +try { +blob = new Blob([]); +ok(true, "an empty blobParts argument should not throw"); +} catch(e) { +ok(false, "NOT REACHED"); +} + +try { +blob = new Blob(null); +ok(false, "NOT REACHED"); +} catch(e) { +ok(true, "a null blobParts member should throw"); +} + +try { +blob = new Blob([], null); +ok(true, "a null options member should not throw"); +} catch(e) { +ok(false, "NOT REACHED"); +} + +try { +blob = new Blob([], undefined); +ok(true, "an undefined options member should not throw"); +} catch(e) { +ok(false, "NOT REACHED"); +} + +try { +blob = new Blob([], false); +ok(false, "NOT REACHED"); +} catch(e) { +ok(true, "a boolean options member should throw"); +} + +try { +blob = new Blob([], 0); +ok(false, "NOT REACHED"); +} catch(e) { +ok(true, "a numeric options member should throw"); +} + +try { +blob = new Blob([], ""); +ok(false, "NOT REACHED"); +} catch(e) { +ok(true, "a string options member should throw"); +} + +/** Test for dictionary initialization order **/ +(function() { + var o = {}; + var p = {type: "text/plain", endings: "transparent"}; + var called = []; + function add_to_called(n) { + called.push(n); + return p[n]; + } + ["type", "endings"].forEach(function(n) { + Object.defineProperty(o, n, { get: add_to_called.bind(null, n) }); + }); + var b = new Blob([], o); + is(JSON.stringify(called), JSON.stringify(["endings", "type"]), "dictionary members should be get in lexicographical order"); +})(); + +let blob1 = new Blob(["squiggle"]); +ok(blob1 instanceof Blob, "Blob constructor should produce Blobs"); +ok(!(blob1 instanceof File), "Blob constructor should not produce Files"); +is(blob1.type, "", "Blob constructor with no options should return Blob with empty type"); +is(blob1.size, 8, "Blob constructor should return Blob with correct size"); + +let blob2 = new Blob(["steak"], {type: "content/type"}); +ok(blob2 instanceof Blob, "Blob constructor should produce Blobs"); +ok(!(blob2 instanceof File), "Blob constructor should not produce Files"); +is(blob2.type, "content/type", "Blob constructor with a type option should return Blob with the type"); +is(blob2.size, 5, "Blob constructor should return Blob with correct size"); + + +let aB = new ArrayBuffer(16); +var int8View = new Int8Array(aB); +for (var i = 0; i < 16; i++) { + int8View[i] = i+65; +} + +let testData = + [ + // Test 3 strings + [["foo", "bar", "baz"], {}, + [{start: 0, length: 9, contents: "foobarbaz"}, + {start: 0, length: 3, contents: "foo"}, + {start: 3, length:6, contents: "barbaz"}, + {start: 6, length: 3, contents: "baz"}, + {start: 6, length: 6, contents: "baz"}, + {start: 0, length: 9, contents: "foobarbaz"}, + {start: 0, length: 11, contents: "foobarbaz"}, + {start: 10, length: 5, contents: ""}]], + // Test string, Blob, string + [["foo", blob1, "baz"], {}, + [{start: 0, length: 3, contents: "foo"}, + {start: 3, length: 8, contents: "squiggle"}, + {start: 2, length: 2, contents: "os"}, + {start: 10, length: 2, contents: "eb"}]], + // Test blob, string, blob + [[blob1, "foo", blob1], {}, + [{start: 0, length: 8, contents: "squiggle"}, + {start: 7, length: 2, contents: "ef"}, + {start: 10, length: 2, contents: "os"}, + {start: 1, length: 3, contents: "qui"}, + {start: 12, length: 3, contents: "qui"}, + {start: 40, length: 20, contents: ""}]], + // Test blobs all the way down + [[blob2, blob1, blob2], {}, + [{start: 0, length: 5, contents: "steak"}, + {start: 5, length: 8, contents: "squiggle"}, + {start: 13, length: 5, contents: "steak"}, + {start: 1, length: 2, contents: "te"}, + {start: 6, length: 4, contents: "quig"}]], + // Test an array buffer + [[aB, blob1, "foo"], {}, + [{start: 0, length: 8, contents: "ABCDEFGH"}, + {start: 8, length:10, contents: "IJKLMNOPsq"}, + {start: 17, length: 3, contents: "qui"}, + {start: 4, length: 8, contents: "EFGHIJKL"}]], + // Test an ArrayBufferView + [[int8View, blob1, "foo"], {}, + [{start: 0, length: 8, contents: "ABCDEFGH"}, + {start: 8, length:10, contents: "IJKLMNOPsq"}, + {start: 17, length: 3, contents: "qui"}, + {start: 4, length: 8, contents: "EFGHIJKL"}]], + // Test a partial ArrayBufferView + [[new Uint8Array(aB, 3, 5), blob1, "foo"], {}, + [{start: 0, length: 8, contents: "DEFGHsqu"}, + {start: 8, length:10, contents: "igglefoo"}, + {start: 4, length: 8, contents: "Hsquiggl"}]], + // Test transparent line endings + [["foo\r\n", "bar\r", "baz\n"], { endings: "transparent" }, + [{start: 0, length: 5, contents: "foo\r\n"}, + {start: 5, length: 4, contents: "bar\r"}, + {start: 9, length: 4, contents: "baz\n"}]], + // Test transparent line endings when the second argument is omitted + [["foo\r\n", "bar\r", "baz\n"], undefined, + [{start: 0, length: 5, contents: "foo\r\n"}, + {start: 5, length: 4, contents: "bar\r"}, + {start: 9, length: 4, contents: "baz\n"}]], + // Test native line endings + [["foo\r\n", "bar\r", "baz\n"], { endings: "native" }, + navigator.platform.indexOf("Win") != -1 ? + [{start: 0, length: 5, contents: "foo\r\n"}, + {start: 5, length: 5, contents: "bar\r\n"}, + {start: 10, length: 5, contents: "baz\r\n"}] : + [{start: 0, length: 4, contents: "foo\n"}, + {start: 4, length: 4, contents: "bar\n"}, + {start: 8, length: 4, contents: "baz\n"}]], + // Test type coercion of a number + [[3, int8View, "foo"], {}, + [{start: 0, length: 8, contents: "3ABCDEFG"}, + {start: 8, length:10, contents: "HIJKLMNOPf"}, + {start: 17, length: 4, contents: "foo"}, + {start: 4, length: 8, contents: "DEFGHIJK"}]] + ]; + +let testCounter = 0; + +function doTest(data) { + testCounter++; + + var [blobs, options, tests] = data; + + function runTest(test) { + + let blob; + if (options !== undefined) { + blob = new Blob(blobs, options); + } else { + blob = new Blob(blobs); + } + ok(blob, "Test " + testCounter + " got blob"); + ok(blob instanceof Blob, "Test " + testCounter + " blob is a Blob"); + ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File"); + + let slice = blob.slice(test.start, test.start + test.length); + ok(slice, "Test " + testCounter + " got slice"); + ok(slice instanceof Blob, "Test " + testCounter + " slice is a Blob"); + ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File"); + is(slice.size, test.contents.length, + "Test " + testCounter + " slice is correct size"); + + testFile(slice, test.contents, "Test " + testCounter); + } + if (Array.isArray(tests)) { + tests.forEach(runTest); + } else { + try { + let blob = new Blob(blobs, options); + ok(false, "NOT REACHED"); + } catch (e) { + is(e.name, tests, "Blob constructor should throw " + tests); + } + } + SpecialPowers.gc(); +} + +SimpleTest.waitForExplicitFinish(); +testData.forEach(doTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1008126.html b/dom/base/test/test_bug1008126.html new file mode 100644 index 0000000000..cd196de09c --- /dev/null +++ b/dom/base/test/test_bug1008126.html @@ -0,0 +1,62 @@ +<!-- +2 Any copyright is dedicated to the Public Domain. +3 http://creativecommons.org/publicdomain/zero/1.0/ +4 --> +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1008126 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1008126</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1008126">Mozilla Bug 1008126</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript;version=1.7"> +function translateChrome(uriStr) { + const { Cc, Ci } = SpecialPowers; + let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry); + let uri = ios.newURI(uriStr, null, ios.newURI(document.baseURI, null, null)); + return chromeReg.convertChromeURL(uri).spec; +} + +function runTest() { + var worker = new Worker("file_bug1008126_worker.js"); + + worker.onmessage = function(event) { + if (event.data.type == 'finish') { + SimpleTest.finish(); + } else if (event.data.type == 'status') { + ok(event.data.status, event.data.msg); + } + }; + + worker.onerror = function(event) { + is(event.target, worker); + ok(false, "Worker had an error: " + event.filename + ":" + event.lineno + ":" + event.colno + ": " + event.message); + SimpleTest.finish(); + }; + + worker.postMessage(translateChrome("file_bug945152.jar")); +} + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + SpecialPowers.pushPrefEnv({"set": [["dom.mapped_arraybuffer.enabled", true]]}, function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTest); + }); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1016960.html b/dom/base/test/test_bug1016960.html new file mode 100644 index 0000000000..399542d102 --- /dev/null +++ b/dom/base/test/test_bug1016960.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1016960 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1016960</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1016960 **/ + + var chromeWindow = window.open("chrome://mochitests/content/chrome/dom/base/test/file_empty.html", "1016960", "chrome"); + ok(chromeWindow instanceof ChromeWindow, "A chrome window should return true for |instanceof ChromeWindow|."); + chromeWindow.close(); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1016960">Mozilla Bug 1016960</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1022229.html b/dom/base/test/test_bug1022229.html new file mode 100644 index 0000000000..356cfe085f --- /dev/null +++ b/dom/base/test/test_bug1022229.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1022229 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1022229</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for postMessage between sandboxed iframe and non-sandboxed window. + This test is particularly interesting on b2g where we're in a mozBrowser. + + We set the test up with an extra iframe so that we can easily run it in + an artificial mozbrowser for desktop builds. + **/ + SimpleTest.waitForExplicitFinish(); + function go() { + var ifr = document.createElement('iframe'); + + /* Uncomment this chunk to run in a mozBrowser. Make sure to uncomment the + chunk in iframe_main as well. */ + /* + SpecialPowers.Services.prefs.setBoolPref("dom.mozBrowserFramesEnabled", true); + SpecialPowers.Services.prefs.setBoolPref("network.disable.ipc.security", true); + SpecialPowers.Services.prefs.setBoolPref("dom.ipc.browser_frames.oop_by_default", false); + SpecialPowers.addPermission("browser", true, document); + SpecialPowers.wrap(ifr).mozbrowser = true; + */ + + ifr.setAttribute('src', 'iframe_main_bug1022229.html'); + document.body.appendChild(ifr); + } + + </script> +</head> +<body onload="go()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1022229">Mozilla Bug 1022229</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1025933.html b/dom/base/test/test_bug1025933.html new file mode 100644 index 0000000000..b48fbf3ef4 --- /dev/null +++ b/dom/base/test/test_bug1025933.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1025933 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1025933</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1025933 **/ + + SimpleTest.waitForExplicitFinish(); + + function test() { + var s = document.getElementById("host").createShadowRoot(); + s.innerHTML = '<div style="width:100px;height:100px;background:red"></div>'; + var el = s.firstElementChild; + is(el.clientWidth, 100); + is(el.clientHeight, 100); + SimpleTest.finish(); + } + + </script> +</head> +<body onload="test()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1025933">Mozilla Bug 1025933</a> +<p id="display"></p> +<div id="content"> + <div id="host"></div> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1037687.html b/dom/base/test/test_bug1037687.html new file mode 100644 index 0000000000..097a3d1e6e --- /dev/null +++ b/dom/base/test/test_bug1037687.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1037687 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1037687</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1037687 **/ + + SimpleTest.waitForExplicitFinish(); + + var host; + var sr; + var embed; + var object; + var iframe; + var resourceLoadCount = 0; + + function resourceLoaded(event) { + ++resourceLoadCount; + ok(true, event.target + " got " + event.load); + if (resourceLoadCount == 3) { + SimpleTest.finish(); + } + } + + function createResource(sr, type) { + var el = document.createElement(type); + var attrName = type == "object" ? "data" : "src"; + el.setAttribute(attrName, "file_mozfiledataurl_img.jpg"); + el.onload = resourceLoaded; + var info = document.createElement("div"); + info.textContent = type; + sr.appendChild(info); + sr.appendChild(el); + } + + function test() { + host = document.getElementById("host"); + sr = host.createShadowRoot(); + embed = createResource(sr, "embed"); + object = createResource(sr, "object"); + iframe = createResource(sr, "iframe"); + } + + </script> +</head> +<body onload="test()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1037687">Mozilla Bug 1037687</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<div id="host"></div> +</body> +</html> diff --git a/dom/base/test/test_bug1043106.html b/dom/base/test/test_bug1043106.html new file mode 100644 index 0000000000..a16c81378e --- /dev/null +++ b/dom/base/test/test_bug1043106.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1043106 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1043106</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1043106">Mozilla Bug 1043106</a> + <iframe id="iframe"></iframe> + <script type="application/javascript"> + +var storage; + +window.addEventListener("storage", function (event) { + ok(event.storageArea, storage, "The storageArea is correct"); + storage.removeItem("a"); + runTests(); +}, false); + +var tests = [ { key: 'localStorage', storage: localStorage }, + { key: 'sessionStorage', storage: sessionStorage } ]; +function runTests() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var t = tests.shift(); + storage = t.storage; + + var ifr = document.getElementById("iframe"); + ifr.src = "data:text/html,<script>" + t.key + ".setItem(\"a\",\"b\");</" + "script>"; +} + +SimpleTest.waitForExplicitFinish(); +runTests(); + </script> +</body> +</html> diff --git a/dom/base/test/test_bug1057176.html b/dom/base/test/test_bug1057176.html new file mode 100644 index 0000000000..e746180dd7 --- /dev/null +++ b/dom/base/test/test_bug1057176.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1057176 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1057176</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1057176 **/ + var doc = document.implementation.createDocument(null, null); + var elem = doc.createElementNS("http://www.w3.org/1999/xhtml", "input"); + elem.pattern = "abc"; + elem.value = "def"; + ok(!elem.validity.valid, '"def" should not match the pattern "abc"'); + elem.value = "abc"; + ok(elem.validity.valid, '"abc" should match the pattern "abc"'); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1057176">Mozilla Bug 1057176</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1060938.html b/dom/base/test/test_bug1060938.html new file mode 100644 index 0000000000..a93627e572 --- /dev/null +++ b/dom/base/test/test_bug1060938.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1060938 +--> + <head> + <meta charset="utf-8"> + <title> Test for Bug 1060938 </title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"> </script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"> </script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + </head> + <body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1060938"> Mozilla Bug 1060938 </a> + <p id="display"></p> + + <pre id="test"> + <script type="application/javascript"> + + /** Test for Bug 1060938 **/ + // test: Element.removeAttributeNode() + + parent = document.getElementsByTagName("p")[0]; + parent.setAttributeNS("www.test1.com", "ID", "Test1"); + parent.setAttributeNS("www.test2.com", "Class", "Test2"); + parent.setAttribute("id", "www.test3.com"); + parent.className = "www.test4.com"; + + allAttributes = parent.attributes; + + function removeAttr(iter){ + var removed_attribute = allAttributes[0]; + is(removed_attribute, parent.removeAttributeNode(removed_attribute), + "(" + iter + ")" + " Returned attribute and remove attribute should be same."); + } + + removeAttr(1); + removeAttr(2); + removeAttr(3); + removeAttr(4); + + </script> + </body> +</html> diff --git a/dom/base/test/test_bug1064481.html b/dom/base/test/test_bug1064481.html new file mode 100644 index 0000000000..e5a3cec266 --- /dev/null +++ b/dom/base/test/test_bug1064481.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1064481 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1064481</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1064481">Mozilla Bug 1064481</a> + <iframe id="iframe"></iframe> + <script type="application/javascript"> + +var a = new URLSearchParams(); + +a.set('foobar', 'a\nb'); +is(a.toString(), 'foobar=a%0Ab', "Bug fixed"); + + </script> +</body> +</html> diff --git a/dom/base/test/test_bug1070015.html b/dom/base/test/test_bug1070015.html new file mode 100644 index 0000000000..824d2bdf70 --- /dev/null +++ b/dom/base/test/test_bug1070015.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1070015 +--> +<head> + <title>Test for Bug 1070015</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1070015">Mozilla Bug 1070015</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="attrTest1" testAttr="testValue1"></div> +<div id="attrTest2" testAttr="testValue2"></div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 1070015 **/ + +function testRemoveAttribute() { + var attrTest1 = document.getElementById("attrTest1"); + var attr1 = attrTest1.getAttributeNode("testAttr"); + + var attrTest2 = document.getElementById("attrTest2"); + var attr2 = attrTest2.getAttributeNode("testAttr"); + + ok(attrTest1.hasAttribute("testAttr"), "First object should have attribute"); + ok(attrTest2.hasAttribute("testAttr"), "Second object should have attribute"); + + try { + attrTest1.removeAttributeNode(attr2); + ok(false, "Should throw when removing from the different element"); + } catch (e) { + ok(true, "Should throw when removing from the different element"); + } + + ok(attrTest1.hasAttribute("testAttr"), "Object should not remove attribute which not belongs to it"); + ok(attrTest2.hasAttribute("testAttr"), "Object should not be changed"); + + attrTest1.removeAttributeNode(attr1); + ok(!attrTest1.hasAttribute("testAttr"), "Object should remove its attribute"); +} +testRemoveAttribute(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1075702.html b/dom/base/test/test_bug1075702.html new file mode 100644 index 0000000000..ccee454df5 --- /dev/null +++ b/dom/base/test/test_bug1075702.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1075702 +--> +<head> + <meta charset="utf-8"> + <title> Test for Bug 1075702 </title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"> </script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"> </script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1075702"> Mozilla Bug 1075702 </a> +<p id="display"></p> + +<pre id="test"> +<script type="application/javascript"> + + /** Test for Bug 1075702 **/ + // test: Element.removeAttributeNode() + + var a1 = document.createAttribute("aa"); + a1.nodeValue = "lowercase"; + + var a2 = document.createAttributeNS("", "AA"); + a2.nodeValue = "UPPERCASE"; + + document.documentElement.setAttributeNode(a1); + document.documentElement.setAttributeNode(a2); + + is(document.documentElement.getAttributeNS("", "aa"), "lowercase", "Should be lowercase!"); + is(document.documentElement.getAttributeNS("", "AA"), "UPPERCASE", "Should be UPPERCASE!"); + + var a3 = document.createAttribute("AA"); + a3.nodeValue = "UPPERCASE AGAIN"; + document.documentElement.setAttributeNode(a3); + + is(document.documentElement.getAttributeNS("", "aa"), "UPPERCASE AGAIN", + "Should be UPPERCASE AGAIN!"); + is(document.documentElement.getAttributeNS("", "AA"), "UPPERCASE", "Should be UPPERCASE!"); + + var removedNodeAccordingToEvent; + + function mutationHandler(aEvent) { + removedNodeAccordingToEvent = aEvent.relatedNode; + } + + var test1 = document.createElement("div"); + test1.setAttribute("x", "y"); + removedNodeAccordingToEvent = null; + + function testremoveNamedItemNS() { + test1.addEventListener("DOMAttrModified", mutationHandler, true); + var removedNodeAccordingToRemoveNamedItemNS = test1.attributes.removeNamedItemNS(null, "x"); + test1.removeEventListener("DOMAttrModified", mutationHandler, true); + is(removedNodeAccordingToEvent, removedNodeAccordingToRemoveNamedItemNS, "Node removed according to event is not same as node removed by removeNamedItemNS."); + } + + testremoveNamedItemNS(); + + var test2 = document.createElement("div"); + test2.setAttribute("x", "y"); + removedNodeAccordingToEvent = null; + + function testremoveNamedItem() { + test2.addEventListener("DOMAttrModified", mutationHandler, true); + var removedNodeAccordingToRemoveNamedItem = test2.attributes.removeNamedItem("x"); + test2.removeEventListener("DOMAttrModified", mutationHandler, true); + is(removedNodeAccordingToEvent, removedNodeAccordingToRemoveNamedItem, "Node removed according to event is not same as node removed by removeNamedItem."); + } + + testremoveNamedItem(); + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug1081686.html b/dom/base/test/test_bug1081686.html new file mode 100644 index 0000000000..bd00c3f64f --- /dev/null +++ b/dom/base/test/test_bug1081686.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>bug 1081686</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="testWebSocket()"> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var ws; + +function forcegc() +{ + SpecialPowers.forceGC(); + SpecialPowers.gc(); + setTimeout(function() + { + SpecialPowers.gc(); + }, 0); +} + +function testWebSocket () { + ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/file_websocket_hello"); + ws.onopen = function(e) { + ws.send("data"); + } + ws.onclose = function(e) { + forcegc(); + setTimeout(function() { + is(ws.readyState, 3, 'WebSocket is closed'); + is(ws.bufferedAmount, 0, 'WebSocket.bufferedAmount should be empty.'); + is(ws.binaryType, 'blob', 'WebSocket.binaryType is blob'); + ws.binaryType = 'arraybuffer'; + is(ws.binaryType, 'arraybuffer', 'WebSocket.binaryType is arraybuffer'); + is(ws.url, 'ws://mochi.test:8888/tests/dom/base/test/file_websocket_hello', 'WebSocket.url is correct'); + ws.close(); + ws.send('foobar'); + SimpleTest.finish(); + }, 1000); + } + + ws.onerror = function(e) { + ok(false, "onerror called!"); + SimpleTest.finish(); + } + ws.onmessage = function(e) { + is(e.data, "Hello world!", "Wrong data"); + ws.close(); + } +} + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +</script> +</pre> +<div> + + +</div> + + +</body> +</html> diff --git a/dom/base/test/test_bug1091883.html b/dom/base/test/test_bug1091883.html new file mode 100644 index 0000000000..c7ed948d9d --- /dev/null +++ b/dom/base/test/test_bug1091883.html @@ -0,0 +1,89 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1091883 +--> +<head> + <meta charset="utf-8"> + <meta name="referrer" content="origin-when-cross-origin"> + <title>Test for Bug 1091883</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1091883">Mozilla Bug 1091883</a></p> +<h2>Results</h2> +<pre id="results">Running...</pre> + +<script> +SimpleTest.waitForExplicitFinish(); + +var origins = [ + "http://mochi.test:8888", "http://example.com", "http://example.org"]; +var numOrigins = origins.length; + +// For each combination of (frame, subframe, target) origins, this test +// includes a "frame" that includes a "subframe"; and then this test +// navigates this "subframe" to the "target". Both the referrer and +// the triggering principal are this test, i.e., "http://mochi.test:8888". +// Since the referrer policy is origin-when-cross-origin, we expect to have +// a full referrer if and only if the target is also "http://mochi.test:8888"; +// in all other cases, the referrer needs to be the origin alone. +var numTests = numOrigins * numOrigins * numOrigins; + +// Helpers to look up the approriate origins for a given test number. +function getFrameOrigin(i) { + return origins[(i / (numOrigins * numOrigins)) | 0]; +} +function getSubframeOrigin(i) { + return origins[((i / numOrigins) | 0) % 3]; +} +function getTargetOrigin(i) { + return origins[i % 3]; +} + +// Create the frames, and tell them which subframes to load. +for (var i = 0; i < numTests; i++) { + var frame = document.createElement("iframe"); + frame.src = getFrameOrigin(i) + + "/tests/dom/base/test/file_bug1091883_frame.html#" + + getSubframeOrigin(i); + document.body.appendChild(frame); +} + +// Navigate all subframes to the target. +window.onload = function() { + for (var i = 0; i < numTests; i++) { + frames[i].frames[0].location = getTargetOrigin(i) + + "/tests/dom/base/test/file_bug1091883_target.html#" + i; + } +}; + +// Check referrer messages from the target. +var results = {}; +function makeResultsKey(i) { + return i + ": " + getFrameOrigin(i) + " | " + getSubframeOrigin(i) + " -> " + + getTargetOrigin(i); +} +window.addEventListener("message", function(event) { + var out = event.data.split(" "); + var referrer = out[0]; + var testRun = +out[1]; + results[makeResultsKey(testRun)] = referrer; + if (event.origin == "http://mochi.test:8888") { + is(referrer, + "http://mochi.test:8888/tests/dom/base/test/test_bug1091883.html", + "must be full referrer"); + } else { + is(referrer, "http://mochi.test:8888/", "must be origin referrer"); + } + if (Object.keys(results).length == numTests) { + document.getElementById("results").textContent = + JSON.stringify(results, null, 4); + SimpleTest.finish(); + } +}); +</script> + +</body> +</html> diff --git a/dom/base/test/test_bug1101364.html b/dom/base/test/test_bug1101364.html new file mode 100644 index 0000000000..dfcb26a49c --- /dev/null +++ b/dom/base/test/test_bug1101364.html @@ -0,0 +1,73 @@ +<!DOCTYPE> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1101364 +--> +<head> +<title>Test for Bug 1101364</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style> + #test1 { + -moz-user-select: none; + } + + #testDiv, #test2 { + -moz-user-select: text; + } + </style> +</head> +<body id='body'> + +<iframe id="test1" src="data:text/html,<h1 id='test1' style='-moz-user-select:none'>Header</h1><div id='testDiv'>test1</div>"></iframe> +<iframe id="test2" src="data:text/html,<div contenteditable id='test2'>AAA<span id='test2Inner'>BBB</span></div>"></iframe> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function test() +{ + var iframe1 = document.getElementById('test1'); + iframe1.focus(); + var Ci = SpecialPowers.Ci; + var webnav = SpecialPowers.wrap(iframe1.contentWindow).QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + var docShell = webnav.QueryInterface(Ci.nsIDocShell); + + // test1 + docShell.doCommand("cmd_selectAll"); + var withoutContenteditable = snapshotWindow(iframe1.contentWindow); + + iframe1.contentDocument.getElementById('testDiv').setAttribute('contentEditable', true); + docShell.doCommand("cmd_selectAll"); + var withContenteditable = snapshotWindow(iframe1.contentWindow); + dump(withoutContenteditable.toDataURL()); + dump(withContenteditable.toDataURL()); + + ok(compareSnapshots(withoutContenteditable, withContenteditable, true)[0], 'Select all should look identical'); + + // test2 + var iframe2 = document.getElementById('test2'); + iframe2.focus(); + var webnav = SpecialPowers.wrap(iframe2.contentWindow).QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + var docShell = webnav.QueryInterface(Ci.nsIDocShell); + var test2Inner = iframe2.contentDocument.getElementById('test2Inner'); + test2Inner.style.MozUserSelect = 'text'; + docShell.doCommand("cmd_selectAll"); + var withoutUserSelect = snapshotWindow(iframe2.contentWindow); + + test2Inner.style.MozUserSelect = 'none'; + docShell.doCommand("cmd_selectAll"); + var withUserSelect = snapshotWindow(iframe2.contentWindow); + ok(compareSnapshots(withoutUserSelect, withUserSelect, true)[0], 'Editable fields should ignore user select style'); + + SimpleTest.finish(); +} +window.onload = function() { setTimeout(test, 0); }; +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1118689.html b/dom/base/test/test_bug1118689.html new file mode 100644 index 0000000000..46639d0871 --- /dev/null +++ b/dom/base/test/test_bug1118689.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1118689 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1118689</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1118689 **/ + SimpleTest.requestFlakyTimeout("Just need some random timeout."); + + function test1() { + // test 1, check that error handling in data documents is still the same + // as it has been for ages. + var d = document.implementation.createHTMLDocument(); + d.body.innerHTML = "<img onerror='ok(false, \"EventHandler shouldn't be called in data document\")'>"; + d.body.firstChild.addEventListener("error", + function() { + ok(true, "EventListener should be called in data document"); + test2(); + }); + d.body.firstChild.addEventListener("load", + function() { + ok(false, "Images in data document shouldn't be loaded"); + }); + d.body.firstChild.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP"; + } + + function test2() { + // test 2, check that load event doesn't keep up being dispatched if + // window has been closed. + var win = window.open('data:text/html,<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP" onload="this.src = this.src">', + "", "height=100,width=100"); + setTimeout(function() { + win.close(); + SimpleTest.finish(); + }, 2500); + } + + SimpleTest.waitForExplicitFinish(); + + </script> +</head> +<body onload="test1();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1118689">Mozilla Bug 1118689</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1126851.html b/dom/base/test/test_bug1126851.html new file mode 100644 index 0000000000..d6d7bf4a22 --- /dev/null +++ b/dom/base/test/test_bug1126851.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1126851 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1126851</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1126851 **/ + + SimpleTest.waitForExplicitFinish(); + + function runTest() { + win = window.open("about:blank", ""); + win.onload = function() { + win.onunload = function() { + ok(true, "got unload"); + win.close(); + SimpleTest.finish(); + } + win.onresize = function() { + win.location.reload(); + } + win.document.dispatchEvent(new win.Event("resize", { bubbles: true })); + } + } + + + </script> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1126851">Mozilla Bug 1126851</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug116083.html b/dom/base/test/test_bug116083.html new file mode 100644 index 0000000000..0d37242f82 --- /dev/null +++ b/dom/base/test/test_bug116083.html @@ -0,0 +1,103 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=116083 +--> +<head> + <title>Test for Bug 116083</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=116083">Mozilla Bug 116083</a> +<div id="content"> +<div style="white-space: pre">foo bar</div> +<div style="white-space: pre-wrap">foo bar</div> +<div style="white-space: pre-line">foo bar</div> +<div style="white-space: -moz-pre-space">foo bar</div> +<div data-result="bar baz"><span style="white-space: pre">bar </span>baz</div> +<div data-result="bar baz"><span style="white-space: pre-wrap">bar </span>baz</div> +<div data-result="bar baz"><span style="white-space: pre-line">bar </span>baz</div> +<div data-result="bar baz"><span style="white-space: -moz-pre-space">bar </span>baz</div> +<div data-result="foo bar ! baz" style="white-space: pre"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar ! baz" style="white-space: pre" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar ! baz" style="white-space: pre-wrap"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar ! baz" style="white-space: pre-wrap" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar ! baz" style="white-space: pre-line"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar ! baz" style="white-space: pre-line" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar ! baz" style="white-space: -moz-pre-space"><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar ! baz" style="white-space: -moz-pre-space" contenteditable><div>foo </div><div> bar</div><div><br></div><div>!</div><div><br><br></div><div>baz</div></div> +<div data-result="foo bar baz qux"><div>foo<br></div><span>bar<br>baz<br>qux</span></div> +<div data-result="foo bar baz qux" contenteditable><div>foo<br></div><span>bar<br>baz<br>qux</span></div> +<div data-result="foo "><div>foo</div><span><br></span></div> +<div data-result="foo " contenteditable><div>foo</div><span><br></span></div> +<div data-result="foo bar"><div>foo</div><span><br></span><div>bar</div></div> +<div data-result="foo bar" contenteditable><div>foo</div><span><br></span><div>bar</div></div> +<div data-result="foo bar "><div>foo</div><span>bar<br></span></div> +<div data-result="foo bar" contenteditable><div>foo</div><span>bar<br></span></div> +<div data-result="foo bar baz"><div>foo</div><span>bar<br></span><div>baz</div></div> +<div data-result="foo bar baz" contenteditable><div>foo</div><span>bar<br></span><div>baz</div></div> +<div data-result=" foo"><div><br><br><div>foo</div></div></div> +<div data-result=" foo" contenteditable><div><br><br><div>foo</div></div></div> +<div data-result="foo bar"><div>foo<br>bar</div></div> +<div data-result="foo bar" contenteditable><div>foo<br>bar</div></div> +<div data-result="foo bar "><div>foo<br>bar<br></div></div> +<div data-result="foo bar" contenteditable><div>foo<br>bar<br></div></div> +<div data-result=" foo bar ">foo bar</div> +</div> +<script type="application/javascript"> + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +function hasExpectedFlavors() { + var cb = Cc["@mozilla.org/widget/clipboard;1"]. + getService(Ci.nsIClipboard); + + ok(cb.hasDataMatchingFlavors(["text/unicode"], 1, cb.kGlobalClipboard), + "The clipboard has text/unicode"); + + // Android only supports plain text + if (navigator.appVersion.indexOf("Android") == -1) { + ok(cb.hasDataMatchingFlavors(["text/html"], 1, cb.kGlobalClipboard), + "The clipboard has text/html"); + } + + if (navigator.appVersion.indexOf("Win") >= 0) { + ok(cb.hasDataMatchingFlavors(["application/x-moz-nativehtml"], 1, cb.kGlobalClipboard), + "The clipboard has application/x-moz-nativehtml"); + } +} + +function nextTest() { + var div = document.querySelector("#content>div"); + if (!div) { + SimpleTest.finish(); + return; + } + getSelection().selectAllChildren(div); + var expected = div.hasAttribute("data-result") ? + div.getAttribute("data-result") : + div.textContent; + SimpleTest.waitForClipboard(expected, function() { + synthesizeKey("C", {accelKey: true}); + }, function() { + ok(true, div.getAttribute("style") + " passed"); + hasExpectedFlavors(); + div.parentNode.removeChild(div); + nextTest(); + }, function() { + ok(false, "failed to copy the expected content to the clipboard"); + SimpleTest.finish(); + }); +} + +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(function() { + SpecialPowers.pushPrefEnv({"set": [["clipboard.plainTextOnly", false]]}, nextTest); +}); + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug1163743.html b/dom/base/test/test_bug1163743.html new file mode 100644 index 0000000000..69d1c8c33f --- /dev/null +++ b/dom/base/test/test_bug1163743.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +This checks if the origin-when-crossorigin policy works. +https://bugzilla.mozilla.org/show_bug.cgi?id=1163743 +--> + +<head> + <meta charset="utf-8"> + <title>Test policies for Bug 1163743</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="referrerHelper.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * testing legacy support for origin-when-crossorigin (1163743) + */ +var tests = (function() { + var iframe = document.getElementById("testframe"); + const sjs = "/tests/dom/base/test/bug704320.sjs?action=generate-policy-test"; + + // origin when crossorigin (trimming whitespace) + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape(' origin-when-crossorigin'); + yield checkIndividualResults("origin-when-cross-origin", ["origin", "full"]); + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> + diff --git a/dom/base/test/test_bug1165501.html b/dom/base/test/test_bug1165501.html new file mode 100644 index 0000000000..fe932d4ea8 --- /dev/null +++ b/dom/base/test/test_bug1165501.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +Spot test to see if newer meta-referrer policy is used +https://bugzilla.mozilla.org/show_bug.cgi?id=1165501 +--> + +<head> + <meta charset="utf-8"> + <title>Test policies for Bug 1165501</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="referrerHelper.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * testing if policy is overwritten if there are two meta statements (1165501) + * XXX: would be nice to test this with CSP and meta as well + */ +var tests = (function() { + var iframe = document.getElementById("testframe"); + const sjs = "/tests/dom/base/test/bug704320.sjs?action=generate-policy-test"; + + // setting first unsafe-url and then origin - origin shall prevail + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape('origin')+ "&wrongPolicy=" + escape('unsafe-url'); + yield checkIndividualResults("unsafe-url then origin", ["origin"]); + + // setting first no-referrer and then default - default shall prevail + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape('default')+ "&wrongPolicy=" + escape('no-referrer'); + yield checkIndividualResults("no-referrer then default", ["full"]); + + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> + diff --git a/dom/base/test/test_bug1187157.html b/dom/base/test/test_bug1187157.html new file mode 100644 index 0000000000..37942f0051 --- /dev/null +++ b/dom/base/test/test_bug1187157.html @@ -0,0 +1,23 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789315 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 789315</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=789315">Mozilla Bug 789315</a> +<form id="a"><input name="b" type="file"/></form> + +<script type="text/javascript"> + var obj = new FormData(document.getElementById('a')).get('b'); + is(obj, "", "We want an empty string."); + +</script> + +</body> +</html> diff --git a/dom/base/test/test_bug1198095.html b/dom/base/test/test_bug1198095.html new file mode 100644 index 0000000000..cebf568884 --- /dev/null +++ b/dom/base/test/test_bug1198095.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<head> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1198095 +--> + <title>Test for Bug 1198095</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1198095">Mozilla Bug 1198095</a> + +<pre id="test"> +<script class="testbody" type="text/javascript;version=1.7"> + +var fileData1 = '1234567890'; +var fileData2 = '43210'; +var r, firstBlob; + +var openerURL = SimpleTest.getTestFileURL("file_bug1198095.js"); + +var opener = SpecialPowers.loadChromeScript(openerURL); +opener.addMessageListener("file.opened", onFileOpened); +opener.addMessageListener("file.modified", onFileModified); +opener.sendAsyncMessage("file.open", fileData1); + +function onLoadEnd1(e) { + e.target.removeEventListener('loadend', onLoadEnd1); + + is(e.target, r, "Target and r are ok"); + ok(e.target.readyState, FileReader.DONE, "The file has been read."); + ok(e.target.result instanceof ArrayBuffer, "The result is an ArrayBuffer"); + + var view = new Uint8Array(e.target.result); + is(view.length, fileData1.length, "File data length matches"); + for (var i = 0; i < fileData1.length; ++i) { + is(String.fromCharCode(view[i]), fileData1[i], "Byte matches"); + } + + opener.sendAsyncMessage("file.modify", fileData2); +} + +function onError1(e) { + ok(false, "This method should not be called - error1!"); +} + +function onError2(e) { + e.target.removeEventListener('error', onError2); + SimpleTest.finish(); +} + +function onFileOpened(blob) { + firstBlob = blob; + r = new FileReader(); + r.addEventListener("loadend", onLoadEnd1); + r.addEventListener("error", onError1); + r.readAsArrayBuffer(firstBlob); +} + +function onFileModified(blob) { + r.removeEventListener('error', onError1); + r.addEventListener("error", onError2); + r.readAsArrayBuffer(firstBlob); +} + +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> </html> diff --git a/dom/base/test/test_bug1238440.html b/dom/base/test/test_bug1238440.html new file mode 100644 index 0000000000..27cd2c0cd8 --- /dev/null +++ b/dom/base/test/test_bug1238440.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test - bug 1238440</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <input type="file" id="file" /> + <script type="application/javascript"> + +var script; + +function step_createScript() { + info("Creating script..."); + var url = SimpleTest.getTestFileURL("script_bug1238440.js"); + script = SpecialPowers.loadChromeScript(url); + next(); +} + +function step_destroyScript() { + info("Destroying script..."); + script.destroy(); + next(); +} + + +function step_createFile() { + info("Creating file..."); + + function onOpened(message) { + var fileList = document.getElementById('file'); + SpecialPowers.wrap(fileList).mozSetFileArray([message.file]); + ok(!!message.file, "File created and set"); + next(); + } + + script.addMessageListener("file.opened", onOpened); + script.sendAsyncMessage("file.open"); +} + +function step_changeFile() { + info("Changing file..."); + script.addMessageListener("file.changed", next); + script.sendAsyncMessage("file.change"); +} + +function step_fileReader(status) { + var fr = new FileReader(); + fr.onload = function() { + is(status, true, "onload called!"); + next(); + } + + fr.onerror = function(e) { + e.preventDefault(); + is(status, false, "onerror called!"); + next(); + } + + fr.readAsArrayBuffer(document.getElementById("file").files[0]); +} + +var steps = [ + step_createScript, + step_createFile, + function() { step_fileReader(true); }, + step_changeFile, + function() { step_fileReader(false); }, + step_destroyScript, +]; + +function next() { + if (!steps.length) { + SimpleTest.finish(); + return; + } + + var step = steps.shift(); + step(); +} + +SimpleTest.waitForExplicitFinish(); +next(); + </script> +</body> +</html> diff --git a/dom/base/test/test_bug1250148.html b/dom/base/test/test_bug1250148.html new file mode 100644 index 0000000000..1584360442 --- /dev/null +++ b/dom/base/test/test_bug1250148.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=1250148 + --> + <head> + <meta charset="utf-8"> + <title>Test for Bug 1250148 - FormData and HTML submission compatibility</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + </head> + <body> + <form id="form" enctype="multipart/form-data"><input type="file" name="test" /></form> + <script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var f = document.getElementById('form'); +var fd = new FormData(f); +is(fd.get("test"), "", "We want an empty string."); + +var getAll = fd.getAll("test"); +ok(Array.isArray(getAll), "We want an array with 1 empty string."); +is(getAll.length, 1, "We want an array with 1 empty string."); +is(getAll[0], "", "We want an array with 1 empty string."); + +var xhr = new XMLHttpRequest(); +xhr.open("POST", "file_bug1250148.sjs", true); +xhr.onload = function() { + var obj = JSON.parse(xhr.responseText); + + ok(Array.isArray(obj), "XHR response is an array."); + is(obj.length, 1, "XHR response array contains 1 result."); + + ok("headers" in obj[0], "XHR response has an header value"); + + ok("Content-Disposition" in obj[0].headers, "XHR response.headers array has a Content-Desposition value"); + is(obj[0].headers["Content-Disposition"], "form-data; name=\"test\"; filename=\"\"", "Correct Content-Disposition"); + + ok("Content-Type" in obj[0].headers, "XHR response.headers array has a Content-Type value"); + is(obj[0].headers["Content-Type"], "application/octet-stream", "Correct Content-Type"); + + ok("body" in obj[0], "XHR response has a body value"); + is(obj[0].body, "", "Correct body value"); + + SimpleTest.finish(); +} +xhr.send(fd); + + </script> + </body> +</html> diff --git a/dom/base/test/test_bug1259588.html b/dom/base/test/test_bug1259588.html new file mode 100644 index 0000000000..40a272f905 --- /dev/null +++ b/dom/base/test/test_bug1259588.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for Bug 1259588</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> +test(function() { + assert_throws(new TypeError, function() { + new File(""); + }, "new File(\"\") should throw TypeError exception"); +}, "Test new File(\"\") should throw exception"); +</script> diff --git a/dom/base/test/test_bug1263696.html b/dom/base/test/test_bug1263696.html new file mode 100644 index 0000000000..289a26ba4f --- /dev/null +++ b/dom/base/test/test_bug1263696.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<html> + <head> + <meta><charset="utf-8"/> + <title>Test Embed/Object Node Conflicts</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="plugin-utils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + var index = 0; + function startTest() { + is(index, 12, "Should have loaded all passing frames."); + SimpleTest.finish(); + } + </script> + </head> + <body onload="startTest()"> + <object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"> + <embed type="text/html" src="file_bug1263696_frame_fail.html" /> + </object> + <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test"> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + </object> + <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test"> + <div></div> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + </object> + <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test"> + <div> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + </div> + </object> + <object style="width: 100px; height: 100px" data="data:application/x-does-not-exist,test"> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + <object data="file_bug1263696_frame_pass.html"> + <embed type="text/html" src="file_bug1263696_frame_fail.html" /> + </object> + <object data="data:application/x-does-not-exist,test"> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + </object> + </object> + <div> + <object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + </div> + <div> + <embed type="text/html" src="file_bug1263696_frame_pass.html" /> + <object data="file_bug1263696_frame_pass.html" style="width: 100px; height: 100px"></object> + </div> + </body> +</html> diff --git a/dom/base/test/test_bug1268962.html b/dom/base/test/test_bug1268962.html new file mode 100644 index 0000000000..c346d4374d --- /dev/null +++ b/dom/base/test/test_bug1268962.html @@ -0,0 +1,105 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1268962 +--> +<head> + <title>Test for Bug 1268962</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1268962">Mozilla Bug 1268962</a> +<p id="display"></p> +<div id="content" style="display: none"></div> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 1268962 **/ + +function testPrefetchEvent(url, crossorigin, expectLoad) { + return new Promise((resolve) => { + var link = document.createElement("LINK"); + link.setAttribute("rel", "prefetch"); + link.setAttribute("href", url); + if (crossorigin) { + link.setAttribute("crossorigin", ""); + } + + link.addEventListener("load", () => { + ok(expectLoad, "not expecting load event for " + url); + link.remove(); + resolve(); + }); + link.addEventListener("error", () => { + ok(!expectLoad, "not expecting error event for " + url); + link.remove(); + resolve(); + }); + document.head.appendChild(link); + }); +} + +function testCancelPrefetchNotCrash(url) { + var ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]. + getService(SpecialPowers.Ci.nsIIOService); + var prefetch = SpecialPowers.Cc["@mozilla.org/prefetch-service;1"]. + getService(SpecialPowers.Ci.nsIPrefetchService); + + var link = document.createElement("LINK"); + link.setAttribute("rel", "prefetch"); + link.setAttribute("href", url); + document.head.appendChild(link); + + // Not actually verifying any value, just to ensure cancelPrefetch + // won't cause crash. + prefetch.cancelPrefetchURI(ios.newURI(url, null, null), link); +} + +const SJS_PATH = window.location.pathname.replace(/[^/]+$/, "file_bug1268962.sjs"); +const SAME_ORIGIN = "http://mochi.test:8888" + SJS_PATH; +const CROSS_ORIGIN = "http://example.com" + SJS_PATH; + +SimpleTest.waitForExplicitFinish(); + +new Promise(resolve => + SpecialPowers.pushPrefEnv({"set": [["network.prefetch-next.aggressive", true]]}, resolve)) + +// test same origin +.then(() => testPrefetchEvent(SAME_ORIGIN + "?statusCode=200&cacheControl=no-cache", false, false)) +.then(() => testPrefetchEvent(SAME_ORIGIN + "?statusCode=404&cacheControl=no-cache", false, false)) +.then(() => testPrefetchEvent(SAME_ORIGIN + "?statusCode=200&cacheControl=max-age%3D120", false, true)) +.then(() => testPrefetchEvent(SAME_ORIGIN + "?statusCode=404&cacheControl=max-age%3D120", false, false)) + +// test cross origin without CORS +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=200&cacheControl=no-cache", false, true)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=404&cacheControl=no-cache", false, true)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=200&cacheControl=max-age%3D120", false, true)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=404&cacheControl=max-age%3D120", false, true)) + +// test cross origin by redirection without CORS +.then(() => testPrefetchEvent(SAME_ORIGIN + "?redirect=crossorigin&statusCode=200&cacheControl=no-cache", false, true)) +.then(() => testPrefetchEvent(SAME_ORIGIN + "?redirect=crossorigin&statusCode=404&cacheControl=no-cache", false, true)) +.then(() => testPrefetchEvent(SAME_ORIGIN + "?redirect=crossorigin&statusCode=200&cacheControl=max-age%3D120", false, true)) +.then(() => testPrefetchEvent(SAME_ORIGIN + "?redirect=crossorigin&statusCode=404&cacheControl=max-age%3D120", false, true)) + +// test cross origin with CORS request but no CORS response +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=200&cacheControl=no-cache", true, true)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=404&cacheControl=no-cache", true, true)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=200&cacheControl=max-age%3D120", true, true)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=404&cacheControl=max-age%3D120", true, true)) + +// test cross origin with CORS request and CORS response +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=200&cacheControl=no-cache&allowOrigin=*", true, false)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=404&cacheControl=no-cache&allowOrigin=*", true, false)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=200&cacheControl=max-age%3D120&allowOrigin=*", true, true)) +.then(() => testPrefetchEvent(CROSS_ORIGIN + "?statusCode=404&cacheControl=max-age%3D120&allowOrigin=*", true, false)) + +// test the crash issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1294159 +.then(() => testCancelPrefetchNotCrash(SAME_ORIGIN + "?statusCode=200&cacheControl=max-age%3D120")) + +.catch((err) => ok(false, "promise rejected: " + err)) +.then(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug1274806.html b/dom/base/test/test_bug1274806.html new file mode 100644 index 0000000000..e49fbf628c --- /dev/null +++ b/dom/base/test/test_bug1274806.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1274806 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1274806</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + SimpleTest.waitForExplicitFinish(); + + /** Test for Bug 1274806 **/ + function test() { + window.testWindow = window.open("file_bug1274806.html", "", ""); + }; + + </script> +</head> +<body onload="setTimeout(test, 0);"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1274806">Mozilla Bug 1274806</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1281963.html b/dom/base/test/test_bug1281963.html new file mode 100644 index 0000000000..013a038643 --- /dev/null +++ b/dom/base/test/test_bug1281963.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/1281963 +--> +<head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Test for Bug 1281963</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content"></div> + +<script class="testbody" type="application/javascript;version=1.7"> + +// __setPref(key, value)__. +// Set a pref value asynchronously, returning a promise that resolves +// when it succeeds. +let setPref = function* (key, value) { + return new Promise(function(resolve, reject) { + SpecialPowers.pushPrefEnv({"set": [[key, value]]}, resolve); + }); +}; + +// Run a test to see that we don't expose the supported mimeTypes +// or installed plugins when "privacy.resistFingerprinting" is active. +add_task(function* () { + let exampleMimeType = undefined, + examplePlugin = undefined; + // Disable fingerprinting resistance. + yield setPref("privacy.resistFingerprinting", false); + // Depending on the testing platform, we may have at least + // one mimeType and plugin available. + exampleMimeType = navigator.mimeTypes[0]; + examplePlugin = navigator.plugins[0]; + + // First check that we can retrieve mimeType or plugin by name and that + // the array length is nonzero. + if (exampleMimeType) { + isnot(navigator.mimeTypes[exampleMimeType.type], undefined, "Should reveal mime type"); + isnot(navigator.mimeTypes.length, 0, "navigator.mimeTypes.length should be nonzero"); + } + if (examplePlugin) { + isnot(navigator.plugins[examplePlugin.name], undefined, "Should reveal plugin"); + isnot(navigator.plugins.length, 0, "navigator.plugins.length should be nonzero"); + } + + // Now test with fingerprinting resistance enabled + yield setPref("privacy.resistFingerprinting", true); + if (exampleMimeType) { + is(navigator.mimeTypes[exampleMimeType.type], undefined, "Don't reveal mime type"); + } + is(navigator.mimeTypes[0], undefined, "Don't reveal mime type"); + is(navigator.mimeTypes.length, 0, "navigator.mimeTypes.length should be 0"); + if (examplePlugin) { + is(navigator.plugins[examplePlugin.name], undefined, "Don't reveal plugin"); + } + is(navigator.plugins[0], undefined, "Don't reveal plugin"); + is(navigator.plugins.length, 0, "navigator.plugins.length should be 0"); +}); + +</script> + +</body> +</html> diff --git a/dom/base/test/test_bug1295852.html b/dom/base/test/test_bug1295852.html new file mode 100644 index 0000000000..ca73549c72 --- /dev/null +++ b/dom/base/test/test_bug1295852.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Bug 1295852</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +<body> +<script> + +var names = [ + "span", "_moz_generated_content_before", "_moz_generated_content_after" +]; + +if (SpecialPowers.getBoolPref("dom.animations-api.core.enabled")) { + names.forEach(name => { + var element = document.createElement(name); + element.animate({ "color": ["red", "blue"] }, { duration: 1000 }); + is(element.getAnimations().length, 1); + }); +} else { + ok("Test requires Web Animations, which is disabled."); +} + +</script> diff --git a/dom/base/test/test_bug1307730.html b/dom/base/test/test_bug1307730.html new file mode 100644 index 0000000000..54ba8ac999 --- /dev/null +++ b/dom/base/test/test_bug1307730.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1307730 +--> +<head> + <title>Test for Bug 1307730</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1307730">Mozilla Bug 1307730</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +const Cu = SpecialPowers.Cu; + +function runTest() { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "https://example.com", false); + try { + xhr.send(); + } catch (e) { + return e.name; + } + return 'XHR succeeded'; +} + +function evalInSandbox(sandbox, func) { + return SpecialPowers.unwrap(Cu.evalInSandbox(`(${func.toString()})()`, sandbox)); +} + +let sandbox = Cu.Sandbox([window, "https://example.org"], + {wantGlobalProperties: ['XMLHttpRequest']}); +is(evalInSandbox(sandbox, runTest), 'NetworkError', + "Shouldn't be able to make a CORS request with an expanded principal"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug1308069.html b/dom/base/test/test_bug1308069.html new file mode 100644 index 0000000000..2775ff1b7e --- /dev/null +++ b/dom/base/test/test_bug1308069.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1308069 +--> +<head> +<title>Bug 1308069</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1308069">Mozilla Bug 1308069</a> +<script class="testbody" type="text/javascript"> + +function testClearPendingErrorEvent() { + return new Promise(function(aResolve, aReject) { + var hasErrorEvent = false; + var imgTarget = new Image(); + + var imgForChangingTargetSrc = new Image(); + // Queue an error event for changing imgTarget's src. + imgForChangingTargetSrc.src = ''; + imgForChangingTargetSrc.onerror = function() { + // This clears imgTarget's pending error event. + imgTarget.src = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96"><path d="M10,10L32,90L90,32z" fill="lightgreen"/></svg>'; + + // Queue an error event for checking and resolving promise. + var imgForCheckingAndResolvingPromise = new Image(); + imgForCheckingAndResolvingPromise.src = ''; + imgForCheckingAndResolvingPromise.onerror = function() { + ok(!hasErrorEvent, + 'Should not receive an error event since the pending error event ' + + 'should be cleared before it fired'); + aResolve(); + }; + }; + + // Setting src to empty string queues an error event. + imgTarget.src = ''; + imgTarget.onerror = function() { + hasErrorEvent = true; + }; + }); +} + +function testReplacePendingErrorEvent() { + return new Promise(function(aResolve) { + var numOfErrorEvent = 0; + var imgTarget = new Image(); + + var imgForChangingTargetSrc = new Image(); + // Queue an error event for changing imgTarget's src. + imgForChangingTargetSrc.src = ''; + imgForChangingTargetSrc.onerror = function() { + // This clears pending error event and fires a new one. + imgTarget.src = ''; + + // Queue an error event for checking and resolving promise. + var imgForCheckingAndResolvingPromise = new Image(); + imgForCheckingAndResolvingPromise.src = ''; + imgForCheckingAndResolvingPromise.onerror = function() { + is(numOfErrorEvent, 1, + 'Should only receive one error event since the first pending error ' + + 'event should be cleared before it fired'); + aResolve(); + }; + }; + + // Setting src to empty string queues an error event. + imgTarget.src = ''; + imgTarget.onerror = function() { + numOfErrorEvent++; + }; + }); +} + +SimpleTest.waitForExplicitFinish(); + +Promise.resolve() +.then(() => testClearPendingErrorEvent()) +.then(() => testReplacePendingErrorEvent()) +.catch((err) => ok(false, "promise rejected: " + err)) +.then(() => SimpleTest.finish()); + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug1314032.html b/dom/base/test/test_bug1314032.html new file mode 100644 index 0000000000..ba12b6101f --- /dev/null +++ b/dom/base/test/test_bug1314032.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1314032</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1314032">Mozilla Bug 1243846</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + + let win = window.open(URL.createObjectURL(new Blob([ + '<meta charset="utf-8">' + + '<script>' + + 'let observer = new IntersectionObserver(([entry]) => {' + + 'document.body.textContent += entry.time' + + '});' + + 'observer.observe(document.documentElement);' + + '<\/script>' + ], {'type': 'text/html'}))); + + win.onload = function () { + win.close(); + ok(true); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<div id="log"> +</div> +</body> +</html> diff --git a/dom/base/test/test_bug166235.html b/dom/base/test/test_bug166235.html new file mode 100644 index 0000000000..8ef7dc4e3d --- /dev/null +++ b/dom/base/test/test_bug166235.html @@ -0,0 +1,160 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=166235 +https://bugzilla.mozilla.org/show_bug.cgi?id=816298 +--> +<head> + <title>Test for Bug 166235</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=166235">Mozilla Bug 166235 and Bug 816298</a> +<p id="test0">This text should be copied.</p> +<p id="test1">This text should<span style="-moz-user-select: none;"> NOT</span> be copied.</p> +<p id="test2">This<span style="-moz-user-select: none;"><span style="-moz-user-select: text"> text should</span> NOT</span> be copied.</p> +<p id="test3">This text should<span style="-moz-user-select: -moz-none;"> NOT</span> be copied.</p> +<p id="test4">This<span style="-moz-user-select: -moz-none;"><span style="-moz-user-select: text"> text should</span> NOT</span> be copied.</p> +<p id="test5">This<span style="-moz-user-select: all"> text<span style="-moz-user-select: none"> should</span></span> be copied.</p> +<div id="content" style="display: none"> + +</div> +<textarea id="input"></textarea> +<pre id="test"> +<script type="application/javascript"> + "use strict"; + +/** Test for Bug 166235 **/ + var Cc = SpecialPowers.Cc; + var Ci = SpecialPowers.Ci; + + var webnav = SpecialPowers.wrap(window).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIWebNavigation) + + var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell); + + var documentViewer = docShell.contentViewer + .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit); + + var clipboard = Cc["@mozilla.org/widget/clipboard;1"] + .getService(SpecialPowers.Ci.nsIClipboard); + + var textarea = SpecialPowers.wrap(document.getElementById('input')); + + function getLoadContext() { + return SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsILoadContext); + } + + function copyChildrenToClipboard(id) { + textarea.blur(); + clipboard.emptyClipboard(1); + window.getSelection().selectAllChildren(document.getElementById(id)); + documentViewer.copySelection(); + + is(clipboard.hasDataMatchingFlavors(["text/unicode"], 1,1), true); + is(clipboard.hasDataMatchingFlavors(["text/html"], 1,1), true); + } + function getClipboardData(mime) { + var transferable = Cc['@mozilla.org/widget/transferable;1'] + .createInstance(SpecialPowers.Ci.nsITransferable); + transferable.init(getLoadContext()); + transferable.addDataFlavor(mime); + clipboard.getData(transferable, 1); + var data = SpecialPowers.createBlankObject(); + transferable.getTransferData(mime, data, {}) ; + return SpecialPowers.wrap(data); + } + function testHtmlClipboardValue(mime, expected, test) { + var expectedValue = expected; + // For Windows, navigator.platform returns "Win32". + if (navigator.platform.indexOf("Win") >= 0) { + expectedValue = "<html><body>\n<!--StartFragment-->" + expected + "<!--EndFragment-->\n</body>\n</html>"; + } + testClipboardValue(mime, expectedValue, test); + } + function testClipboardValue(mime, expected, test) { + var data = getClipboardData(mime); + is (data.value == null ? data.value : + data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data, + expected, + mime + " value in the clipboard"); + return data.value; + } + function testPasteText(expected, test) { + textarea.value=""; + textarea.focus(); + textarea.editor.paste(1); + is(textarea.value, expected, test + ": textarea paste"); + } + function testInnerHTML(id, expected) { + var value = document.getElementById(id).innerHTML; + is(value, expected, id + ".innerHTML"); + } + +// expected results for Selection.toString() +var originalStrings = [ + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.' +]; + +// expected results for clipboard text/html +var clipboardHTML = [ + '<p id=\"test0\">This text should be copied.</p>', + '<p id=\"test1\">This text should be copied.</p>', + '<p id=\"test2\">This<span style=\"-moz-user-select: text\"> text should</span> be copied.</p>', + '<p id=\"test3\">This text should be copied.</p>', + '<p id=\"test4\">This<span style=\"-moz-user-select: text\"> text should</span> be copied.</p>', + '<p id=\"test5\">This<span style=\"-moz-user-select: all\"> text<span style=\"-moz-user-select: none\"> should</span></span> be copied.</p>', +]; + +// expected results for clipboard text/unicode +var clipboardUnicode = [ + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.' +]; + +// expected results for .innerHTML +var innerHTMLStrings = [ + 'This text should be copied.', + 'This text should<span style=\"-moz-user-select: none;\"> NOT</span> be copied.', + 'This<span style=\"-moz-user-select: none;\"><span style=\"-moz-user-select: text\"> text should</span> NOT</span> be copied.', + 'This text should<span style=\"-moz-user-select: -moz-none;\"> NOT</span> be copied.', + 'This<span style=\"-moz-user-select: -moz-none;\"><span style=\"-moz-user-select: text\"> text should</span> NOT</span> be copied.', + 'This<span style=\"-moz-user-select: all\"> text<span style=\"-moz-user-select: none\"> should</span></span> be copied.', +]; + +// expected results for pasting into a TEXTAREA +var textareaStrings = [ + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.', + 'This text should be copied.' +]; + +for (var i = 0; i < originalStrings.length; i++) { + var id = 'test' + i; + copyChildrenToClipboard(id); + is(window.getSelection().toString(), originalStrings[i], id + ' Selection.toString()'); + testHtmlClipboardValue("text/html", clipboardHTML[i], id); + testClipboardValue("text/unicode", clipboardUnicode[i], id); + testInnerHTML(id, innerHTMLStrings[i]); + testPasteText(textareaStrings[i], id + '.innerHTML'); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug199959.html b/dom/base/test/test_bug199959.html new file mode 100644 index 0000000000..ed5766ef33 --- /dev/null +++ b/dom/base/test/test_bug199959.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=199959 +--> +<head> + <title>Test for Bug 199959</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=199959">Mozilla Bug 199959</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="attrTest" testAttr="testValue"></div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 199959 **/ + +// From ACID3 +var attrTest = document.getElementById("attrTest"); +var attr = attrTest.getAttributeNode("testAttr"); +ok(attr.specified, "Attribute isn't specified!"); +attrTest.removeAttributeNode(attr); +ok(attr.specified, "Attribute isn't specified after removal!"); + +// From bug 199959 +attr = document.createAttribute('foo'); +ok(attr.specified, "Attribute isn't specified!"); + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug218236.html b/dom/base/test/test_bug218236.html new file mode 100644 index 0000000000..a8247aeb98 --- /dev/null +++ b/dom/base/test/test_bug218236.html @@ -0,0 +1,139 @@ +<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=218236
+-->
+<head>
+ <title>Test for Bug 218236</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=218236">Mozilla Bug 218236</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 218236 **/
+
+SimpleTest.waitForExplicitFinish();
+
+/* Test data */
+
+var url_200 = window.location.href;
+var url_404 = url_200.replace(/[^/]+$/, "this_file_is_not_going_to_be_there.dummy");
+var url_connection_error = url_200.replace(/^(\w+:\/\/[^/]+?)(:\d+)?\//, "$1:9546/");
+
+// List of tests: name of the test, URL to be requested, expected sequence
+// of events and optionally a function to be called from readystatechange handler.
+// Numbers in the list of events are values of XMLHttpRequest.readyState
+// when readystatechange event is triggered.
+var tests = [
+ ["200 OK", url_200, [1, 2, 3, 4, "load"], null],
+ ["404 Not Found", url_404, [1, 2, 3, 4, "load"], null],
+ ["connection error", url_connection_error, [1, 2, 4, "error"], null],
+ ["abort() call on readyState = 1", url_200, [1, 4], null, doAbort1],
+ ["abort() call on readyState = 2", url_200, [1, 2, 4], doAbort2],
+];
+
+var testName = null;
+var currentState = 0;
+var currentSequence = null;
+var expectedSequence = null;
+var currentCallback = null;
+var finalizeTimeoutID = null;
+
+var request = null;
+
+runNextTest();
+
+function doAbort1() {
+ if (request.readyState == 1)
+ request.abort();
+}
+function doAbort2() {
+ if (request.readyState == 2)
+ request.abort();
+}
+
+/* Utility functions */
+
+function runNextTest() {
+ if (tests.length > 0) {
+ var test = tests.shift();
+
+ // Initialize state variables
+ testName = test[0]
+ currentState = 0;
+ currentSequence = [];
+ expectedSequence = test[2];
+ currentCallback = test[3];
+ postSendCallback = test[4];
+
+ // Prepare request object
+ request = new XMLHttpRequest();
+ request.onreadystatechange = onReadyStateChange;
+ request.open("GET", test[1]);
+ request.onload = onLoad;
+ request.onerror = onError;
+
+ // Start request
+ request.send(null);
+ if (postSendCallback)
+ postSendCallback();
+ }
+ else
+ SimpleTest.finish();
+}
+
+function finalizeTest() {
+ finalizeTimeoutID = null;
+ ok(compareArrays(expectedSequence, currentSequence), "event sequence for '" + testName + "' was " + currentSequence.join(", "));
+
+ runNextTest();
+}
+
+function onReadyStateChange() {
+ clearTimeout(finalizeTimeoutID);
+ finalizeTimeoutID = null;
+
+ currentState = request.readyState;
+ currentSequence.push(currentState);
+
+ if (currentState == 4) {
+ // Allow remaining event to fire but then we are finished with this test
+ // unless we get another onReadyStateChange in which case we'll cancel
+ // this timeout
+ finalizeTimeoutID = setTimeout(finalizeTest, 0);
+ }
+
+ if (currentCallback)
+ currentCallback();
+}
+
+function onLoad() {
+ currentSequence.push("load");
+}
+
+function onError() {
+ currentSequence.push("error");
+}
+
+function compareArrays(array1, array2) {
+ if (array1.length != array2.length)
+ return false;
+
+ for (var i = 0; i < array1.length; i++)
+ if (array1[i] != array2[i])
+ return false;
+
+ return true;
+}
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/base/test/test_bug218277.html b/dom/base/test/test_bug218277.html new file mode 100644 index 0000000000..88cda1d788 --- /dev/null +++ b/dom/base/test/test_bug218277.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=218277 +--> +<head> + <title>Test for Bug 218277</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=218277">Mozilla Bug 218277</a> +<p id="display"></p> +<div id="content" style="display: block"> + <input id="ctrl" name="ctrl" size="20" value="keep together" readonly /> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 218277 **/ + +is(escape($('ctrl').value), "keep%A0together", "nbsp preserved in form submissions"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug238409.html b/dom/base/test/test_bug238409.html new file mode 100644 index 0000000000..f4dfe004a4 --- /dev/null +++ b/dom/base/test/test_bug238409.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=238409
+-->
+<head>
+ <title>Test for Bug 238409</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=238409">Mozilla Bug 238409</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <table id="table_spacing0" cellspacing="0">
+ <tr><td>cellspacing="0"</td></tr>
+ </table>
+
+ <table id="table_spacing2" cellspacing="2">
+ <tr><td>cellspacing="2"</td></tr>
+ </table>
+
+ <table id="table_spacingNone">
+ <tr><td>no cellspacing</td></tr>
+ </table>
+
+ <table id="table_spacingMalformed" cellspacing>
+ <tr><td>malformed cellspacing</td></tr>
+ </table>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 238409 **/
+
+ok(document.getElementById("table_spacing0").cellSpacing == "0", "parsing table with cellspacing='0'");
+ok(document.getElementById("table_spacing2").cellSpacing == "2", "parsing table with cellspacing='2'");
+ok(document.getElementById("table_spacingNone").cellSpacing == "", "parsing table without cellspacing");
+ok(document.getElementById("table_spacingMalformed").cellSpacing == "", "parsing table with malformed cellspacing");
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/base/test/test_bug254337.html b/dom/base/test/test_bug254337.html new file mode 100644 index 0000000000..9cc6e53dbf --- /dev/null +++ b/dom/base/test/test_bug254337.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=254337 +--> +<head> + <title>Test for Bug 254337</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=254337">Mozilla Bug 254337</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 254337 **/ + +var el = document.createElement("div"); +el.setAttribute("class", "foobar1"); +is(el.className, "foobar1", "Wrong className!"); +el.className += " foobar2 "; +is(el.className, "foobar1 foobar2 ", "Appending to className didn't work!"); +el.className += "foobar3"; +is(el.className, "foobar1 foobar2 foobar3", "Appending to className didn't work!"); + +var el = document.createElement("div"); +el.setAttribute("class", " foobar1 "); +is(el.className, " foobar1 ", "Wrong className!"); +el.className += "foobar2"; +is(el.className, " foobar1 foobar2", "Appending to className didn't work!"); +el.setAttribute("class", " "); +is(el.getAttribute("class"), " ", "class attribute didn't store the right value!"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug270145.xhtml b/dom/base/test/test_bug270145.xhtml new file mode 100644 index 0000000000..3a6fc0f2bb --- /dev/null +++ b/dom/base/test/test_bug270145.xhtml @@ -0,0 +1,53 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=270145 +--> +<head> + <title>Test the html copy encoder with XHTML </title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=270145">Mozilla Bug 270145</a> +<p id="display"></p> +<div id="content" > +<p id="foo"><![CDATA[a text to copy]]></p> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +//<![CDATA[ +function testHtmlCopyEncoder () { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + var out, expected; + + var node = document.getElementById('draggable'); + + var select = window.getSelection(); + select.removeAllRanges(); + + node = document.getElementById("foo").firstChild; + var range = document.createRange(); + range.setStart(node, 0); + range.setEnd(node, "a text to copy".length); + select.addRange(range); + encoder.init(document, "text/html", 0); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = "a text to copy"; + is(out, expected, "test xhtml copy"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlCopyEncoder); +//]]> +</script> +</pre> + +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/test_bug276037-1.html b/dom/base/test/test_bug276037-1.html new file mode 100644 index 0000000000..4995479f49 --- /dev/null +++ b/dom/base/test/test_bug276037-1.html @@ -0,0 +1,105 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=276037 +--> +<head> + <title>Test for Bug 276037</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=276037">Mozilla Bug 276037</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 276037 **/ +function countElements (node, namespaceURI, localName) { + var count = 0; + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if (child.nodeType == Node.ELEMENT_NODE && child.localName == localName && + child.namespaceURI == namespaceURI) { + count++; + } + if (child.hasChildNodes()) { + count += countElements(child, namespaceURI, localName); + } + } + return count; +} + +function checkElements(namespaceURI, localName) { + var elementsNS = document.getElementsByTagNameNS(namespaceURI, localName); + var elements = document.getElementsByTagName(localName); + var elementCount = countElements(document, namespaceURI, localName); + const gEBTN = 'document.getElementsByTagName(\'' + localName + '\').length: ' + elements.length; + const gEBTNNS = '; document.getElementsByTagNameNS(\'' + namespaceURI + '\', \'' + localName + '\').length: ' + elementsNS.length; + + text1 = gEBTN + '; element count: ' + elementCount; + text2 = gEBTNNS + '; element count: ' + elementCount; + + is(elements.length, elementCount, text1); + is(elementsNS.length, elementCount, text2); + is(global.gEBTN[namespaceURI][localName].length, elementCount, text1); + is(global.gEBTNNS[namespaceURI][localName].length, elementCount, text2); +} + +const xhtmlNS = 'http://www.w3.org/1999/xhtml'; + +function checkSpansAndScripts () { + checkElements(xhtmlNS, 'span'); + checkElements(xhtmlNS, 'script'); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { checkSpansAndScripts() }); +addLoadEvent(SimpleTest.finish); + +// Init our global lists +var global = {}; +global.gEBTN = {}; +global.gEBTN[xhtmlNS] = {}; +global.gEBTNNS = {}; +global.gEBTNNS[xhtmlNS] = {}; + +global.gEBTN[xhtmlNS].span = document.getElementsByTagName("span"); +global.gEBTNNS[xhtmlNS].span = document.getElementsByTagNameNS(xhtmlNS, "span"); +global.gEBTN[xhtmlNS].script = document.getElementsByTagName("script"); +global.gEBTNNS[xhtmlNS].script = document.getElementsByTagNameNS(xhtmlNS, "script"); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug276037-2.xhtml b/dom/base/test/test_bug276037-2.xhtml new file mode 100644 index 0000000000..432d57e71d --- /dev/null +++ b/dom/base/test/test_bug276037-2.xhtml @@ -0,0 +1,106 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=276037 +--> +<head> + <title>Test for Bug 276037</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=276037">Mozilla Bug 276037</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ + +/** Test for Bug 276037 **/ +function countElements (node, namespaceURI, tagName) { + var count = 0; + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if (child.nodeType == Node.ELEMENT_NODE && child.tagName == tagName && + child.namespaceURI == namespaceURI) { + count++; + } + if (child.hasChildNodes()) { + count += countElements(child, namespaceURI, tagName); + } + } + return count; +} + +function checkElements(namespaceURI, tagName) { + var elementsNS = document.getElementsByTagNameNS(namespaceURI, tagName); + var elements = document.getElementsByTagName(tagName); + var elementCount = countElements(document, namespaceURI, tagName); + const gEBTN = 'document.getElementsByTagName(\'' + tagName + '\').length: ' + elements.length; + const gEBTNNS = '; document.getElementsByTagNameNS(\'' + namespaceURI + '\', \'' + tagName + '\').length: ' + elementsNS.length; + + var text1 = gEBTN + '; element count: ' + elementCount; + var text2 = gEBTNNS + '; element count: ' + elementCount; + + is(elements.length, elementCount, text1); + is(elementsNS.length, elementCount, text2); + is(global.gEBTN[namespaceURI][tagName].length, elementCount, text1); + is(global.gEBTNNS[namespaceURI][tagName].length, elementCount, text2); +} + +const xhtmlNS = 'http://www.w3.org/1999/xhtml'; + +function checkSpansAndScripts () { + checkElements(xhtmlNS, 'span'); + checkElements(xhtmlNS, 'script'); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { checkSpansAndScripts() }); +addLoadEvent(SimpleTest.finish); + +// Init our global lists +var global = {}; +global.gEBTN = {}; +global.gEBTN[xhtmlNS] = {}; +global.gEBTNNS = {}; +global.gEBTNNS[xhtmlNS] = {}; +global.gEBTN[xhtmlNS].span = document.getElementsByTagName("span"); +global.gEBTNNS[xhtmlNS].span = document.getElementsByTagNameNS(xhtmlNS, "span"); +global.gEBTN[xhtmlNS].script = document.getElementsByTagName("script"); +global.gEBTNNS[xhtmlNS].script = document.getElementsByTagNameNS(xhtmlNS, "script"); +]]> +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +<p><span>Static text in span.</span></p> +<script type="text/javascript"> +checkSpansAndScripts(); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug282547.html b/dom/base/test/test_bug282547.html new file mode 100644 index 0000000000..054785abef --- /dev/null +++ b/dom/base/test/test_bug282547.html @@ -0,0 +1,104 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=282547 +--> +<head> + <title>Test for Bug 282547</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=282547">Mozilla Bug 282547</a> +<p id="display"></p> +<div id="content" style="display: none"></div> + +<script class="testbody" type="text/javascript"> + +function xhr_userpass_sync() { + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'bug282547.sjs', false, 'username', 'password'); + + xhr.send(null); + ok(xhr.status == 401, "Status 401"); + + runTests(); +} + +function xhr_userpass_async() { + xhr = new XMLHttpRequest(); + xhr.open('GET', 'bug282547.sjs', true, 'username', 'password'); + + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + ok(xhr.status == 401, "Status 401"); + runTests(); + } + } + + xhr.send(null); +} + +function xhr_auth_header_sync() { + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'bug282547.sjs', false); + xhr.setRequestHeader("Authorization", "42"); + + xhr.send(null); + ok(xhr.status == 401, "Status 401"); + + runTests(); +} + +function xhr_auth_header_async() { + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'bug282547.sjs', true); + xhr.setRequestHeader("Authorization", "42"); + + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + ok(xhr.status == 401, "Status 401"); + runTests(); + } + } + + xhr.send(null); +} + +function xhr_crossorigin_sync() { + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'http://example.com/tests/dom/base/test/bug282547.sjs', true); + xhr.withCredentials = true; + + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + ok(xhr.status == 401, "Status 401"); + runTests(); + } + } + + xhr.send(null); +} + +var tests = [ xhr_userpass_sync, + xhr_userpass_async, + xhr_auth_header_sync, + xhr_auth_header_async, + /* Disabled: bug799540 xhr_crossorigin_sync */ ]; +function runTests() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTests(); +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_bug28293.html b/dom/base/test/test_bug28293.html new file mode 100644 index 0000000000..61c14cbd8f --- /dev/null +++ b/dom/base/test/test_bug28293.html @@ -0,0 +1,86 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=28293 +--> +<head> + <title>Test for Bug 28293</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script> +scriptInsertedExternalExecuted = false; +res = 'A'; + +SimpleTest.waitForExplicitFinish(); +onload = function () { + + res+='2'; + + s = document.createElement('script'); + s.textContent="res+='g';"; + s.defer = true; + document.body.appendChild(s); + + res+='3'; + + s = document.createElement('script'); + s.textContent="res+='i';done()"; + s.defer = true; + document.body.appendChild(s); + + res+='4'; +} + +function done() { + is(res, "AacBCDEFGeHIJb1M2g3i", "scripts executed in the wrong order"); + ok(scriptInsertedExternalExecuted, "Dynamic script did not block load"); + SimpleTest.finish(); +} +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=28293">Mozilla Bug 28293</a> + +<script defer> +res += 'a'; +</script> +<script defer src="data:text/plain,res+='b'"></script> +<script defer> +res += 'c'; +</script> +<script> +res += 'B'; +</script> +<script> +res += 'C'; + +s = document.createElement('script'); +s.textContent="res+='D';"; +document.body.appendChild(s); + +res += 'E'; +</script> +<script> +res += 'F'; +document.addEventListener("DOMContentLoaded", function() { + res += '1' + s = document.createElement('script'); + s.src="file_bug28293.sjs?res+='M';"; + document.body.appendChild(s); +}, false); +res += 'G'; +</script> +<script defer> +res += 'e'; +</script> +<script src="file_bug28293.sjs?res+='H';"></script> +<script> +res += 'I'; +s = document.createElement('script'); +s.src="file_bug28293.sjs?scriptInsertedExternalExecuted=true;"; +document.body.appendChild(s); +res += 'J'; +</script> + +</body> +</html> diff --git a/dom/base/test/test_bug28293.xhtml b/dom/base/test/test_bug28293.xhtml new file mode 100644 index 0000000000..7ea4eff209 --- /dev/null +++ b/dom/base/test/test_bug28293.xhtml @@ -0,0 +1,87 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=28293 +--> +<head> + <title>Test for Bug 28293</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script> +scriptInsertedExternalExecuted = false; +res = 'A'; + +SimpleTest.waitForExplicitFinish(); +onload = function () { + + res+='2'; + + s = document.createElement('script'); + s.textContent="res+='g';"; + s.defer = true; + document.body.appendChild(s); + + res+='3'; + + s = document.createElement('script'); + s.textContent="res+='i';done()"; + s.defer = true; + document.body.appendChild(s); + + res+='4'; +} + +function done() { + is(res, "AacBCDEFGeHIJb1M2g3i", "scripts executed in the wrong order"); + ok(scriptInsertedExternalExecuted, "Dynamic script did not block load"); + SimpleTest.finish(); +} +</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=28293">Mozilla Bug 28293</a> + +<script defer="defer"> +res += 'a'; +</script> +<script defer="defer" src="data:text/plain,res+='b'"></script> +<script defer="defer"> +res += 'c'; +</script> +<script> +res += 'B'; +</script> +<script> +res += 'C'; + +s = document.createElement('script'); +s.textContent="res+='D';"; +document.body.appendChild(s); + +res += 'E'; +</script> +<script> +res += 'F'; +document.addEventListener("DOMContentLoaded", function() { + res += '1' + s = document.createElement('script'); + s.src="file_bug28293.sjs?res+='M';"; + document.body.appendChild(s); +}, false); +res += 'G'; +</script> +<script defer="defer"> +res += 'e'; +</script> +<script src="file_bug28293.sjs?res+='H';"></script> +<script> +<![CDATA[ +res += 'I'; +s = document.createElement('script'); +s.src="file_bug28293.sjs?scriptInsertedExternalExecuted=true;"; +document.body.appendChild(s); +res += 'J'; +]]> +</script> + +</body> +</html> diff --git a/dom/base/test/test_bug298064.html b/dom/base/test/test_bug298064.html new file mode 100644 index 0000000000..377c9e19b9 --- /dev/null +++ b/dom/base/test/test_bug298064.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=298064 +--> +<head> + <title>Test for Bug 298064</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=298064">Mozilla Bug 298064</a> +<p id="display"><iframe src="bug298064-subframe.html"></iframe></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 298064 **/ +SimpleTest.waitForExplicitFinish() +addLoadEvent(function() { + window.frames[0].test_func(); +}); +addLoadEvent(SimpleTest.finish); + + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug300992.html b/dom/base/test/test_bug300992.html new file mode 100644 index 0000000000..ae426b31c2 --- /dev/null +++ b/dom/base/test/test_bug300992.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=300992 +--> +<head> + <title>Test for Bug 300992</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=300992">Mozilla Bug 300992</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 300992 **/ +SimpleTest.waitForExplicitFinish(); + +var i = 0; +var states = ['loading', + 'interactive1', 'interactive2', + 'complete1', 'complete2']; + +is(document.readyState, states[i++], 'initial readyState'); +document.onreadystatechange = function (event) { + is(document.readyState + '1', states[i++], 'readystatechange event "on" handler'); +}; +document.addEventListener('readystatechange', function(event) { + is(document.readyState + '2', states[i++], 'readystatechange event document listener'); +}, false); +window.addEventListener('readystatechange', function(event) { + ok(false, 'window listener', 'readystatechange event should not bubble to window'); +}, false); +addLoadEvent(function() { + is(i, states.length, 'readystatechange event count'); + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug311681.xml b/dom/base/test/test_bug311681.xml new file mode 100644 index 0000000000..23efcb4688 --- /dev/null +++ b/dom/base/test/test_bug311681.xml @@ -0,0 +1,103 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=311681 +--> +<head> + <title>Test for Bug 311681</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=311681">Mozilla Bug 311681</a> +<script class="testbody" type="text/javascript"> +<![CDATA[ + // Setup script + SimpleTest.waitForExplicitFinish(); + + // Make sure to trigger the hashtable case by asking for enough elements + // by ID. + for (var i = 0; i < 256; ++i) { + var x = document.getElementById(i); + } + + // save off the document.getElementById function, since getting it as a + // property off the document it causes a content flush. + var fun = document.getElementById; + + // Slot for our initial element with id "content" + var testNode; + + function getCont() { + return fun.call(document, "content"); + } + + function testClone() { + // Test to make sure that if we have multiple nodes with the same ID in + // a document we don't forget about one of them when the other is + // removed. + var newParent = $("display"); + var node = testNode.cloneNode(true); + isnot(node, testNode, "Clone should be a different node"); + + newParent.appendChild(node); + + // Check what getElementById returns, no flushing + is(getCont(), node, "Should be getting orig node pre-flush 1"); + + // Trigger a layout flush, just in case. + var itemHeight = newParent.offsetHeight/10; + + // Check what getElementById returns now. + is(getCont(), node, "Should be getting new node post-flush 1"); + + clear(newParent); + + // Check what getElementById returns, no flushing + is(getCont(), testNode, "Should be getting orig node pre-flush 2"); + + // Trigger a layout flush, just in case. + var itemHeight = newParent.offsetHeight/10; + + // Check what getElementById returns now. + is(getCont(), testNode, "Should be getting orig node post-flush 2"); + + node = testNode.cloneNode(true); + newParent.appendChild(node); + testNode.parentNode.removeChild(testNode); + + // Check what getElementById returns, no flushing + is(getCont(), node, "Should be getting clone pre-flush"); + + // Trigger a layout flush, just in case. + var itemHeight = newParent.offsetHeight/10; + + // Check what getElementById returns now. + is(getCont(), node, "Should be getting clone post-flush"); + + } + + function clear(node) { + while (node.hasChildNodes()) { + node.removeChild(node.firstChild); + } + } + + addLoadEvent(testClone); + addLoadEvent(SimpleTest.finish); +]]> +</script> +<p id="display"></p> +<div id="content" style="display: none"> + <script class="testbody" type="text/javascript"> + <![CDATA[ + testNode = fun.call(document, "content"); + // Needs incremental XML parser + isnot(testNode, null, "Should have node here"); + ]]> + </script> +</div> +<pre id="test"> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug313646.html b/dom/base/test/test_bug313646.html new file mode 100644 index 0000000000..c4d59b197f --- /dev/null +++ b/dom/base/test/test_bug313646.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=313646 +--> +<head> + <title>Test for Bug 313646</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=313646">Mozilla Bug 313646</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 313646 **/ + +// dom/base/test/bug313646.txt + +SimpleTest.waitForExplicitFinish(); + +var count1 = 0; +var count2 = 0; +var count3 = 0; +var count4 = 0; +var innerXHRDone = 0; +var req = new XMLHttpRequest(); +req.onreadystatechange = function(evt) { + ++window["count" + evt.target.readyState]; + + // Do something a bit evil, start a new sync XHR in + // readyStateChange listener. + var innerXHR = new XMLHttpRequest(); + innerXHR.onreadystatechange = function(e) { + if (e.target.readyState == 4) { + ++innerXHRDone; + } + } + innerXHR.open("GET","bug313646.txt", false); + innerXHR.send(); +} + +// make the synchronous request +req.open("GET","bug313646.txt", false); +req.send(); + +ok(count1, "XMLHttpRequest wasn't in state 1"); +is(count2, 0, "XMLHttpRequest shouldn't have been in state 2"); +is(count3, 0, "XMLHttpRequest shouldn't have been in state 3"); +ok(count4, "XMLHttpRequest wasn't in state 4"); +is(innerXHRDone, 2, "There should have been 2 inner XHRs."); + +SimpleTest.finish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug320799.html b/dom/base/test/test_bug320799.html new file mode 100644 index 0000000000..c40485d01f --- /dev/null +++ b/dom/base/test/test_bug320799.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=320799 +--> +<head> + <title>Test for Bug 320799</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=320799">Mozilla Bug 320799</a> +<p id="display"> + <select id="s" style="width: 100px; box-sizing: border-box; border: 0"> + <option>This is a test, it really is a test I tell you</option> + </select> + <select id="s2"> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + <option>x</option> + </select> + <select id="s3"> + <option>x</option> + </select> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 320799 **/ +is($("s").scrollWidth, 100, "Scroll width should not include dropdown contents"); +is($("s2").clientWidth, $("s3").clientWidth, + "Client width should not depend on the dropdown's vertical scrollbar"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug322317.html b/dom/base/test/test_bug322317.html new file mode 100644 index 0000000000..b5581a6e72 --- /dev/null +++ b/dom/base/test/test_bug322317.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=322317 +--> +<head> + <title>Test for Bug 322317</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=322317">Mozilla Bug 322317</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 322317 **/ +/* Test that this does not throw exceptions */ +var http =new XMLHttpRequest(); +http.open("GET", window.location.href); +http.send(null); +http.open("GET", window.location.href); +http.send(null); +is(1, 1, "Got here, yay!"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug326337.html b/dom/base/test/test_bug326337.html new file mode 100644 index 0000000000..5e8f67ec7f --- /dev/null +++ b/dom/base/test/test_bug326337.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=326337 +--> +<head> + <title>Test for Bug 326337</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=326337">Mozilla Bug 326337</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 326337 **/ + +SimpleTest.waitForExplicitFinish(); + +var win = window.open("file_bug326337_outer.html", "", "width=10, height=10"); + +function finishTest(str) { + win.close(); + is(str, "#done", "failed to run"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug330925.xhtml b/dom/base/test/test_bug330925.xhtml new file mode 100644 index 0000000000..a26ab94be9 --- /dev/null +++ b/dom/base/test/test_bug330925.xhtml @@ -0,0 +1,74 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=330925 +--> +<head> + <title>Test for Bug 330925</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<style type="text/css"> +#t { +-moz-binding: url(#randomxbl); +} +</style> + +<bindings xmlns="http://www.mozilla.org/xbl"> +<binding id="randomxbl" inheritstyle="false"> +<content> +xbl textnode1 +<div> +xbl textnode2 +<children xmlns="http://www.mozilla.org/xbl"/> +</div> +</content> +</binding> +</bindings> + +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=330925">Mozilla Bug 330925</a> + +<p id="display"> +<div id="t" /> +</p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ + +/** Test for Bug 330925 **/ + +// We have to wait until onload because XBL doesn't bind immediately. +SimpleTest.waitForExplicitFinish(); +addLoadEvent(init); + +function init() +{ + var t = document.getElementById("t"); + var d = SpecialPowers.wrap(document); + + is(SpecialPowers.unwrap(d.getBindingParent(d.getAnonymousNodes(t)[0])), + t, + "Wrong binding parent for anonymous node"); + + is(SpecialPowers.unwrap(d.getBindingParent(d.getAnonymousNodes(t)[1].childNodes[0])), + t, + "Wrong binding parent for child of anonymous node"); + + is(d.getBindingParent(t), + null, + "Non-anonymous node should not have a binding parent"); + + is(d.getBindingParent(document.documentElement), + null, + "Document element should not have a binding parent"); + + SimpleTest.finish(); +} + +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug331959.html b/dom/base/test/test_bug331959.html new file mode 100644 index 0000000000..5ef20400f9 --- /dev/null +++ b/dom/base/test/test_bug331959.html @@ -0,0 +1,151 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=331959 +--> +<head> + <title>Test for Bug 331959</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=331959">Mozilla Bug 331959</a> +<p id="display"> + <iframe id="link-in-link-mouse"></iframe> + <iframe id="link-in-link-keyboard"></iframe> + <iframe id="input-in-link-mouse"></iframe> + <iframe id="input-in-link-keyboard"></iframe> + <iframe id="button-in-link-mouse"></iframe> + <iframe id="button-in-link-keyboard"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 331959 **/ +SimpleTest.waitForExplicitFinish(); + +const FAILURL = "data:text/plain,FAIL"; +const PASSURL = "data:text/plain,PASS"; + +var currentTest = 0; +var tests = [ testLinkInLinkMouse, testLinkInLinkKeyboard, + testInputInLinkMouse, testInputInLinkKeyboard, + testButtonInLinkMouse, testButtonInLinkKeyboard ]; +function doNextTest() { + if (currentTest == tests.length) { + SimpleTest.finish(); + } else { + tests[currentTest++](); + } +} + +function generateLinkInLink(id, desc) { + var doc = $(id).contentDocument; + var outerA = doc.createElement("a"); + var innerA = doc.createElement("a"); + outerA.id = "outer"; + innerA.id = "inner"; + innerA.href = PASSURL; + outerA.href = FAILURL; + innerA.appendChild(doc.createTextNode("Text")); + outerA.appendChild(innerA); + doc.body.appendChild(outerA); + $(id).onload = function() { + is(this.contentDocument.documentElement.textContent, "PASS", desc); + // Have to remove the iframe we used from the DOM, because the harness is + // stupid and doesn't have enough space for more than one iframe. + $(id).parentNode.removeChild($(id)); + doNextTest(); + }; + return [innerA, $(id).contentWindow]; +} + +function testLinkInLinkMouse() { + var [innerA, testWin] = + generateLinkInLink("link-in-link-mouse", + "Clicking an inner link should load the inner link"); + synthesizeMouseAtCenter(innerA, {}, testWin); +} + +function testLinkInLinkKeyboard() { + var [innerA, testWin] = + generateLinkInLink("link-in-link-keyboard", + "Hitting enter on an inner link should load the inner link"); + innerA.focus(); + synthesizeKey("VK_RETURN", {}, testWin); +} + +function generateInputInLink(id, desc) { + var doc = $(id).contentDocument; + doc.body.innerHTML = + "<form action='" + PASSURL + "'><a href='" + FAILURL + + "'><input type='submit' id='submit'>"; + $(id).onload = function() { + is(this.contentDocument.documentElement.textContent, "PASS?", desc); + // Have to remove the iframe we used from the DOM, because the harness is + // stupid and doesn't have enough space for more than one iframe. + $(id).parentNode.removeChild($(id)); + doNextTest(); + }; + var input = doc.getElementById("submit"); + doc.body.offsetWidth; + return [input, $(id).contentWindow]; +} + +function testInputInLinkMouse() { + var [input, testWin] = + generateInputInLink("input-in-link-mouse", + "Clicking an submit input inside an anchor should submit the form"); + synthesizeMouseAtCenter(input, {}, testWin); +} + +function testInputInLinkKeyboard() { + var [input, testWin] = + generateInputInLink("input-in-link-keyboard", + "Return on submit input inside an anchor should submit the form"); + input.focus(); + synthesizeKey("VK_RETURN", {}, testWin); +} + +function generateButtonInLink(id, desc) { + var doc = $(id).contentDocument; + doc.body.innerHTML = + "<form action='" + PASSURL + "'><a href='" + FAILURL + + "'><button type='submit' id='submit'>Submit</button>"; + $(id).onload = function() { + is(this.contentDocument.documentElement.textContent, "PASS?", desc); + // Have to remove the iframe we used from the DOM, because the harness is + // stupid and doesn't have enough space for more than one iframe. + $(id).parentNode.removeChild($(id)); + doNextTest(); + }; + var button = doc.getElementById("submit"); + return [button, $(id).contentWindow]; +} + +function testButtonInLinkMouse() { + var [button, testWin] = + generateButtonInLink("button-in-link-mouse", + "Clicking an submit button inside an anchor should submit the form"); + synthesizeMouseAtCenter(button, {}, testWin); +} + +function testButtonInLinkKeyboard() { + var [button, testWin] = + generateButtonInLink("button-in-link-keyboard", + "Return on submit button inside an anchor should submit the form"); + button.focus(); + synthesizeKey("VK_RETURN", {}, testWin); +} + +// We need focus to handle clicks properly +SimpleTest.waitForFocus(doNextTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug333064.html b/dom/base/test/test_bug333064.html new file mode 100644 index 0000000000..6e99fed881 --- /dev/null +++ b/dom/base/test/test_bug333064.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=333064 +--> +<head> + <title>Test for Bug 333064</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=333064">Mozilla Bug 333064</a> +<p id="display"></p> + +<div id="display"> +</div> +<div id="korean-text">안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안안</div> + +<pre id="test"> +</pre> + +<script class="testbody" type="application/javascript"> + +/** Test for Bug 333064 **/ +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(function() { + var div = document.getElementById("korean-text"); + var sel = window.getSelection(); + + // Select text node in div. + var r = document.createRange(); + r.setStart(div, 0); + r.setEnd(div, 1); + sel.addRange(r); + + SimpleTest.waitForClipboard( + function compare(value) { + // Make sure we got the HTML flavour we asked for and that our + // string is included without additional spaces. + return value.includes("korean-text") && value.includes("안".repeat(160)); + }, + function setup() { + synthesizeKey("C", {accelKey: true}); + }, + function onSuccess() { + SimpleTest.finish(); + }, + function onFailure() { + SimpleTest.finish(); + }, + "text/html" + ); +}); + +</script> + +</body> +</html> diff --git a/dom/base/test/test_bug333198.html b/dom/base/test/test_bug333198.html new file mode 100644 index 0000000000..452284080b --- /dev/null +++ b/dom/base/test/test_bug333198.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=333198 +--> +<head> + <title>Test for Bug 333198</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<!-- setTimeout so that the test starts after paint suppression ends --> +<body onload="setTimeout(runTest,0);"> +<iframe id="ifr"></iframe><br> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=333198">Mozilla Bug 333198</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 333198 **/ + +var focusTester; +var focusTester2; +var focusCount = 0; +var eventCount = 0; +function clickHandler() { + ++eventCount; +} + +function suppressEvents(suppress) { + SpecialPowers.DOMWindowUtils.suppressEventHandling(suppress); +} + +function sendEvents() { + windowUtils = SpecialPowers.getDOMWindowUtils(window); + windowUtils.sendMouseEvent("mousedown", 1, 1, 0, 1, 0); + windowUtils.sendMouseEvent("mouseup", 1, 1, 0, 1, 0); + + iframeUtils = SpecialPowers.getDOMWindowUtils(document.getElementById("ifr").contentWindow); + iframeUtils.sendMouseEvent("mousedown", 1, 1, 0, 1, 0); + iframeUtils.sendMouseEvent("mouseup", 1, 1, 0, 1, 0); +} + +function runTest() { + window.focus(); + focusTester = document.getElementsByTagName("input")[0]; + focusTester.blur(); + window.addEventListener("click", clickHandler, true); + var ifr = document.getElementById("ifr") + ifr.contentWindow.addEventListener("click", clickHandler, true); + sendEvents(); + is(eventCount, 2, "Wrong event count(1)"); + suppressEvents(true); + sendEvents(); + is(eventCount, 2, "Wrong event count(2)"); + suppressEvents(false); + sendEvents(); + is(eventCount, 4, "Wrong event count(2)"); + + is(focusCount, 0, "Wrong focus count (1)"); + var xhr = new XMLHttpRequest(); + xhr.open("GET", window.location, false); + xhr.onload = function() { + focusTester.focus(); + is(focusCount, 1, "Wrong focus count (2)"); + focusTester.blur(); + } + xhr.send(); + + focusTester.focus(); + is(focusCount, 2, "Wrong focus count (3)"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<input type="text" onfocus="++focusCount;"> +</body> +</html> diff --git a/dom/base/test/test_bug333673.html b/dom/base/test/test_bug333673.html new file mode 100644 index 0000000000..fbc3700d00 --- /dev/null +++ b/dom/base/test/test_bug333673.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=333673 +--> +<head> + <title>Test for Bug 333673</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=333673">Mozilla Bug 333673</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 333673 **/ + +is(document.implementation, document.implementation, + "document.implementation should be the same object all the time."); + + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug337631.html b/dom/base/test/test_bug337631.html new file mode 100644 index 0000000000..4f9beeec93 --- /dev/null +++ b/dom/base/test/test_bug337631.html @@ -0,0 +1,99 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=337631 +--> +<head> + <title>Test for Bug 337631</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=337631">Mozilla Bug 337631</a> +<p id="display"></p> +<div id="content"> + +<a href="foo" id="test4">foo</a> +<input id="test1" value="test"> +<p id="test2">adsf<a href="#" id="test3">asdf</a><input id="test5"></p> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 337631 **/ + +function getActiveElement() +{ + var rv; + + var el = document.activeElement; + if (!el) { + rv = "none"; + return rv; + } + + if (el && el != document.documentElement) { + var nt; + try { + nt = el.nodeType; + } catch (e) { + rv = "[no permission]"; + return rv; + } + if (!nt) { + rv = "[unknown]"; + } else if (nt == 1) { + rv = el.tagName; + } else if (nt == 3) { + rv = "textnode" + } else { + rv = nt; + } + + el = el.parentNode; + while (el && el != document.documentElement) { + rv += " in "; + try { + nt = el.nodeType; + } catch (e) { + rv += "[no permission]"; + return rv; + } + if (!nt) { + rv += "[unknown]"; + } else if (nt == 1) { + rv += el.tagName; + } else if (nt == 3) { + rv += "textnode" + } else { + rv += nt; + } + + el = el.parentNode; + } + } + + return rv; +} + +$('test1').focus(); +is(getActiveElement(), "INPUT in DIV in BODY", "getActiveElement tests"); + +$('test2').focus(); +is(getActiveElement(), "INPUT in DIV in BODY", "getActiveElement tests"); + +$('test3').focus(); +is(getActiveElement(), "A in P in DIV in BODY", "getActiveElement tests"); + +$('test4').focus(); +is(getActiveElement(), "A in DIV in BODY", "getActiveElement tests"); + +$('test5').focus(); +is(getActiveElement(), "INPUT in P in DIV in BODY", "getActiveElement tests"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug338541.xhtml b/dom/base/test/test_bug338541.xhtml new file mode 100644 index 0000000000..424c02aa1d --- /dev/null +++ b/dom/base/test/test_bug338541.xhtml @@ -0,0 +1,49 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=338541 +--> +<head> + <title>Test for Bug 338541</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=338541">Mozilla Bug 338541</a> +<p id="display"></p> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 338541 **/ +function getName(aNode, f) +{ + return (aNode ? aNode.nodeName : "(null)"); +} + +function walkDOM() +{ + var walker = document.createTreeWalker($('content'), NodeFilter.SHOW_ELEMENT, null); + var output = ""; + while (walker.nextNode()) + { + output += getName(walker.currentNode) + "\n"; + } + output += "Final currentNode: " + getName(walker.currentNode); + is(output, "foo\nbar\nhtml:b\nqux\nbaz\nFinal currentNode: baz","treewalker returns correct nodeName"); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(walkDOM, ok); + +</script> +</pre> +<div id="content" style="display: none"> + <foo xmlns="http://example.com"> + <bar><html:b xmlns:html="http://www.w3.org/1999/xhtml"><qux/></html:b> + <baz/> + </bar> + </foo> +</div> +</body> +</html> + diff --git a/dom/base/test/test_bug338583.html b/dom/base/test/test_bug338583.html new file mode 100644 index 0000000000..4e50e4e330 --- /dev/null +++ b/dom/base/test/test_bug338583.html @@ -0,0 +1,666 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=338583 +--> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Test for Bug 338583</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +</head> +<body bgColor=white> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=338583">Mozilla Bug 338583</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Tests for Bug 338583 **/ + +// we test: +// 1) the EventSource behaviour +// 2) if the events are trusted +// 3) possible invalid eventsources +// 4) the close method when the object is just been used +// 5) access-control +// 6) the data parameter +// 7) delayed server responses + +// -- + + var gTestsHaveFinished = []; + + function setTestHasFinished(test_id) + { + if (gTestsHaveFinished[test_id]) { + return; + } + + gTestsHaveFinished[test_id] = true; + for (var i=0; i < gTestsHaveFinished.length; ++i) { + if (!gTestsHaveFinished[i]) { + return; + } + } + + SimpleTest.finish(); + } + + function runAllTests() { + // these tests run asynchronously, and they will take 8000 ms + var all_tests = [ + doTest1, doTest1_e, doTest1_f, doTest2, doTest3, doTest3_b, doTest3_c, doTest3_d, + doTest3_e, doTest3_f, doTest3_g, doTest3_h, doTest4, doTest4_b, + doTest5, doTest5_b, doTest5_c, doTest5_e, doTest6, doTest7 + ]; + + for (var test_id=0; test_id < all_tests.length; ++test_id) { + gTestsHaveFinished[test_id] = false; + var fn = all_tests[test_id]; + fn(test_id); + } + + setTimeout(function() { + for (var test_id=0; test_id < all_tests.length; ++test_id) { + if (!gTestsHaveFinished[test_id]) { + ok(false, "Test " + test_id + " took too long"); + setTestHasFinished(test_id); + } + } + }, 60000 * stress_factor); // all tests together are supposed to take less than 1 minute + } + + function fn_onmessage(e) { + if (e.currentTarget == e.target && e.target.hits != null) + e.target.hits['fn_onmessage']++; + } + + function fn_event_listener_message(e) { + if (e.currentTarget == e.target && e.target.hits != null) + e.target.hits['fn_event_listener_message']++; + } + + function fn_other_event_name(e) { + if (e.currentTarget == e.target && e.target.hits != null) + e.target.hits['fn_other_event_name']++; + } + + var gEventSourceObj1 = null, gEventSourceObj1_e, gEventSourceObj1_f; + var gEventSourceObj2 = null; + var gEventSourceObj3_a = null, gEventSourceObj3_b = null, + gEventSourceObj3_c = null, gEventSourceObj3_d = null, + gEventSourceObj3_e = null, gEventSourceObj3_f = null, + gEventSourceObj3_g = null, gEventSourceObj3_h = null; + var gEventSourceObj4_a = null, gEventSourceObj4_b = null; + var gEventSourceObj5_a = null, gEventSourceObj5_b = null, + gEventSourceObj5_c = null, gEventSourceObj5_d = null, + gEventSourceObj5_e = null, gEventSourceObj5_f = null; + var gEventSourceObj6 = null; + var gEventSourceObj7 = null; + var stress_factor; // used in the setTimeouts in order to help + // the test when running in slow machines + + function hasBeenHitFor1And2(obj, min) { + if (obj.hits['fn_onmessage'] < min || + obj.hits['fn_event_listener_message'] < min || + obj.hits['fn_other_event_name'] < min) + return false; + return true; + } + +// in order to test (1): +// a) if the EventSource constructor parameter is equal to its url attribute +// b) let its fn_onmessage, fn_event_listener_message, and fn_other_event_name functions listeners be hit four times each +// c) the close method (we expect readyState == CLOSED) +// d) the close method (we expect no message events anymore) +// e) use the default for withCredentials when passing dictionary arguments that don't explicitly set it +// f) if a 204 HTTP response closes (interrupts) connections. See bug 869432. + + function doTest1(test_id) { + gEventSourceObj1 = new EventSource("eventsource.resource"); + ok(gEventSourceObj1.url == "http://mochi.test:8888/tests/dom/base/test/eventsource.resource", "Test 1.a failed."); + ok(gEventSourceObj1.readyState == 0 || gEventSourceObj1.readyState == 1, "Test 1.a failed."); + + doTest1_b(test_id); + } + + function doTest1_b(test_id) { + gEventSourceObj1.hits = []; + gEventSourceObj1.hits['fn_onmessage'] = 0; + gEventSourceObj1.onmessage = fn_onmessage; + gEventSourceObj1.hits['fn_event_listener_message'] = 0; + gEventSourceObj1.addEventListener('message', fn_event_listener_message, true); + gEventSourceObj1.hits['fn_other_event_name'] = 0; + gEventSourceObj1.addEventListener('other_event_name', fn_other_event_name, true); + + // the eventsources.res always use a retry of 0.5 second, so for four hits a timeout of 6 seconds is enough + setTimeout(function(){ + bhits = hasBeenHitFor1And2(gEventSourceObj1, 4); + ok(bhits, "Test 1.b failed."); + + doTest1_c(test_id); + }, parseInt(6000*stress_factor)); + } + + function doTest1_c(test_id) { + gEventSourceObj1.close(); + ok(gEventSourceObj1.readyState == 2, "Test 1.c failed."); + + doTest1_d(test_id); + } + + function doTest1_d(test_id) { + gEventSourceObj1.hits['fn_onmessage'] = 0; + gEventSourceObj1.hits['fn_event_listener_message'] = 0; + gEventSourceObj1.hits['fn_other_event_name'] = 0; + + setTimeout(function(){ + bhits = hasBeenHitFor1And2(gEventSourceObj1, 1); + ok(!bhits, "Test 1.d failed."); + gEventSourceObj1.close(); + setTestHasFinished(test_id); + }, parseInt(2000*stress_factor)); + } + + function doTest1_e(test_id) { + try { + for (var options of [null, undefined, {}]) { + gEventSourceObj1_e = new EventSource("eventsource.resource", options); + is(gEventSourceObj1_e.withCredentials, false, "withCredentials should default to false"); + gEventSourceObj1_e.close(); + } + } catch (e) { + ok(false, "Test 1.e failed"); + } + setTestHasFinished(test_id); + } + + function doTest1_f(test_id) { + var called_on_error = false; + + gEventSourceObj1_f = new EventSource("file_bug869432.eventsource"); + gEventSourceObj1_f.onopen = function(e) { + ok(false, "Test 1.f failed: onopen was called"); + }; + gEventSourceObj1_f.onmessage = function(e) { + ok(false, "Test 1.f failed: onmessage was called"); + }; + gEventSourceObj1_f.onerror = function(e) { + if (called_on_error) { + ok(false, "Test 1.f failed: onerror was called twice"); + } + called_on_error = true; + ok(gEventSourceObj1_f.readyState == 2, "Test 1.f failed: onerror was called with readyState = " + gEventSourceObj1_f.readyState); + }; + + setTimeout(function() { // just to clean... + ok(called_on_error, "Test 1.f failed: onerror was not called"); + setTestHasFinished(test_id); + }, parseInt(5000*stress_factor)); + } + +// in order to test (2) +// a) set a eventsource that give the dom events messages +// b) expect trusted events + + function doTest2(test_id) { + var func = function(e) { + ok(e.isTrusted, "Test 2 failed"); + gEventSourceObj2.close(); + }; + + gEventSourceObj2 = new EventSource("eventsource.resource"); + gEventSourceObj2.onmessage = func; + + setTimeout(function() { // just to clean... + gEventSourceObj2.close(); + setTestHasFinished(test_id); + }, parseInt(5000*stress_factor)); + } + +// in order to test (3) +// a) XSite domain error test +// b) protocol file:// test +// c) protocol javascript: test +// d) wrong Content-Type test +// e) bad http response code test +// f) message eventsource without a data test +// g) DNS error +// h) EventSource which last message doesn't end with an empty line. See bug 710546 + + function doTest3(test_id) { + gEventSourceObj3_a = new EventSource("http://example.org/tests/dom/base/test/eventsource.resource"); + + gEventSourceObj3_a.onmessage = fn_onmessage; + gEventSourceObj3_a.hits = []; + gEventSourceObj3_a.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_a.hits['fn_onmessage'] == 0, "Test 3.a failed"); + gEventSourceObj3_a.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_b(test_id) { + // currently no support yet for local files for b2g/Android mochitest, see bug 838726 + if (navigator.appVersion.indexOf("Android") != -1 || SpecialPowers.Services.appinfo.name == "B2G") { + setTestHasFinished(test_id); + return; + } + + var xhr = new XMLHttpRequest; + xhr.open("GET", "/dynamic/getMyDirectory.sjs", false); + xhr.send(); + var basePath = xhr.responseText; + + gEventSourceObj3_b = new EventSource("file://" + basePath + "eventsource.resource"); + + gEventSourceObj3_b.onmessage = fn_onmessage; + gEventSourceObj3_b.hits = []; + gEventSourceObj3_b.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_b.hits['fn_onmessage'] == 0, "Test 3.b failed"); + gEventSourceObj3_b.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function jsEvtSource() + { + return "event: message\n" + + "data: 1\n\n"; + } + + function doTest3_c(test_id) { + gEventSourceObj3_c = new EventSource("javascript: return jsEvtSource()"); + + gEventSourceObj3_c.onmessage = fn_onmessage; + gEventSourceObj3_c.hits = []; + gEventSourceObj3_c.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_c.hits['fn_onmessage'] == 0, "Test 3.c failed"); + gEventSourceObj3_c.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_d(test_id) { + gEventSourceObj3_d = new EventSource("badContentType.eventsource"); + + gEventSourceObj3_d.onmessage = fn_onmessage; + gEventSourceObj3_d.hits = []; + gEventSourceObj3_d.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_d.hits['fn_onmessage'] == 0, "Test 3.d failed"); + gEventSourceObj3_d.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_e(test_id) { + gEventSourceObj3_e = new EventSource("badHTTPResponseCode.eventsource"); + + gEventSourceObj3_e.onmessage = fn_onmessage; + gEventSourceObj3_e.hits = []; + gEventSourceObj3_e.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_e.hits['fn_onmessage'] == 0, "Test 3.e failed"); + gEventSourceObj3_e.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_f(test_id) { + gEventSourceObj3_f = new EventSource("badMessageEvent.eventsource"); + + gEventSourceObj3_f.onmessage = fn_onmessage; + gEventSourceObj3_f.hits = []; + gEventSourceObj3_f.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_f.hits['fn_onmessage'] == 0, "Test 3.f failed"); + gEventSourceObj3_f.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function fnInvalidNCName() { + fnInvalidNCName.hits++; + } + + function doTest3_g(test_id) { + gEventSourceObj3_g = new EventSource("http://hdfskjghsbg.jtiyoejowe.dafsgbhjab.com"); + + gEventSourceObj3_g.onmessage = fn_onmessage; + gEventSourceObj3_g.hits = []; + gEventSourceObj3_g.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_g.hits['fn_onmessage'] == 0, "Test 3.g failed"); + gEventSourceObj3_g.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function fnMessageListenerTest3h(e) { + fnMessageListenerTest3h.msg_ok = (fnMessageListenerTest3h.msg_ok && e.data == "ok"); + fnMessageListenerTest3h.id_ok = (fnMessageListenerTest3h.id_ok && e.lastEventId == ""); + } + + function doTest3_h(test_id) { + gEventSourceObj3_h = new EventSource("badMessageEvent2.eventsource"); + + gEventSourceObj3_h.addEventListener('message', fnMessageListenerTest3h, true); + fnMessageListenerTest3h.msg_ok = true; + fnMessageListenerTest3h.id_ok = true; + + gEventSourceObj3_h.onmessage = fn_onmessage; + gEventSourceObj3_h.hits = []; + gEventSourceObj3_h.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj3_h.hits['fn_onmessage'] > 1, "Test 3.h.1 failed"); + if (gEventSourceObj3_h.hits['fn_onmessage'] > 1) { + ok(fnMessageListenerTest3h.msg_ok, "Test 3.h.2 failed"); + ok(fnMessageListenerTest3h.id_ok, "Test 3.h.3 failed"); + } + gEventSourceObj3_h.close(); + setTestHasFinished(test_id); + }, parseInt(6000*stress_factor)); + } + +// in order to test (4) +// a) close the object when it is in use, which is being processed and that is expected +// to dispatch more eventlisteners +// b) remove an eventlistener in use + + function fn_onmessage4_a(e) + { + if (e.data > gEventSourceObj4_a.lastData) + gEventSourceObj4_a.lastData = e.data; + if (e.data == 2) + gEventSourceObj4_a.close(); + } + + function fn_onmessage4_b(e) + { + if (e.data > gEventSourceObj4_b.lastData) + gEventSourceObj4_b.lastData = e.data; + if (e.data == 2) + gEventSourceObj4_b.removeEventListener('message', fn_onmessage4_b, true); + } + + function doTest4(test_id) { + gEventSourceObj4_a = new EventSource("forRemoval.resource"); + gEventSourceObj4_a.lastData = 0; + gEventSourceObj4_a.onmessage = fn_onmessage4_a; + + setTimeout(function() { + ok(gEventSourceObj4_a.lastData == 2, "Test 4.a failed"); + gEventSourceObj4_a.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest4_b(test_id) + { + gEventSourceObj4_b = new EventSource("forRemoval.resource"); + gEventSourceObj4_b.lastData = 0; + gEventSourceObj4_b.addEventListener('message', fn_onmessage4_b, true); + + setTimeout(function() { + ok(gEventSourceObj4_b.lastData == 2, "Test 4.b failed"); + gEventSourceObj4_b.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + +// in order to test (5) +// a) valid access-control xsite request +// b) invalid access-control xsite request +// c) valid access-control xsite request on a restricted page with credentials +// d) valid access-control xsite request on a restricted page without credentials +// e) valid access-control xsite request on a restricted page when the parameter withCredentials is a getter +// f) valid access-control xsite request on a restricted page when the parameter withCredentials is missing + + function doTest5(test_id) + { + gEventSourceObj5_a = new EventSource("http://example.org/tests/dom/base/test/accesscontrol.resource"); + + gEventSourceObj5_a.onmessage = fn_onmessage; + gEventSourceObj5_a.hits = []; + gEventSourceObj5_a.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_a.hits['fn_onmessage'] != 0, "Test 5.a failed"); + gEventSourceObj5_a.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest5_b(test_id) + { + gEventSourceObj5_b = new EventSource("http://example.org/tests/dom/base/test/invalid_accesscontrol.resource"); + + gEventSourceObj5_b.onmessage = fn_onmessage; + gEventSourceObj5_b.hits = []; + gEventSourceObj5_b.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_b.hits['fn_onmessage'] == 0, "Test 5.b failed"); + gEventSourceObj5_b.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest5_c(test_id) + { + // credentials using the auth cache + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + // also, test mixed mode UI + xhr.open("GET", "https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.c"); + + gEventSourceObj5_c = new EventSource("https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc", + { withCredentials: true } ); + ok(gEventSourceObj5_c.withCredentials, "Wrong withCredentials in test 5.c"); + + gEventSourceObj5_c.onmessage = function(e) { + ok(e.origin == "https://example.com", "Wrong Origin in test 5.c"); + fn_onmessage(e); + }; + gEventSourceObj5_c.hits = []; + gEventSourceObj5_c.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_c.hits['fn_onmessage'] > 0, "Test 5.c failed"); + gEventSourceObj5_c.close(); + doTest5_d(test_id); + }, parseInt(3000*stress_factor)); + }; + } + + function doTest5_d(test_id) + { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open("GET", "https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.d"); + + gEventSourceObj5_d = new EventSource("https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc"); + ok(!gEventSourceObj5_d.withCredentials, "Wrong withCredentials in test 5.d"); + + gEventSourceObj5_d.onmessage = function(e) { + ok(e.origin == "https://example.com", "Wrong Origin in test 5.d"); + fn_onmessage(e); + }; + gEventSourceObj5_d.hits = []; + gEventSourceObj5_d.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_d.hits['fn_onmessage'] == 0, "Test 5.d failed"); + gEventSourceObj5_d.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + }; + } + + function doTest5_e(test_id) + { + // credentials using the auth cache + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open("GET", "http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.e"); + + gEventSourceObj5_e = new EventSource("http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc", + { get withCredentials() { return true; } } ); + ok(gEventSourceObj5_e.withCredentials, "Wrong withCredentials in test 5.e"); + + gEventSourceObj5_e.onmessage = function(e) { + ok(e.origin == "http://example.org", "Wrong Origin in test 5.e"); + fn_onmessage(e); + }; + gEventSourceObj5_e.hits = []; + gEventSourceObj5_e.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_e.hits['fn_onmessage'] > 0, "Test 5.e failed"); + gEventSourceObj5_e.close(); + doTest5_f(test_id); + }, parseInt(5000*stress_factor)); + }; + } + + function doTest5_f(test_id) + { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open("GET", "http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.f"); + + gEventSourceObj5_f = new EventSource("http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc", + { }); + ok(!gEventSourceObj5_f.withCredentials, "Wrong withCredentials in test 5.f"); + + gEventSourceObj5_f.onmessage = function(e) { + ok(e.origin == "http://example.org", "Wrong Origin in test 5.f"); + fn_onmessage(e); + }; + gEventSourceObj5_f.hits = []; + gEventSourceObj5_f.hits['fn_onmessage'] = 0; + + setTimeout(function() { + ok(gEventSourceObj5_f.hits['fn_onmessage'] == 0, "Test 5.f failed"); + gEventSourceObj5_f.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + }; + } + + function doTest6(test_id) + { + gEventSourceObj6 = new EventSource("somedatas.resource"); + var fn_somedata = function(e) { + if (fn_somedata.expected == 0) { + ok(e.data == "123456789\n123456789123456789\n123456789123456789123456789123456789\n 123456789123456789123456789123456789123456789123456789123456789123456789\nçãá\"\'@`~Ý Ḿyyyy", + "Test 6.a failed"); + } else if (fn_somedata.expected == 1) { + ok(e.data == " :xxabcdefghij\nçãá\"\'@`~Ý Ḿyyyy : zz", + "Test 6.b failed"); + gEventSourceObj6.close(); + } else { + ok(false, "Test 6 failed (unexpected message event)"); + } + fn_somedata.expected++; + } + fn_somedata.expected = 0; + gEventSourceObj6.onmessage = fn_somedata; + + setTimeout(function() { + gEventSourceObj6.close(); + setTestHasFinished(test_id); + }, parseInt(2500*stress_factor)); + } + + function doTest7(test_id) + { + gEventSourceObj7 = new EventSource("delayedServerEvents.sjs"); + gEventSourceObj7.msg_received = []; + gEventSourceObj7.onmessage = function(e) + { + e.target.msg_received.push(e.data); + } + + setTimeout(function() { + gEventSourceObj7.close(); + + ok(gEventSourceObj7.msg_received[0] == "" && + gEventSourceObj7.msg_received[1] == "delayed1" && + gEventSourceObj7.msg_received[2] == "delayed2", "Test 7 failed"); + + document.getElementById('waitSpan').innerHTML = ''; + setTestHasFinished(test_id); + }, parseInt(8000*stress_factor)); + } + + function doTest() + { + // Allow all cookies, then run the actual test + SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, + function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], + doTestCallback); + }); + } + + function doTestCallback() + { + + // we get a good stress_factor by testing 10 setTimeouts and some float + // arithmetic taking my machine as stress_factor==1 (time=589) + + var begin_time = (new Date()).getTime(); + + var f = function() { + for (var j=0; j<f.i; ++j) + eval("Math.log(Math.atan(Math.sqrt(Math.pow(3.1415, 13.1415))/0.0007))"); + if (f.i < 10) { + f.i++; + setTimeout(f, 10 + 10*f.i); + } else { + stress_factor = ((new Date()).getTime()-begin_time)*1/589; + stress_factor *= 1.50; // also, a margin of 50% + + runAllTests(); + } + } + f.i = 0; + + setTimeout(f, 10); + } + + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("untriaged"); + addLoadEvent(doTest); + +</script> +</pre> + <span id=waitSpan>Wait please...</span> +</body> +</html> + diff --git a/dom/base/test/test_bug338679.html b/dom/base/test/test_bug338679.html new file mode 100644 index 0000000000..ac34bfc015 --- /dev/null +++ b/dom/base/test/test_bug338679.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=338679 +--> +<head> +<title>Bug 338679: correct reporting of newValue/prevValue in + DOMAttrModified events</title> +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=338679">Bug + 338679: correct reporting of newValue/prevValue in + DOMAttrModified events</a> + +<div id="test" style="width:20em"></div> + +<script> +var testDiv = document.getElementById("test"); +var e_new, e_prev = testDiv.getAttribute("style"); +var phase, recursive = false; + +/* driver */ +var tests = [ test_1, test_2, test_3 ]; +var i = 0; +function nextTest() { + if (i < tests.length) { + phase = tests[i]; + i++; + phase(); + } else { + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +testDiv.addEventListener("DOMAttrModified", attr_modified, false); +nextTest(); + +/* event handler */ +function attr_modified(ev) { + is(ev.newValue, e_new, + phase.name + (recursive ? " recursive" : "") + ": newValue"); + is(ev.prevValue, e_prev, + phase.name + (recursive ? " recursive" : "") + ": prevValue"); + + e_prev = e_new; + if (!recursive) { + recursive = true; + e_new = "width: 0px;"; + testDiv.style.width = "0"; + } else { + recursive = false; + setTimeout(nextTest, 0); + } +} + +/* tests */ +function test_1() { + e_new = "width: auto;"; + testDiv.style.width = "auto"; +} + +function test_2() { + e_new = "width: 15%;"; + testDiv.style.width = "15%"; +} + +function test_3() { + window.getComputedStyle(testDiv, null).width; // force style resolution + e_new = "width: inherit;"; + testDiv.style.width = "inherit"; +} +</script> +</body> +</html> diff --git a/dom/base/test/test_bug339494.html b/dom/base/test/test_bug339494.html new file mode 100644 index 0000000000..b44bd75622 --- /dev/null +++ b/dom/base/test/test_bug339494.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=339494 +--> +<head> + <title>Test for Bug 339494</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=339494">Mozilla Bug 339494</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="d"></div> + <div id="s"></div> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + /** Test for Bug 339494 **/ + + var d = document.getElementById("d"); + + d.setAttribute("hhh", "testvalue"); + + document.addEventListener("DOMAttrModified", removeItAgain, false); + d.removeAttribute("hhh"); + document.removeEventListener("DOMAttrModified", removeItAgain, false); + + function removeItAgain() + { + ok(!d.hasAttribute("hhh"), "Value check 1", + "There should be no value"); + isnot(d.getAttribute("hhh"), "testvalue", "Value check 2"); + document.removeEventListener("DOMAttrModified", removeItAgain, false); + d.removeAttribute("hhh"); + ok(true, "Reachability", "We shouldn't have crashed"); + } + + var s = document.getElementById("s"); + + s.setAttribute("ggg", "testvalue"); + + document.addEventListener("DOMAttrModified", compareVal, false); + s.setAttribute("ggg", "othervalue"); + document.removeEventListener("DOMAttrModified", compareVal, false); + + function compareVal() + { + ok(s.hasAttribute("ggg"), "Value check 3", + "There should be a value"); + isnot(s.getAttribute("ggg"), "testvalue", "Value check 4"); + is(s.getAttribute("ggg"), "othervalue", "Value check 5"); + } + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug339494.xhtml b/dom/base/test/test_bug339494.xhtml new file mode 100644 index 0000000000..6a028f1559 --- /dev/null +++ b/dom/base/test/test_bug339494.xhtml @@ -0,0 +1,60 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=339494 +--> +<head> + <title>Test for Bug 339494</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=339494">Mozilla Bug 339494</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="d" /> + <div id="s" /> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 339494 **/ + + var d = document.getElementById("d"); + + d.setAttribute("hhh", "testvalue"); + + document.addEventListener("DOMAttrModified", removeItAgain, false); + d.removeAttribute("hhh"); + document.removeEventListener("DOMAttrModified", removeItAgain, false); + + function removeItAgain() + { + ok(!d.hasAttribute("hhh"), "Value check 1", + "There should be no value"); + isnot(d.getAttribute("hhh"), "testvalue", "Value check 2"); + document.removeEventListener("DOMAttrModified", removeItAgain, false); + d.removeAttribute("hhh"); + ok(true, "Reachability", "We shouldn't have crashed"); + } + + var s = document.getElementById("s"); + + s.setAttribute("ggg", "testvalue"); + + document.addEventListener("DOMAttrModified", compareVal, false); + s.setAttribute("ggg", "othervalue"); + document.removeEventListener("DOMAttrModified", compareVal, false); + + function compareVal() + { + ok(s.hasAttribute("ggg"), "Value check 3", + "There should be a value"); + isnot(s.getAttribute("ggg"), "testvalue", "Value check 4"); + is(s.getAttribute("ggg"), "othervalue", "Value check 5"); + } + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug340571.html b/dom/base/test/test_bug340571.html new file mode 100644 index 0000000000..c0289e9a9d --- /dev/null +++ b/dom/base/test/test_bug340571.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=340571 +--> +<head> + <title>Test for Bug 340571</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=340571">Mozilla Bug 340571</a> +<p id="display"></p> +<div><select id="sel"></select></div> +<script type="application/javascript"> +ok(!document.getBoxObjectFor, "Detecting getBoxObjectFor"); +try { + document.getBoxObjectFor(document.body); + ok(false, "getBoxObjectFor succeeded"); +} catch (e) { + ok(true, "getBoxObjectFor succeeded"); +} + +var sel = document.getElementById("sel"); +ok(!sel.boxObject, "Getting boxObject"); +</script> +</body> +</html> diff --git a/dom/base/test/test_bug343596.html b/dom/base/test/test_bug343596.html new file mode 100644 index 0000000000..567bef491c --- /dev/null +++ b/dom/base/test/test_bug343596.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=343596 +--> +<head> + <title>Test for Bug 343596</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=343596">Mozilla Bug 343596</a> +<p id="display"></p> +<script id="foo"></script> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 343596 **/ + +SimpleTest.waitForExplicitFinish(); + +/** Cut error handling, because we're going to throw on purpose**/ +var errorHandler = window.onerror; +window.onerror = null; + + +try{ + // Insert text into an empty script node that will cause a syntax error. + document.getElementById("foo").appendChild(document.createTextNode("(")); +} +catch(ex){ + // Note that this catch block does not execute. + ok(false, "this catch block should not execute"); +} + +setTimeout(function(){ +ok(true,"setTimeout still executes after bogus script insertion"); +window.error = errorHandler; +SimpleTest.finish();}, 0); + + + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug345339.html b/dom/base/test/test_bug345339.html new file mode 100644 index 0000000000..095696762f --- /dev/null +++ b/dom/base/test/test_bug345339.html @@ -0,0 +1,85 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=345339 +--> +<head> + <title>Test for Bug 345339</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345339">Mozilla Bug 345339</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + <iframe id="testframe" + src="http://mochi.test:8888/tests/dom/base/test/345339_iframe.html"> + </iframe> +<pre id="test"> +<script class="testbody" type="text/javascript;version=1.7"> +/** Test for Bug 345339 **/ +SimpleTest.waitForExplicitFinish(); + +const testData = "Test data\n"; +let file = new File([testData], + "345339_test.file", + { type: "text/plain" }); + +function afterLoad() { + var iframeDoc = $("testframe").contentDocument; + + /* change all the form controls */ + iframeDoc.getElementById("select").selectedIndex = 1; + iframeDoc.getElementById("radio2").checked = true; + iframeDoc.getElementById("password").value = "123456"; + iframeDoc.getElementById("hidden").value = "gecko"; + + SpecialPowers.wrap(iframeDoc).getElementById("file").mozSetFileArray([file]); + + /* Reload the page */ + $("testframe").setAttribute("onload", "afterReload()"); + iframeDoc.location.reload(); +} + +addLoadEvent(afterLoad); + +function afterReload() { + var iframeDoc = $("testframe").contentDocument; + + is(iframeDoc.getElementById("select").selectedIndex, 1, + "select element selected index preserved"); + is(iframeDoc.getElementById("radio1").checked, false, + "radio button #1 value preserved"); + is(iframeDoc.getElementById("radio2").checked, true, + "radio button #2 value preserved"); + isnot(iframeDoc.getElementById("password").value, "123456", + "password field value forgotten"); + is(iframeDoc.getElementById("hidden").value, "gecko", + "hidden field value preserved"); + + // The new file object isn't ===, but it's extensionally equal: + let newFile = iframeDoc.getElementById("file").files[0]; + for (let prop of ["name", "lastModified", "size", "type"]) { + is(newFile[prop], file[prop], + "file field " + prop + " property preserved"); + } + let reader = new FileReader(); + reader.onloadend = function() { + SimpleTest.finish(); + }; + reader.onload = function() { + is(reader.result, testData, + "file field contents preserved") + }; + reader.onerror = function() { + is(reader.error, null, + "FileReader error"); + }; + reader.readAsText(newFile); +} +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug346485.html b/dom/base/test/test_bug346485.html new file mode 100644 index 0000000000..8db0fc67e2 --- /dev/null +++ b/dom/base/test/test_bug346485.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=346485 +--> +<head> + <title>Test for Bug 346485</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=346485">Mozilla Bug 346485</a> +<p id="display"></p> +<div id="content" style="display: none"> + <input id='a'> + <input id='b'> + <output id='o' for='a b'></output> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 346485 **/ + +/** + * This test is testing DOMTokenList used by the output element. + */ + +function checkHtmlFor(htmlFor, list, msg) { + var length = htmlFor.length; + is(length, list.length, htmlFor + ": incorrect htmlFor length (" + msg + ")"); + for (var i = 0; i < length; ++i) { + is(htmlFor[i], list[i], htmlFor + ": wrong element at " + i + " (" + msg + ")"); + } +} + +var o = document.getElementById('o'); + +is(String(o.htmlFor), 'a b', + "htmlFor IDL attribute should reflect for content attribute"); + +is(o.htmlFor.value, 'a b', + "value should return the underlying string"); + +is(o.htmlFor.length, 2, "Size should be '2'"); + +ok(o.htmlFor.contains('a'), "It should contain 'a' token'"); +ok(!o.htmlFor.contains('c'), "It should not contain 'c' token"); + +is(o.htmlFor.item(0), 'a', "First item is 'a' token'"); +is(o.htmlFor.item(42), null, "Out-of-range should return null"); + +o.htmlFor.add('c'); +checkHtmlFor(o.htmlFor, ['a', 'b', 'c'], "'c' token should have been added"); + +o.htmlFor.add('a'); +checkHtmlFor(o.htmlFor, ['a', 'b', 'c'], "Nothing should have changed"); + +o.htmlFor.remove('a'); +checkHtmlFor(o.htmlFor, ['b', 'c'], "'a' token should have been removed"); + +o.htmlFor.remove('d'); +checkHtmlFor(o.htmlFor, ['b', 'c'], "Nothing should have been removed"); + +o.htmlFor.toggle('a'); +checkHtmlFor(o.htmlFor, ['b', 'c', 'a'], "'a' token should have been added"); + +o.htmlFor.toggle('b'); +checkHtmlFor(o.htmlFor, ['c', 'a'], "Nothing should have changed"); + +o.htmlFor.value = "foo bar"; +checkHtmlFor(o.htmlFor, ['foo', 'bar'], "The underlying string should have changed"); +ok(o.htmlFor.contains('foo'), "It should contain 'foo'"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug352728.html b/dom/base/test/test_bug352728.html new file mode 100644 index 0000000000..faf2f681a8 --- /dev/null +++ b/dom/base/test/test_bug352728.html @@ -0,0 +1,139 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=352728 +--> +<head> + <title>Test for Bug 352728</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=352728">Mozilla Bug 352728</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 352728 **/ + +function checkTypes(aNode, aNodeType, aTypeArray) +{ + for (var i = 0; i < aTypeArray.length; ++i) { + ok(aNode instanceof aTypeArray[i], aNodeType + " type test " + i, + aNodeType + " should be a " + aTypeArray[i]); + } +} + +function checkInterfaces(aNode, aNodeType, aInterfaceArray) +{ + for (var i = 0; i < aInterfaceArray.length; ++i) { + ok(aNode instanceof SpecialPowers.Ci[aInterfaceArray[i]], + aNodeType + " interface test " + i, + aNodeType + " should be a " + aInterfaceArray[i]); + } +} + +function testCharacterData(aNode, aText) +{ + is(aNode.length, aText.length, "Text length should match"); + is(aNode.data, aText, "Text content should match"); + is(aNode.nodeValue, aText, "Check nodeValue"); + is(aNode.localName, undefined, "Check localName") + is(aNode.namespaceURI, undefined, "Check namespaceURI"); +} + +function testComment(aText) +{ + try { + var comment = document.createComment(aText); + var types = [ Comment, CharacterData, Node ]; + checkTypes(comment, "comment", types); + + var interfaces = [ "nsIDOMComment", "nsIDOMCharacterData", "nsIDOMNode", + "nsIDOMEventTarget" ]; + checkInterfaces(comment, "comment", interfaces); + + testCharacterData(comment, aText); + is(comment.nodeName, "#comment", "Check nodeName"); + is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType"); + } catch (e) { + ok(0, "Correct functioning of comment stuff", "something broke: " + e); + } +} + +function testCDATASection(aText, aShouldSucceed) +{ + try { + var cdataSection = document.createCDATASection(aText); + ok(0, "Invalid CDATA section creation", + "Shouldn't create CDATA sections in HTML"); + } catch (e) { + is(e.name, "NotSupportedError", "Check exception"); + is(e.code, DOMException.NOT_SUPPORTED_ERR, "Check exception code"); + } +} + +function testPI(aTarget, aData, aShouldSucceed, aReason) +{ + try { + var pi = document.createProcessingInstruction(aTarget, aData); + var types = [ ProcessingInstruction, Node ]; + checkTypes(pi, "processing instruction", types); + + var interfaces = [ "nsIDOMProcessingInstruction", "nsIDOMNode", + "nsIDOMEventTarget" ]; + checkInterfaces(pi, "processing instruction", interfaces); + + is(pi.target, aTarget, "Check target"); + is(pi.data, aData, "Check data"); + is(pi.nodeName, aTarget, "Check nodeName"); + is(pi.nodeValue, aData, "Check nodeValue"); + is(pi.localName, undefined, "Check localName") + is(pi.namespaceURI, undefined, "Check namespaceURI"); + + is(pi.nodeType, Node.PROCESSING_INSTRUCTION_NODE, "Check nodeType"); + + if (!aShouldSucceed) { + ok(false, "Invalid processing instruction creation", aReason); + } + } catch (e) { + if (aShouldSucceed) { + ok(false, "Correct functioning of processing instruction stuff", + "something broke: " + e); + } else { + is(e.name, "InvalidCharacterError", "Check exception"); + is(e.code, DOMException.INVALID_CHARACTER_ERR, "Check exception code"); + } + } +} + +testComment("Some text"); +testComment("Some text with a '-' in it"); +testComment("Some text with a '-' and a '-' and another '-'"); +testComment("Some text -- this should create a node!"); +testComment("<!-- This is an HTML comment -->"); + +testCDATASection("Some text", true); +testCDATASection("Some text with a '?' in it", true); +testCDATASection("Some text with a '>' in it", true); +testCDATASection("Some text with a '?' and a '>' in it", true); +testCDATASection("Some text with a '? >' in it", true); +testCDATASection("Some text -- ?> this should be ok", true); +testCDATASection("Some text ]]> this should not create a node!", false); + +testPI("foo", "bar", true); +testPI("foo:bar", "baz", true); +testPI("foo", "bar?", true); +testPI("foo", "bar>", true); +testPI("foo", "bar? >", true); +testPI("<aaa", "bar", false, "Target should not contain '<'"); +testPI("aaa>", "bar", false, "Target should not contain '>'"); +testPI("aa?", "bar", false, "Target should not contain '?'"); +testPI("foo", "bar?>", false, "Data should not contain '?>'"); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug352728.xhtml b/dom/base/test/test_bug352728.xhtml new file mode 100644 index 0000000000..6f85810d61 --- /dev/null +++ b/dom/base/test/test_bug352728.xhtml @@ -0,0 +1,187 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=352728 +--> +<head> + <title>Test for Bug 352728</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=352728">Mozilla Bug 352728</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<!-- First make sure that a script consisting of multiple CDATA sections is + even supported --> +<script class="testbody" type="text/javascript"> + var cdataTest1 = false; + var cdataTest2 = false; + var cdataTest3 = false; +</script> + +<script class="testbody" type="text/javascript"> +<![CDATA[ + cdataTest1 = true; +]]> + cdataTest2 = true; +<![CDATA[ + cdataTest3 = true; +]]> +</script> + +<script class="testbody" type="text/javascript"> + is(cdataTest1, true, "Check first CDATA section"); + is(cdataTest2, true, "Check in between CDATA sections"); + is(cdataTest3, true, "Check second CDATA section"); +</script> + +<script class="testbody" type="text/javascript"> +<![CDATA[ + +/** Test for Bug 352728 **/ +function checkTypes(aNode, aNodeType, aTypeArray) +{ + for (var i = 0; i < aTypeArray.length; ++i) { + ok(aNode instanceof aTypeArray[i], aNodeType + " type test " + i, + aNodeType + " should be a " + aTypeArray[i]); + } +} + +function checkInterfaces(aNode, aNodeType, aInterfaceArray) +{ + for (var i = 0; i < aInterfaceArray.length; ++i) { + ok(aNode instanceof SpecialPowers.Ci[aInterfaceArray[i]], + aNodeType + " interface test " + i, + aNodeType + " should be a " + aInterfaceArray[i]); + } +} + +function testCharacterData(aNode, aText) +{ + is(aNode.length, aText.length, "Text length should match"); + is(aNode.data, aText, "Text content should match"); + is(aNode.nodeValue, aText, "Check nodeValue"); + is(aNode.localName, undefined, "Check localName") + is(aNode.namespaceURI, undefined, "Check namespaceURI"); +} + +function testComment(aText) +{ + try { + var comment = document.createComment(aText); + var types = [ Comment, CharacterData, Node ]; + checkTypes(comment, "comment", types); + + var interfaces = [ "nsIDOMComment", "nsIDOMCharacterData", "nsIDOMNode", + "nsIDOMEventTarget" ]; + checkInterfaces(comment, "comment", interfaces); + + testCharacterData(comment, aText); + is(comment.nodeName, "#comment", "Check nodeName"); + is(comment.nodeType, Node.COMMENT_NODE, "Check nodeType"); + } catch (e) { + ok(0, "Correct functioning of comment stuff", "something broke: " + e); + } +} + +function testCDATASection(aText, aShouldSucceed) +{ + try { + var cdataSection = document.createCDATASection(aText); + var types = [ CDATASection, CharacterData, Node ]; + checkTypes(cdataSection, "CDATA section", types); + + var interfaces = [ "nsIDOMCDATASection", "nsIDOMCharacterData", + "nsIDOMNode", "nsIDOMEventTarget" ]; + checkInterfaces(cdataSection, "CDATA section", interfaces); + + testCharacterData(cdataSection, aText); + is(cdataSection.nodeName, "#cdata-section", "Check nodeName"); + is(cdataSection.nodeType, Node.CDATA_SECTION_NODE, "Check nodeType"); + + if (!aShouldSucceed) { + ok(0, "Invalid CDATA section creation", +]]> + "Shouldn't create CDATA section with embedded \"]]>\""); +<![CDATA[ + } + } catch (e) { + if (aShouldSucceed) { + ok(0, "Correct functioning of CDATA section stuff", + "something broke: " + e); + } else { + is(e.name, "InvalidCharacterError", "Check exception"); + is(e.code, DOMException.INVALID_CHARACTER_ERR, "Check exception code"); + } + } +} + +function testPI(aTarget, aData, aShouldSucceed, aReason) +{ + try { + var pi = document.createProcessingInstruction(aTarget, aData); + var types = [ ProcessingInstruction, Node ]; + checkTypes(pi, "processing instruction", types); + + var interfaces = [ "nsIDOMProcessingInstruction", "nsIDOMNode", + "nsIDOMEventTarget" ]; + checkInterfaces(pi, "processing instruction", interfaces); + + is(pi.target, aTarget, "Check target"); + is(pi.data, aData, "Check data"); + is(pi.nodeName, aTarget, "Check nodeName"); + is(pi.nodeValue, aData, "Check nodeValue"); + is(pi.localName, undefined, "Check localName") + is(pi.namespaceURI, undefined, "Check namespaceURI"); + + is(pi.nodeType, Node.PROCESSING_INSTRUCTION_NODE, "Check nodeType"); + + if (!aShouldSucceed) { + ok(0, "Invalid processing instruction creation", aReason); + } + } catch (e) { + if (aShouldSucceed) { + ok(0, "Correct functioning of processing instruction stuff", + "something broke: " + e); + } else { + is(e.name, "InvalidCharacterError", "Check exception"); + is(e.code, DOMException.INVALID_CHARACTER_ERR, "Check exception code"); + } + } +} + +testComment("Some text"); +testComment("Some text with a '-' in it"); +testComment("Some text with a '-' and a '-' and another '-'"); +testComment("Some text -- this should create a node!"); +testComment("<!-- This is an HTML comment -->"); + +testCDATASection("Some text", true); +testCDATASection("Some text with a '?' in it", true); +testCDATASection("Some text with a '>' in it", true); +testCDATASection("Some text with a '?' and a '>' in it", true); +testCDATASection("Some text with a '? >' in it", true); +testCDATASection("Some text -- ?> this should be ok", true); +]]> +testCDATASection("Some text ]]> this should not create a node!", false); + +<![CDATA[ + +testPI("foo", "bar", true); +testPI("foo:bar", "baz", true); +testPI("foo", "bar?", true); +testPI("foo", "bar>", true); +testPI("foo", "bar? >", true); +testPI("<aaa", "bar", false, "Target should not contain '<'"); +testPI("aaa>", "bar", false, "Target should not contain '>'"); +testPI("aa?", "bar", false, "Target should not contain '?'"); +testPI("foo", "bar?>", false, "Data should not contain '?>'"); +]]> +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug353334.html b/dom/base/test/test_bug353334.html new file mode 100644 index 0000000000..0f0acd4236 --- /dev/null +++ b/dom/base/test/test_bug353334.html @@ -0,0 +1,67 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=353334 +--> +<head> + <title>Test for Bug 353334</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script>var x = "PASS"</script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=353334">Mozilla Bug 353334</a> +<p id="display"> +<iframe id="one"></iframe> +<object id="two" data="about:blank"></object> +<iframe id="three" src="data:text/html,<body>test</body>"></iframe> +<object id="four" data="data:text/html,<body>test</body>"></object> +<iframe id="five" src="javascript:parent.x"></iframe> +<object id="six" data="javascript:x"></object> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 353334 **/ +SimpleTest.waitForExplicitFinish(); + +function doPrincipalTest(id) { + var doc = SpecialPowers.wrap($(id).contentDocument); + + isnot(doc.nodePrincipal, undefined, "Should have a principal"); + isnot(doc.nodePrincipal, null, "Should have a non-null principal"); + is(doc.nodePrincipal.origin, SpecialPowers.wrap(document).nodePrincipal.origin, + "Wrong principal for document in node with id='" + id + "'"); +} + +function doContentTest(id) { + is($(id).contentDocument.documentElement.textContent, "PASS", + "Script executed in wrong context in node with id='" + id + "'"); +} + +function checkPrincipal() { + ok(SpecialPowers.call_Instanceof(SpecialPowers.wrap(document).nodePrincipal, SpecialPowers.Ci.nsIPrincipal), + "Should be a principal"); +} + +addLoadEvent(function() { + checkPrincipal(); + + for (var i of [ "one", "two", "three", "four" ]) { + doPrincipalTest(i); + } + + for (i of [ "five", "six" ]) { + doContentTest(i); + } + + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug355026.html b/dom/base/test/test_bug355026.html new file mode 100644 index 0000000000..70237dc63e --- /dev/null +++ b/dom/base/test/test_bug355026.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test from Adam Guthrie. + +https://bugzilla.mozilla.org/show_bug.cgi?id=355026 +--> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=355026">Mozilla Bug 355026</a> +<div style="display: none" id="lengthtest"> +</div> +<pre id="test"> +<script type="text/javascript"> + + var foo = document.createElement("div"); + foo.appendChild(document.createElement("div")); + var children = foo.getElementsByTagName("div"); + + is(children.length, 1, "After appending a child div to a div, div.length should be 1."); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug357450.html b/dom/base/test/test_bug357450.html new file mode 100644 index 0000000000..9b2f56fc70 --- /dev/null +++ b/dom/base/test/test_bug357450.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=357450 +--> + +<head> + <title>Test for Bug 357450</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="file_bug357450.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style type="text/css"> + + </style> +</head> + +<body> + +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=357450" + target="_blank" >Mozilla Bug 357450</a> + +<p id="display"></p> +<span class="classtest">hmm</span> +<span class="classtest">hmm</span> +<div id="content" style="display: block"> + <a name="nametest">hmm</a> + <b class="foo">hmm</b> + <b id="test1" class="test1">hmm</b> + <b id="test2" class="test2">hmm</b> + <b id="int-class" class="1">hmm</b> + <span class="classtest">hmm</span> + <div id="example"> + <p id="p1" class="aaa bbb"/> + <p id="p2" class="aaa ccc"/> + <p id="p3" class="bbb ccc"/> + </div> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug357450.xhtml b/dom/base/test/test_bug357450.xhtml new file mode 100644 index 0000000000..872ea4798a --- /dev/null +++ b/dom/base/test/test_bug357450.xhtml @@ -0,0 +1,40 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=357450 +--> + +<head> + <title>Test for Bug 357450</title> + <script type="text/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="file_bug357450.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> + +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=357450" + target="_blank">Mozilla Bug 357450</a> + +<p id="display"></p> +<span class="classtest">hmm</span> +<span class="classtest">hmm</span> + +<div id="content" style="display: block"> + <a name="nametest">hmm</a> + <b class="foo">hmm</b> + <b id="test1" class="test1">hmm</b> + <b id="test2" class="test2">hmm</b> + <b id="int-class" class="1">hmm</b> + <span class="classtest">hmm</span> + + <div id="example"> + <p id="p1" class="aaa bbb"/> + <p id="p2" class="aaa ccc"/> + <p id="p3" class="bbb ccc"/> + </div> + +</div> +</body> +</html> diff --git a/dom/base/test/test_bug357450_svg.xhtml b/dom/base/test/test_bug357450_svg.xhtml new file mode 100644 index 0000000000..87d25bd832 --- /dev/null +++ b/dom/base/test/test_bug357450_svg.xhtml @@ -0,0 +1,47 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> + +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=357450 +--> + +<head> + <title>Test for Bug 357450</title> + <script type="text/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="file_bug357450.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +</head> + +<body> + +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=357450" + target="_blank">Mozilla Bug 357450</a> + +<p id="display"></p> +<span class="classtest">hmm</span> +<span class="classtest">hmm</span> +<div id="content" style="display: block"> + <a name="nametest">hmm</a> + <b class="foo">hmm</b> + <b id="test1" class="test1">hmm</b> + <b id="test2" class="test2">hmm</b> + <b id="int-class" class="1">hmm</b> + <svg xmlns="http://www.w3.org/2000/svg" + height="100" width="100" style="float:left"> + <path d="M38,38c0-12,24-15,23-2c0,9-16,13-16,23v7h11v-4c0-9,17-12,17-27c-2-22-45-22-45,3zM45,70h11v11h-11z" fill="#371"/> + + <circle cx="50" cy="50" r="45" class="classtest" + fill="none" stroke="#371" stroke-width="10"/> + </svg> + + <div id="example"> + <p id="p1" class="aaa bbb"/> + <p id="p2" class="aaa ccc"/> + <p id="p3" class="bbb ccc"/> + </div> + +</div> + +</body> +</html> diff --git a/dom/base/test/test_bug357509.html b/dom/base/test/test_bug357509.html new file mode 100644 index 0000000000..f18f5143b9 --- /dev/null +++ b/dom/base/test/test_bug357509.html @@ -0,0 +1,36 @@ +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=357509 +--> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script> + function foo(elem) { + rng = document.createRange(); + rng.setStartBefore(elem); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=357509">Mozilla Bug 357509</a> +<div style="display: none" id="rangetest"> +</div> +<pre id="test"> +<script type="text/javascript"> +var passed = false; +try { + foo(document.getElementById("rangetest")) + passed = true; +} +catch (e) { + passed = false; +} + +<!-- The ok() function tests the first arg --> +ok(passed, "nsIDOMRange.setStartBefore"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug358660.html b/dom/base/test/test_bug358660.html new file mode 100644 index 0000000000..bad9759369 --- /dev/null +++ b/dom/base/test/test_bug358660.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=358660 +--> +<head> + <title>Test for Bug 358660</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=358660">Mozilla Bug 358660</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="testframe" + src="data:text/html,<html><body>Some text</body></html>"></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 358660 **/ +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + var doc = $("testframe").contentDocument; + var range = doc.createRange(); + range.selectNode(doc.documentElement); + is(range.toString(), "Some text", "Check text"); + + SimpleTest.finish() +} + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug362391.xhtml b/dom/base/test/test_bug362391.xhtml new file mode 100644 index 0000000000..f40d18761f --- /dev/null +++ b/dom/base/test/test_bug362391.xhtml @@ -0,0 +1,75 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:foobar="http://www.foobar.com"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=362391 +--> +<head> + <title>Test for Bug 362391</title> + <!-- XHTML needs explicit script elements --> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/Iter.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=362391">Mozilla Bug 362391</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="test1"/> +<div id="test2"/> +<div id="test3" attr="null"/> +<div id="test4" foobar:attr="http://www.foobar.com"/> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 362391 **/ + + var currentTest = 0; + var expected = ""; + function listener(evt) { + var r = document.getElementById("result"); + ++currentTest; + ok(((evt.relatedNode.namespaceURI + "") == expected), + evt.relatedNode.namespaceURI + " == "+ expected); + } + + document.addEventListener("DOMAttrModified", listener, true); + + function test() { + expected = "null"; + document.getElementById("test1") + .setAttribute("attr", "null"); + + expected = "http://www.foobar.com"; + document.getElementById("test2") + .setAttributeNS("http://www.foobar.com", "attr", "http://www.foobar.com"); + + expected = "http://www.foobar.com"; + document.getElementById("test3") + .setAttributeNS("http://www.foobar.com", "attr", "http://www.foobar.com"); + + expected = "null"; + document.getElementById("test4") + .setAttribute("attr", "null"); + + expected = "http://www.foobar.com"; + document.getElementById("test3") + .removeAttributeNS("http://www.foobar.com", "attr"); + + expected = "null"; + document.getElementById("test4") + .removeAttribute("attr"); + } + + test(); +</script> +</pre> + +</body> +</html> + diff --git a/dom/base/test/test_bug364092.xhtml b/dom/base/test/test_bug364092.xhtml new file mode 100644 index 0000000000..72276443bd --- /dev/null +++ b/dom/base/test/test_bug364092.xhtml @@ -0,0 +1,46 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=364092 +--> +<head> + <title>Test for Bug 364092</title> + <!-- XHTML needs explicit script elements --> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/Iter.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=364092">Mozilla Bug 364092</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="test1" foo="foo"/> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 364092 **/ + + var test1 = document.getElementById("test1"); + var attrNode = test1.getAttributeNode("foo"); + function mutationHandler(aEvent) { + ok(attrNode == aEvent.relatedNode); + ok(!test1.hasAttribute("foo")); + } + + function runTest() { + test1.addEventListener("DOMAttrModified", mutationHandler, true); + test1.removeAttributeNode(attrNode); + test1.removeEventListener("DOMAttrModified", mutationHandler, true); + } + + runTest(); +</script> +</pre> + +</body> +</html> + diff --git a/dom/base/test/test_bug364413.xhtml b/dom/base/test/test_bug364413.xhtml new file mode 100644 index 0000000000..14c0af0f1d --- /dev/null +++ b/dom/base/test/test_bug364413.xhtml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:foobar="http://www.foobar.com"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=364413 +--> +<head> + <title>Test for Bug 364413</title> + <!-- XHTML needs explicit script elements --> + <script type="text/javascript" src="/MochiKit/Base.js"></script> + <script type="text/javascript" src="/MochiKit/Iter.js"></script> + <script type="text/javascript" src="/MochiKit/DOM.js"></script> + <script type="text/javascript" src="/MochiKit/Style.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=364413">Mozilla Bug 364413</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="test1" foobar:foo="foo"/> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 364413 **/ + + var test1 = document.getElementById("test1"); + var attrNode = test1.getAttributeNodeNS("http://www.foobar.com", "foo"); + function mutationHandler(aEvent) { + ok(attrNode == aEvent.relatedNode); + ok(aEvent.target == attrNode.ownerElement); + } + + function runTest() { + test1.removeAttributeNode(attrNode); + test1.addEventListener("DOMAttrModified", mutationHandler, true); + test1.setAttributeNodeNS(attrNode); + test1.removeEventListener("DOMAttrModified", mutationHandler, true); + } + + runTest(); +</script> +</pre> + +</body> +</html> + diff --git a/dom/base/test/test_bug366944.html b/dom/base/test/test_bug366944.html new file mode 100644 index 0000000000..8e4acd9e3f --- /dev/null +++ b/dom/base/test/test_bug366944.html @@ -0,0 +1,49 @@ +<!doctype html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=366944 +--> +<title>Test for Bug 366944</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=366944">Mozilla Bug 366944</a> +<script> + +/** Test for Bug 366944 **/ +var testNodes = [document, document.doctype, document.createDocumentFragment()]; +for (var i = 0; i < testNodes.length; i++) { + var range = document.createRange(); + // If a non-Text node is partially contained, we expect to throw for that + // first + range.setStart(document.head, 0); + range.setEnd(document.body, 0); + var threw = false; + var desc = " (surrounding a range with partially-contained Element " + + "with " + (i == 0 ? "document" : i == 1 ? "doctype" : "docfrag") + ")"; + try { + range.surroundContents(testNodes[i]); + } catch(e) { + threw = true; + is(Object.getPrototypeOf(e), DOMException.prototype, + "Must throw DOMException" + desc); + is(e.name, "InvalidStateError", "Must throw InvalidStateError" + desc); + } + ok(threw, "Must throw" + desc); + + range.setStart(document.body, 0); + range.setEnd(document.body, 1); + threw = false; + desc = " (surrounding a regular range " + + "with " + (i == 0 ? "document" : i == 1 ? "doctype" : "docfrag") + ")"; + try { + range.surroundContents(testNodes[i]); + } catch(e) { + threw = true; + is(Object.getPrototypeOf(e), DOMException.prototype, + "Must throw DOMException" + desc); + is(e.name, "InvalidNodeTypeError", + "Must throw InvalidNodeTypeError" + desc); + } + ok(threw, "Must throw" + desc); +} + +</script> diff --git a/dom/base/test/test_bug366946.html b/dom/base/test/test_bug366946.html new file mode 100644 index 0000000000..bd35238a40 --- /dev/null +++ b/dom/base/test/test_bug366946.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=366946 +--> +<head> + <title>Test for Bug 366946</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=366946">Mozilla Bug 366946</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="1"></div> + <div id="2"></div> + <div id="3"></div> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + /** Test for Bug 366946 **/ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + var doc1 = document; + + // Set up a new document. + var doc2 = document.implementation.createDocument('', '', null); + + // Copy some nodes into doc2 + var node1 = doc2.importNode(doc1.getElementById('1'), false); + var node2 = doc2.importNode(doc1.getElementById('1'), false); + node1.appendChild(node2); + doc2.appendChild(node1); + + // Create two ranges in doc1 to compare. + var range1 = doc1.createRange(); + range1.setStart(doc1.getElementById('1'), 0); + range1.setEnd(doc1.getElementById('2'), 0); + + var range2 = doc1.createRange(); + range2.setStart(doc1.getElementById('2'), 0); + range2.setEnd(doc1.getElementById('3'), 0); + + // Create a range in doc2. + var range3 = doc2.createRange(); + range3.setStart(node1, 0); + range3.setEnd(node2, 0); + + // Compare range1 and range2: Should return 1. + try { + var result1 = range2.compareBoundaryPoints(Range.START_TO_START, range1); + } + catch (ex) { + } + ok(result1 === 1, "range1 and range2 are compared correctly."); + + // Compare range1 and range3: Should throw DOMException WRONG_DOCUMENT_ERR. + try { + var result2 = range3.compareBoundaryPoints(Range.START_TO_START, range1); + } + catch (ex) { + var error = ex.name; + var errorCode = ex.code; + } + + ok(error == "WrongDocumentError", + "The WrongDocumentError exception thrown when comparing ranges from " + + "different documents "); + ok(errorCode == DOMException.WRONG_DOCUMENT_ERR, + "The exception thrown when comparing ranges from different documents " + + "has the code DOMException.WRONG_DOCUMENT_ERR"); + ok(result2 === undefined, "range1 and range3 couldn't be compared as expected."); + SimpleTest.finish(); + }); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug367164.html b/dom/base/test/test_bug367164.html new file mode 100644 index 0000000000..a499a833d5 --- /dev/null +++ b/dom/base/test/test_bug367164.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=367164 +--> +<head> + <title>Test for Bug 367164</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=367164">Mozilla Bug 367164</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 367164 **/ + +var span = document.createElement("span"); + +var ins1 = false; +var ins2 = false; +var rem1 = false; +var rem2 = false; + +span.addEventListener("DOMNodeInserted", function() { ins1 = true; }, true); +span.addEventListener("DOMNodeInserted", function() { ins2 = true; }, false); +span.addEventListener("DOMNodeRemoved", function() { rem1 = true; }, true); +span.addEventListener("DOMNodeRemoved", function() { rem2 = true; }, false); + +$("content").appendChild(span); +$("content").removeChild(span); + +is(ins1, true, "Capturing DOMNodeInserted listener"); +is(ins2, true, "Bubbling DOMNodeInserted listener"); +is(rem1, true, "Capturing DOMNodeRemoved listener"); +is(rem2, true, "Bubbling DOMNodeRemoved listener"); + +</script> + +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug368972.html b/dom/base/test/test_bug368972.html new file mode 100644 index 0000000000..74c6c055eb --- /dev/null +++ b/dom/base/test/test_bug368972.html @@ -0,0 +1,120 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=368972 +--> +<head> + <title>Test for Bug 368972</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<style type="text/css"> +#embed11, #object11 { + width: 400px; + height: 400px; +} +</style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=368972">Mozilla Bug 368972</a> +<p id="display"></p> +<div id="content"> +Embed without defined width/height: +<embed id="embed1" type="bogus"><br> +Embed width=0 height=0 +<embed id="embed2" type="bogus" width="0" height="0"><br> +Embed width=100 height=100 +<embed id="embed3" type="bogus" width="100" height="100"><br> +Embed height=100 +<embed id="embed4" type="bogus" height="100"><br> +Embed width=100 +<embed id="embed5" type="bogus" width="100"><br> +Embed width=100xxx height=100 +<embed id="embed6" type="bogus" width="100xxx" height="100"><br> +Embed width=0100 height=100 +<embed id="embed7" type="bogus" width="0100" height="100"><br> +Embed width= height=100 +<embed id="embed8" type="bogus" width="" height="100"><br> +Embed width=100 height=100 style="width:400px" +<embed id="embed9" type="bogus" width="100" height="100" style="width:400px;"><br> +Embed height=100 style="width:400px" +<embed id="embed10" type="bogus" height="100" style="width:400px;"><br> +Embed height=100 (stylesheet width:400px height:400px) +<embed id="embed11" type="bogus" height="100"><br> + +Object without defined width/height: +<object id="object1" type="bogus"> +</object><br> +Object width=0 height=0 +<object id="object2" type="bogus" width="0" height="0"> +</object><br> +Object width=100 height=100 +<object id="object3" type="bogus" width="100" height="100"> +</object><br> +Object height=100 +<object id="object4" type="bogus" height="100"> +</object><br> +Object width=100 +<object id="object5" type="bogus" width="100"> +</object><br> +Object width=100xxx height=100 +<object id="object6" type="bogus" width="100xxx" height="100"> +</object><br> +Object width=0100 height=100 +<object id="object7" type="bogus" width="0100" height="100"> +</object><br> +Object width= height=100 +<object id="object8" type="bogus" width="" height="100"> +</object><br> +Object width=100 height=100 style="width:400px" +<object id="object9" type="bogus" width="100" height="100" style="width:400px;"> +</object><br> +Object height=100 style="width:400px" +<object id="object10" type="bogus" height="100" style="width:400px;"> +</object><br> +Object height=100 (stylesheet width:400px height:400px) +<object id="object11" type="bogus" height="100"> +</object><br> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +function check_size(id, width, height) { + var element = document.getElementById(id); + ok(element, "Plugin element " + id + " did not exist"); + if (width != "auto") { + width = width + "px"; + } + if (height != "auto") { + height = height + "px"; + } + var style = window.getComputedStyle(element, null); + is(style.width, width, "Plugin element " + id + " had an incorrect width"); + is(style.height, height, "Plugin element " + id + " had an incorrect height"); +} + +check_size("embed1", "auto", "auto"); +check_size("embed2", 0, 0); +check_size("embed3", 100, 100); +check_size("embed4", "auto", 100); +check_size("embed5", 100, "auto"); +check_size("embed6", 100, 100); +check_size("embed7", 100, 100); +check_size("embed8", "auto", 100); +check_size("embed9", 400, 100); +check_size("embed10", 400, 100); +check_size("embed11", 400, 400); + +check_size("object1", "auto", "auto"); +check_size("object2", 0, 0); +check_size("object3", 100, 100); +check_size("object4", "auto", 100); +check_size("object5", 100, "auto"); +check_size("object6", 100, 100); +check_size("object7", 100, 100); +check_size("object8", "auto", 100); +check_size("object9", 400, 100); +check_size("object10", 400, 100); +check_size("object11", 400, 400); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug371576-2.html b/dom/base/test/test_bug371576-2.html new file mode 100644 index 0000000000..2fdf3fcb43 --- /dev/null +++ b/dom/base/test/test_bug371576-2.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=371576 +--> +<head id="head"> + <title>Test for Bug 371576</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=371576">Mozilla Bug 371576</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var result = "A"; + var scrElem= document.createElement('script'); + scrElem.textContent = 'result+="B";$("content").innerHTML="--";result+="C";'; + $("head").appendChild(scrElem); + result += "D"; + +</script> +<script>result += "E"</script> +<script>result += "F"</script> +<script>is(result, "ABCDEF", "Wrong order of execution");</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug371576-3.html b/dom/base/test/test_bug371576-3.html new file mode 100644 index 0000000000..8bf6c12613 --- /dev/null +++ b/dom/base/test/test_bug371576-3.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=371576 +--> +<head id="head"> + <title>Test for Bug 371576</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=371576">Mozilla Bug 371576</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script src='data:text/javascript, + var result = "A"; + var scrElem= document.createElement("script"); + scrElem.textContent = "result+=\"B\";$(\"content\").innerHTML=\"--\";result+=\"C\";"; + $("head").appendChild(scrElem); + result += "D";'></script> +<script>result += "E"</script> +<script>result += "F"</script> +<script>is(result, "ABCDEF", "Wrong order of execution");</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug371576-4.html b/dom/base/test/test_bug371576-4.html new file mode 100644 index 0000000000..878676f854 --- /dev/null +++ b/dom/base/test/test_bug371576-4.html @@ -0,0 +1,21 @@ +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=371576 +--> +<head> + <title>Test2 for Bug 371576</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script> + +var _bShouldbeThere = false; +var oScript = document.createElement('script'); +oScript.innerHTML = '_bShouldbeThere = true'; +document.getElementsByTagName('head')[0].appendChild(oScript); +ok(_bShouldbeThere,"_bShouldbeThere is true, script has executed on time"); + +</script> + +</head> +</html> diff --git a/dom/base/test/test_bug371576-5.html b/dom/base/test/test_bug371576-5.html new file mode 100644 index 0000000000..1d3ca956c1 --- /dev/null +++ b/dom/base/test/test_bug371576-5.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=371576 +--> +<head id="head"> + <title>Test for Bug 371576</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script> +SimpleTest.waitForExplicitFinish(); + +addLoadEvent( + function doe(){ + var x=document.createElement('script'); + x.src='data:text/html,var scr=document.createElement("script");\ + scr.innerHTML = "function doe3(){$(\'display\').innerHTML = \'You should see this text\';}";\ + $("head").appendChild(scr);'; + x.onload= function (){ + doe3(); + ok(true,"function doe3 is defined, and the body content has been replaced."); + is($("display").textContent, "You should see this text", "text set properly"); + SimpleTest.finish(); + }; + $('head').appendChild(x); + } +); +</script> + +</head> +<body> +<p id="display">You shouldn't see this</p> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=371576">Mozilla Bug 371576</a> +</body> +</html> diff --git a/dom/base/test/test_bug372086.html b/dom/base/test/test_bug372086.html new file mode 100644 index 0000000000..75bf1a5417 --- /dev/null +++ b/dom/base/test/test_bug372086.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=372086 +--> +<head> + <title>Test for Bug 372086</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=372086">Mozilla Bug 372086</a> +<p id="display"> + <!-- Binding is: + <bindings xmlns="http://www.mozilla.org/xbl"> + <binding id="test"> + <content>ghi<children/>jkl</content> + </binding> + </bindings> + --> + <div id="d" style="-moz-binding: url(data:application/xml,%3Cbindings%20xmlns%3D%22http%3A%2F%2Fwww.mozilla.org%2Fxbl%22%3E%3Cbinding%20id%3D%22test%22%3E%3Ccontent%3Eghi%3Cchildren%2F%3Ejkl%3C%2Fcontent%3E%3C%2Fbinding%3E%3C%2Fbindings%3E)">abc</div>def +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 372086 **/ + +// Note that we could avoid a lot of SpecialPowers.unwrap calls if the SpecialPowers +// wrappers could be made to preserve identity. See bug 718543. + +function runTest() { + var range = SpecialPowers.wrap(document.createRange()); + + var c = $("d").firstChild; + var a = $("d").nextSibling; + + range.setStart(c, 1); + range.setEnd(c, 3); + is(SpecialPowers.unwrap(range.startContainer), c, "Unexpected start container"); + is(range.startOffset, 1, "Unexpected start offset"); + is(SpecialPowers.unwrap(range.endContainer), c, "Unexpected end container"); + is(range.endOffset, 3, "Unexpected end offset"); + is(range.toString(), "bc", "Unexpected range serialization"); + + var anon = SpecialPowers.wrap(document).getAnonymousNodes($("d"))[0]; + // Should collapse the range, because can't determine order + range.setEnd(anon, 2); + is(SpecialPowers.unwrap(range.startContainer), SpecialPowers.unwrap(anon), + "Unexpected collapsed start container"); + is(range.startOffset, 2, "Unexpected collapsed start offset"); + is(SpecialPowers.unwrap(range.endContainer), SpecialPowers.unwrap(anon), + "Unexpected collapsed end container"); + is(range.endOffset, 2, "Unexpected collapsed end offset"); + is(range.toString(), "", "Unexpected collapsed range serialization"); + + range.setEnd(a, 2); + range.setStart(a, 0); + is(SpecialPowers.unwrap(range.startContainer), a, "Unexpected start container after"); + is(range.startOffset, 0, "Unexpected start offset after"); + is(SpecialPowers.unwrap(range.endContainer), a, "Unexpected end container after"); + is(range.endOffset, 2, "Unexpected end offset after"); + is(range.toString(), "de", "Unexpected range serialization after"); + + anon = SpecialPowers.wrap(document).getAnonymousNodes($("d"))[2]; + // Collapses because one endpoint is anonymous from point of view of + // the other. + range.setStart(anon, 1); + is(SpecialPowers.unwrap(range.startContainer), + SpecialPowers.unwrap(anon), "Unexpected newly collapsed start container"); + is(range.startOffset, 1, "Unexpected newly collapsed start offset"); + is(SpecialPowers.unwrap(range.endContainer), SpecialPowers.unwrap(anon), + "Unexpected newly collapsed end container"); + is(range.endOffset, 1, "Unexpected newly collapsed end offset"); + is(range.toString(), "", "Unexpected collapsed range serialization"); + + range.setEnd(anon, 3); + is(SpecialPowers.unwrap(range.startContainer), + SpecialPowers.unwrap(anon), "Unexpected anon start container"); + is(range.startOffset, 1, "Unexpected anon start offset"); + is(SpecialPowers.unwrap(range.endContainer), + SpecialPowers.unwrap(anon), "Unexpected anon end container"); + is(range.endOffset, 3, "Unexpected anon end offset"); + is(range.toString(), "kl", "Unexpected anon range serialization"); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); +addLoadEvent(SimpleTest.finish) +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug372964-2.html b/dom/base/test/test_bug372964-2.html new file mode 100644 index 0000000000..cbf941b59d --- /dev/null +++ b/dom/base/test/test_bug372964-2.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=372964 +--> +<head> + <title>Test for Bug 372964</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=372964">Mozilla Bug 372964</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 372964 **/ + +var eventCount = 0; + +function runTest() { + var ifr = document.getElementsByTagName("iframe")[0]; + var xhr = new ifr.contentWindow.XMLHttpRequest(); + xhr.addEventListener("foo", ifr.contentWindow.listener, false); + var event = ifr.contentDocument.createEvent("Events"); + event.initEvent("foo", true, true); + xhr.dispatchEvent(event); + is(eventCount, 1, "Should have handled an event"); + ifr.contentDocument.open(); + ifr.contentDocument.close(); + event = ifr.contentDocument.createEvent("Events"); + event.initEvent("foo", true, true); + xhr.dispatchEvent(event); + is(eventCount, 2, + "Should have handled the event because open()/close() keep the active document"); + ifr.onload = function() { + event = ifr.contentDocument.createEvent("Events"); + event.initEvent("foo", true, true); + xhr.dispatchEvent(event); + is(eventCount, 2, + "Shouldn't have handled an event because the context has changed"); + SimpleTest.finish(); + }; + ifr.contentWindow.location = "about:blank"; +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + +</script> +</pre> +<iframe src="data:text/html,<script>function listener() { ++parent.eventCount; } </script>"> +</body> +</html> + diff --git a/dom/base/test/test_bug372964.html b/dom/base/test/test_bug372964.html new file mode 100644 index 0000000000..cc8ac7d2dd --- /dev/null +++ b/dom/base/test/test_bug372964.html @@ -0,0 +1,144 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=372964 +--> +<head> + <title>Test for Bug 372964</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=372964">Mozilla Bug 372964</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 372964 **/ + +var expectedEventType = ""; +var shouldBeTrusted = false; +var eventHandlerCallCount = 0; + +function eventHandler(evt) { + ++eventHandlerCallCount; + is(evt.type, expectedEventType, "Wrong event type"); + is(evt.isTrusted, shouldBeTrusted, "Wrong .isTrusted"); +} + +function test(trusted, type, removeAddedListener, removeSetListener, allowUntrusted) { + if (trusted) { + var x1 = SpecialPowers.wrap(new XMLHttpRequest()); + } else { + x1 = new XMLHttpRequest(); + } + + var handlerCount = 0; + if (trusted || allowUntrusted || allowUntrusted == undefined) { + ++handlerCount; + } + + if (allowUntrusted == undefined) { + // Test .addEventListener with 3 parameters. + x1.addEventListener(type, eventHandler, false); + } else { + // Test .addEventListener with 4 parameters. + x1.addEventListener(type, eventHandler, false, allowUntrusted); + } + + if (("on" + type) in x1) { + ++handlerCount; + x1["on" + type] = eventHandler; + } + + if (removeAddedListener) { + x1.removeEventListener(type, eventHandler, false); + if (trusted || allowUntrusted || allowUntrusted == undefined) { + --handlerCount; + } + } + + if (removeSetListener) { + if (("on" + type) in x1) { + --handlerCount; + x1["on" + type] = null; + } + } + + var e1 = document.createEvent("Events"); + e1.initEvent(type, true, true); + expectedEventType = type; + shouldBeTrusted = trusted; + var ecc = eventHandlerCallCount; + x1.dispatchEvent(e1); + is(eventHandlerCallCount, ecc + handlerCount, + "Wrong number event handler calls. (1)"); + + e1 = document.createEvent("Events"); + e1.initEvent(type, true, true); + expectedEventType = type; + // Set trusted since open() may cause events to be sent. + shouldBeTrusted = true; + x1.open("GET", window.location); + x1.abort(); // This should not remove event listeners. + ecc = eventHandlerCallCount; + shouldBeTrusted = trusted; + x1.dispatchEvent(e1); + is(eventHandlerCallCount, ecc + handlerCount, + "Wrong number event handler calls. (2)"); + + e1 = document.createEvent("Events"); + e1.initEvent(type, true, true); + expectedEventType = type; + // Set trusted since open()/send() may cause events to be sent. + shouldBeTrusted = true; + x1.open("GET", window.location); + x1.send(""); + x1.abort(); // This should not remove event listeners! + ecc = eventHandlerCallCount; + shouldBeTrusted = trusted; + x1.dispatchEvent(e1); + is(eventHandlerCallCount, ecc + handlerCount, + "Wrong number event handler calls. (3)"); +} + +var events = + ["load", "error", "progress", "readystatechange", "foo"]; + +do { + var e = events.shift(); + test(false, e, false, false); + test(false, e, false, true); + test(false, e, true, false); + test(false, e, true, true); + test(true, e, false, false); + test(true, e, false, true); + test(true, e, true, false); + test(true, e, true, true); + + test(false, e, false, false, false); + test(false, e, false, false, true); + test(false, e, false, true, false); + test(false, e, false, true, true); + test(false, e, true, false, false); + test(false, e, true, false, true); + test(false, e, true, true, false); + test(false, e, true, true, true); + test(true, e, false, false, false); + test(true, e, false, false, true); + test(true, e, false, true, false); + test(true, e, false, true, true); + test(true, e, true, false, false); + test(true, e, true, false, true); + test(true, e, true, true, false); + test(true, e, true, true, true); +} while(events.length); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug373181.xhtml b/dom/base/test/test_bug373181.xhtml new file mode 100644 index 0000000000..17af078224 --- /dev/null +++ b/dom/base/test/test_bug373181.xhtml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>Testcase for bug 373181</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"/> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/x-javascript"> + function onLoadFired() + { + ok(true, "Body onload event should fire"); + SimpleTest.finish(); + } + SimpleTest.waitForExplicitFinish(); + </script> + </head> + <body onload="onLoadFired();"/> +</html> diff --git a/dom/base/test/test_bug375314.html b/dom/base/test/test_bug375314.html new file mode 100644 index 0000000000..4858f80639 --- /dev/null +++ b/dom/base/test/test_bug375314.html @@ -0,0 +1,187 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=375314 +--> +<head> + <title>Test for Bug 375314</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=375314">Mozilla Bug 375314</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 375314 **/ + +var lastContentType = -1; +const testURL = window.location.href + "/this/is/the/test/url"; +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +// Content policy / factory implementation for the test +var policyID = SpecialPowers.wrap(SpecialPowers.Components).ID("{b80e19d0-878f-d41b-2654-194714a4115c}"); +var policyName = "@mozilla.org/testpolicy;1"; +var policy = { + // nsISupports implementation + QueryInterface: function(iid) { + + iid = SpecialPowers.wrap(iid); + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIFactory) || + iid.equals(Ci.nsIContentPolicy)) + return this; + + throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE; + }, + + // nsIFactory implementation + createInstance: function(outer, iid) { + return this.QueryInterface(iid); + }, + + // nsIContentPolicy implementation + shouldLoad: function(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) { + + // Remember last content type seen for the test url + if (SpecialPowers.wrap(contentLocation).spec == testURL) { + lastContentType = contentType; + return Ci.nsIContentPolicy.REJECT_REQUEST; + } + + return Ci.nsIContentPolicy.ACCEPT; + }, + + shouldProcess: function(contentType, contentLocation, requestOrigin, context, mimeTypeGuess, extra) { + + return Ci.nsIContentPolicy.ACCEPT; + } +} +policy = SpecialPowers.wrapCallbackObject(policy); + +// Register content policy +var componentManager = SpecialPowers.wrap(SpecialPowers.Components).manager + .QueryInterface(Ci.nsIComponentRegistrar); + +componentManager.registerFactory(policyID, "Test content policy", policyName, policy); + +var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager); +categoryManager.addCategoryEntry("content-policy", policyName, policyName, false, true); + +// Try creating different request types +var tests = ["SCRIPT", "IMAGE", "STYLESHEET", "OBJECT", "DOCUMENT", "SUBDOCUMENT", "XBL", "XMLHTTPREQUEST"]; +var curTest = -1; + +var div; + +SimpleTest.waitForExplicitFinish(); +setTimeout(runNextTest, 0); + +function runNextTest() { + + if (curTest >= 0) { + var type = "TYPE_" + tests[curTest]; + is(lastContentType, Ci.nsIContentPolicy[type], "Content policies triggered for " + type); + + if (tests[curTest] == "XBL") + { + //XXX Removing binding to work-around a memory leak (bugs 478528, 499735). + div.style.MozBinding = ""; + } + } + + curTest++; + if (curTest < tests.length) { + var method = "request_" + tests[curTest].toLowerCase(); + try { + window[method](); + } catch(e) {} + setTimeout(runNextTest, 0); + } + else { + // Unregister content policy + categoryManager.deleteCategoryEntry("content-policy", policyName, false); + + setTimeout(function() { + // Component must be unregistered delayed, otherwise other content + // policy will not be removed from the category correctly + componentManager.unregisterFactory(policyID, policy); + }, 0); + + SimpleTest.finish(); + } +} + +// Request creating functions + +function request_script() { + var content = $("content"); + + var script = document.createElement("script"); + script.setAttribute("type", "text/javascript") + script.setAttribute("src", testURL) + content.appendChild(script); +} + +function request_image() { + var content = $("content"); + + var image = new Image(); + image.src = testURL; +} + +function request_stylesheet() { + var content = $("content"); + + var stylesheet = document.createElement("link"); + stylesheet.setAttribute("rel", "stylesheet"); + stylesheet.setAttribute("type", "text/css"); + stylesheet.setAttribute("href", testURL); + content.appendChild(stylesheet); +} + +function request_object() { + var content = $("content"); + + var object = document.createElement("embed"); + object.setAttribute("src", testURL); + content.appendChild(object); +} + +function request_document() { + top.location.href = testURL; +} + +function request_subdocument() { + var content = $("content"); + + var frame = document.createElement("iframe"); + frame.setAttribute("src", testURL); + content.appendChild(frame); +} + +function request_xbl() { + var content = $("content"); + + div = document.createElement("div"); + div.style.MozBinding = "url(" + testURL + ")"; + $('test').appendChild(div); + div.offsetLeft; // Flush styles. +} + +function request_xmlhttprequest() { + var request = new XMLHttpRequest(); + request.open("GET", testURL, false); + request.send(null); +} + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug378969.html b/dom/base/test/test_bug378969.html new file mode 100644 index 0000000000..965df74ba4 --- /dev/null +++ b/dom/base/test/test_bug378969.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=378969 +--> +<head> + <title>Test for Bug 378969</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=378969">Mozilla Bug 378969</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 378969 **/ + +function do_test() +{ + var XHTMLDocString = '<html xmlns="http://www.w3.org/1999/xhtml">'; + XHTMLDocString += '<body><input/>input</body></html>'; + + var doc = new DOMParser().parseFromString(XHTMLDocString, "application/xml"); + + var body = doc.getElementsByTagName("body")[0]; + var filter = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT; + var walker = doc.createTreeWalker(body, filter, null); + walker.currentNode = body.firstChild; + walker.nextNode(); + + ok("A" == "A", "A is A"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(do_test); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug380418.html b/dom/base/test/test_bug380418.html new file mode 100644 index 0000000000..f2166c2bde --- /dev/null +++ b/dom/base/test/test_bug380418.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- https://bugzilla.mozilla.org/show_bug.cgi?id=380418 --> +<head> + <title>Test for Bug 380418</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=380418">Mozilla Bug 380418</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var request = new XMLHttpRequest(); + request.open("GET", window.location.href, false); + request.send(null); + + // Try reading headers in unprivileged context + is(request.getResponseHeader("Set-Cookie"), null, "Reading Set-Cookie response header in unprivileged context"); + is(request.getResponseHeader("Set-Cookie2"), null, "Reading Set-Cookie2 response header in unprivileged context"); + is(request.getResponseHeader("X-Dummy"), "test", "Reading X-Dummy response header in unprivileged context"); + + ok(!/\bSet-Cookie:/i.test(request.getAllResponseHeaders()), "Looking for Set-Cookie in all response headers in unprivileged context"); + ok(!/\bSet-Cookie2:/i.test(request.getAllResponseHeaders()), "Looking for Set-Cookie2 in all response headers in unprivileged context"); + ok(/\bX-Dummy:/i.test(request.getAllResponseHeaders()), "Looking for X-Dummy in all response headers in unprivileged context"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug380418.html^headers^ b/dom/base/test/test_bug380418.html^headers^ new file mode 100644 index 0000000000..5f8d4969c0 --- /dev/null +++ b/dom/base/test/test_bug380418.html^headers^ @@ -0,0 +1,4 @@ +Set-Cookie: test +Set-Cookie2: test2 +X-Dummy: test +Cache-Control: max-age=0 diff --git a/dom/base/test/test_bug382113.html b/dom/base/test/test_bug382113.html new file mode 100644 index 0000000000..3cf6791520 --- /dev/null +++ b/dom/base/test/test_bug382113.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=382113 +--> +<head> + <title>Test for Bug 382113</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script class="testbody" type="application/javascript"> + + SimpleTest.waitForExplicitFinish(); + var childGotOnload = false; + var objectGotOnload = false; + + /** Test for Bug 100533 **/ + function checkEvents() { + is(childGotOnload, true, "Child got load event"); + is(objectGotOnload, true, "Object got load event"); + SimpleTest.finish(); + } + </script> +</head> +<body onload="checkEvents()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=382113">Mozilla Bug 382113</a> +<p id="display"></p> +<div id="content"> + <object type="text/html" data="bug382113_object.html" + onload="objectGotOnload = true;"></object> +</div> +<pre id="test"> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug382871.html b/dom/base/test/test_bug382871.html new file mode 100644 index 0000000000..c36a5f335d --- /dev/null +++ b/dom/base/test/test_bug382871.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=382871 +--> +<head> + <title>Test for Bug 382871</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=382871">Mozilla Bug 382871</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 382871 **/ + +function loadHandler(evt) { + ok("randomProperty" in evt.target); + ok("randomProperty" in evt.target.upload); + SimpleTest.finish(); +} + +function runTest() { + var xhr = new XMLHttpRequest(); + xhr.onload = loadHandler; + xhr.randomProperty = true; + xhr.upload.randomProperty = true; + xhr.open("GET", "test_bug382871.html"); + xhr.send(); + xhr = null; + SpecialPowers.gc(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug384003.xhtml b/dom/base/test/test_bug384003.xhtml new file mode 100644 index 0000000000..d1ed91821e --- /dev/null +++ b/dom/base/test/test_bug384003.xhtml @@ -0,0 +1,84 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml" attr="value"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=384003 +--> +<head> + <title>Test for Bug 384003</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=384003">Mozilla Bug 384003</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test" xmlns:foo="http://www.foo.org"><foo:foo/> +<script type="application/javascript"> +<![CDATA[ + +/** Test for Bug 384003 **/ + + +function resolverTest(expr, resolver, result, extype) { + if (!extype) { + extype = 0; + } + try { + is(document.evaluate(expr, document, resolver, + XPathResult.FIRST_ORDERED_NODE_TYPE, null). + singleNodeValue, + result, + "Wrong XPathResult"); + if (extype) { + ok(false, "Should have got an exception!"); + } + } catch(ex) { + is(ex.name, extype, "Wrong exception"); + } +} + +// Expression should return document element. +// Document resolver +resolverTest("*", document, document.documentElement); +// Element resolver +resolverTest("*", document.documentElement, document.documentElement); +// Attribute resolver +resolverTest("*", document.documentElement.getAttributeNode("attr"), + document.documentElement); +// Text node resolver +resolverTest("*", document.documentElement.firstChild, + document.documentElement); +// Comment node resolver +resolverTest("*", document.documentElement.firstChild.nextSibling, + document.documentElement); + +// Expression should return foo element, but because of the +// resolver it may throw an exception. +var foo = document.getElementById("test").firstChild; +// Document resolver +resolverTest("//foo:foo", document, foo, "NamespaceError"); +// Element resolver +resolverTest("//foo:foo", document.documentElement, foo, "NamespaceError"); +// Attribute resolver +resolverTest("//foo:foo", document.documentElement.getAttributeNode("attr"), + foo, "NamespaceError"); +// Text node resolver +resolverTest("//foo:foo", document.documentElement.firstChild, + foo, "NamespaceError"); +// Comment node resolver +resolverTest("//foo:foo", document.documentElement.firstChild.nextSibling, + foo, "NamespaceError"); +// Function resolver +resolverTest("//foo:foo", + function(p) { return (p == "foo") ? "http://www.foo.org" : ""; }, + foo); +// Element resolver, which has definition for foo namespace +resolverTest("//foo:foo", foo.parentNode, foo); + +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug390219.html b/dom/base/test/test_bug390219.html new file mode 100644 index 0000000000..9f0b1aa7f4 --- /dev/null +++ b/dom/base/test/test_bug390219.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=390219 +--> +<head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Test for Bug 390219</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 390219 **/ + +SimpleTest.waitForExplicitFinish(); +xhr = new XMLHttpRequest(); +xhr.open("GET", "nonexistent_url", true); +xhr.send(null); +xhr.abort(); +xhr.open("GET", ".", true); +xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + is(xhr.status, 200, "wrong status"); + SimpleTest.finish(); + } +} +xhr.send(null); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug390735.html b/dom/base/test/test_bug390735.html new file mode 100644 index 0000000000..025d780e7a --- /dev/null +++ b/dom/base/test/test_bug390735.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=390735 +--> +<head> + <meta http-equiv="content-type" content="text/html; charset=utf-8"> + <title>Test for Bug 390735</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 390735 **/ + +var contents = document.getElementsByTagName("head")[0].innerHTML; +var expectedFind = "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"; + +ok(contents.indexOf(expectedFind) > -1, "The meta tag element was not found"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug392318.html b/dom/base/test/test_bug392318.html new file mode 100644 index 0000000000..4afde0075e --- /dev/null +++ b/dom/base/test/test_bug392318.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=392318 +--> +<head> + <title>Test for Bug 392318</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script class="testbody" type="text/javascript"> + /** Test for Bug 392318 **/ + + SimpleTest.waitForExplicitFinish(); + var testRan = false; + + function runTest() { + isnot($("t").offsetWidth, 0, "Unexpected offsetWidth"); + testRan = true; + } + + document.addEventListener("DOMContentLoaded", runTest, false); + + addLoadEvent(function() { + is(testRan, true, "Onload firing too early"); + }); + + addLoadEvent(SimpleTest.finish); + </script> + <!-- IMPORTANT: This sheet must come after the test that sets up the + DOMContentLoaded handler and before the <body> --> + <link rel="stylesheet" type="text/css" href="data:text/css;%20charset=utf-8,%23t%20%7B%0Awidth%3A%20200px%3B%0Aborder%3A%201px%20solid%20black%3B%0Aheight%3A%20100px%3B%0A%7D"> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=392318">Mozilla Bug 392318</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<div id="t"></div> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug392511.html b/dom/base/test/test_bug392511.html new file mode 100644 index 0000000000..13f9788f9b --- /dev/null +++ b/dom/base/test/test_bug392511.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=392511 +--> +<head> + <title>Test for Bug 392511</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=392511">Mozilla Bug 392511</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="t1"><span onclick=""&"></span></div> + <div id="t2"><span foo=""&"></span></div> + <div id="t3"><span onclick=''&'></span></div> + <div id="t4"><span foo=''&'></span></div> + <div id="t5"><span onclick='"'&'></span></div> + <div id="t6"><span foo='"'&'></span></div> + <div id="t7"><span onclick="'"&"></span></div> + <div id="t8"><span foo="'"&"></span></div> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 392511 **/ + +var results = [ + "\""&\"", + "\""&\"", + "\"'&\"", + "\"'&\"", + "\""'&\"", + "\""'&\"", + "\"'"&\"", + "\"'"&\"" +]; + +for (var i = 1; i <= 8; ++i) { + var id = "t" + i; + var str = $(id).innerHTML; + var expect = "<span "; + expect += (i % 2) ? "onclick" : "foo"; + expect += "=" + results[i-1] + "></span>"; + is (str, expect, "Wrong string for test " + id); +} + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug393968.html b/dom/base/test/test_bug393968.html new file mode 100644 index 0000000000..08ed852926 --- /dev/null +++ b/dom/base/test/test_bug393968.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=393968 +--> +<head> + <title>Test for Bug 393968</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=393968">Mozilla Bug 393968</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 393968 **/ +var req = new XMLHttpRequest(); +req.open("POST", window.location.href); +req.setRequestHeader("Content-Type", "text/plain; charset=us-ascii; boundary=01234567890"); +req.send("Some text"); + +is(SpecialPowers.wrap(req).channel + .QueryInterface(SpecialPowers.Ci.nsIHttpChannel) + .getRequestHeader("Content-Type"), + "text/plain; charset=UTF-8; boundary=01234567890", + "Headers should match"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug395915.html b/dom/base/test/test_bug395915.html new file mode 100644 index 0000000000..aa1ee17d32 --- /dev/null +++ b/dom/base/test/test_bug395915.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html class="A b"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=395915 +--> +<head> + <title>Test for Bug 395915</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=395915">Mozilla Bug 395915</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 395915 **/ +is(document.getElementsByClassName("a").length, 0, + "Class names are case-sensitive"); +is(document.getElementsByClassName("A").length, 1, + "Have one node of class A"); +is(document.getElementsByClassName("A")[0], document.documentElement, + "Root is class A"); + +is(document.getElementsByClassName("a b").length, 0, + "Class names are case-sensitive two"); +is(document.getElementsByClassName("A B").length, 0, + "Class names are case-sensitive three"); +is(document.getElementsByClassName("a B").length, 0, + "Class names are case-sensitive four"); +is(document.getElementsByClassName("A b").length, 1, + "Have one node of class 'A b'"); +is(document.getElementsByClassName("A b")[0], document.documentElement, + "Root is class 'A b'"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug397234.html b/dom/base/test/test_bug397234.html new file mode 100644 index 0000000000..654df12aaa --- /dev/null +++ b/dom/base/test/test_bug397234.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=397234 +--> +<head> + <title>Test for Bug 397234</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=397234">Mozilla Bug 397234</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 397234 **/ +var req = new XMLHttpRequest(); +req.open("POST", window.location.href); +// Capitalization of charet param is on purpose! +req.setRequestHeader("Content-Type", "text/plain; charset='uTf-8'"); +req.send("Some text"); + +is(SpecialPowers.wrap(req).channel + .QueryInterface(SpecialPowers.Ci.nsIHttpChannel) + .getRequestHeader("Content-Type"), + "text/plain; charset='uTf-8'", + "Headers should match"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug398243.html b/dom/base/test/test_bug398243.html new file mode 100644 index 0000000000..3b5d7400cf --- /dev/null +++ b/dom/base/test/test_bug398243.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=398243 +--> +<head> + <title>Test for Bug 398243</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=398243">Mozilla Bug 398243</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + <iframe id="testframe" src="http://mochi.test:8888/tests/dom/base/test/formReset.html"></iframe> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 398243 **/ +const enteredText1 = "New value for text input"; +const enteredText2 = "New value for texarea"; +SimpleTest.waitForExplicitFinish(); + +function afterLoad() { + var iframeDoc = $("testframe").contentDocument; + /* change all the form controls */ + iframeDoc.getElementById("checkbox1").checked = true; + iframeDoc.getElementById("checkbox2").checked = false; + iframeDoc.getElementById("textinput").value = enteredText1; + iframeDoc.getElementById("textarea").value = enteredText2; + + /* Reload the page */ + $("testframe").setAttribute("onload", "afterReload()"); + iframeDoc.location.reload(); +} + +addLoadEvent(afterLoad); + +function afterReload() { + var iframeDoc = $("testframe").contentDocument; + is(iframeDoc.getElementById("checkbox1").checked, true, + "checkbox #1 state preserved"); + is(iframeDoc.getElementById("checkbox2").checked, false, + "checkbox #2 state preserved"); + is(iframeDoc.getElementById("textinput").value, enteredText1, + "text preserved in <input>"); + is(iframeDoc.getElementById("textarea").value, enteredText2, + "text preserved in <textarea>"); + + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug401662.html b/dom/base/test/test_bug401662.html new file mode 100644 index 0000000000..c390a80d0a --- /dev/null +++ b/dom/base/test/test_bug401662.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=401662 +--> +<head> + <title>Test for Bug 401662</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=401662">Mozilla Bug 401662</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="testframe" + src="data:text/html,<html><body>foo<style>bar</style></body></html>"> + </iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 401662 - don't serialize style elements in body into + plaintext**/ +SimpleTest.waitForExplicitFinish(); + +window.onload = function() { + const Cc = SpecialPowers.Cc; + const Ci = SpecialPowers.Ci; + + var encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"] + .createInstance(Ci.nsIDocumentEncoder); + + var doc = $("testframe").contentDocument; + + encoder.init(doc, "text/plain", encoder.OutputBodyOnly); + encoder.setCharset("UTF-8"); + + var out = encoder.encodeToString(); + + is(out, "foo", "style content serialized in plaintext?"); + + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug402150.html b/dom/base/test/test_bug402150.html new file mode 100644 index 0000000000..5c24dd6de5 --- /dev/null +++ b/dom/base/test/test_bug402150.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=402150
+-->
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <title>Test for Bug 402150</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 402150 **/
+ok(true, "The document loaded properly");
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/base/test/test_bug402150.html^headers^ b/dom/base/test/test_bug402150.html^headers^ new file mode 100644 index 0000000000..453e7e1f37 --- /dev/null +++ b/dom/base/test/test_bug402150.html^headers^ @@ -0,0 +1 @@ +Last-Modified: Fri, 2 Nov 19107 00:00:01 GMT
diff --git a/dom/base/test/test_bug403841.html b/dom/base/test/test_bug403841.html new file mode 100644 index 0000000000..390aac0397 --- /dev/null +++ b/dom/base/test/test_bug403841.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=403841 +--> +<head> + <title>Test for Bug 403841</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=403841">Mozilla Bug 403841</a> +<span id="content">abc</p> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 403841 - Crash in nsContentUtils::CreateContextualFragment when passed a non-element node as context node **/ + var t = document.getElementById("content").firstChild; + var r = document.createRange(); + r.setStart(t,0); + r.setEnd(t,3); + // make sure this doesn't crash + var f = r.createContextualFragment("<span>"); + ok(f.firstChild instanceof HTMLSpanElement, "created fragment ok"); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug403852.html b/dom/base/test/test_bug403852.html new file mode 100644 index 0000000000..30192cb1b4 --- /dev/null +++ b/dom/base/test/test_bug403852.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<html> +<head> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=403852 +--> + <title>Test for Bug 403852</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=403852">Mozilla Bug 403852</a> +<p id="display"> + <input id="fileList" type="file"></input> +</p> +<div id="content" style="display: none"> +</div> + +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var url = SimpleTest.getTestFileURL("bug403852_fileOpener.js"); +var script = SpecialPowers.loadChromeScript(url); +script.addMessageListener("file.opened", onOpened); +script.sendAsyncMessage("file.open"); + +function onOpened(message) { + var fileList = document.getElementById('fileList'); + SpecialPowers.wrap(fileList).mozSetFileArray([message.file]); + + // Make sure the file is accessible with indexed notation + var domFile = fileList.files[0]; + + is(domFile.name, "prefs.js", "fileName should be prefs.js"); + + ok("lastModifiedDate" in domFile, "lastModifiedDate must be present"); + + var d = new Date(message.mtime); + is(d.getTime(), domFile.lastModifiedDate.getTime(), "lastModifiedDate should be the same"); + + var x = new Date(); + + // In our implementation of File object, lastModifiedDate is unknown only for new objects. + // Using canvas or input[type=file] elements, we 'often' have a valid lastModifiedDate values. + // For canvas we use memory files and the lastModifiedDate is now(). + var f = new File([new Blob(['test'], {type: 'text/plain'})], "test-name"); + + var y = f.lastModifiedDate; + var z = new Date(); + + ok((x.getTime() <= y.getTime()) && (y.getTime() <= z.getTime()), "lastModifiedDate of file which does not have last modified date should be current time"); + + + var d = new Date(message.fileDate); + is(d.getTime(), message.fileWithDate.lastModifiedDate.getTime(), "lastModifiedDate should be the same when lastModified is set: " + message.fileWithDate.lastModified); + + script.destroy(); + SimpleTest.finish(); +} + +</script> +</pre> +</body> </html> diff --git a/dom/base/test/test_bug403868.xml b/dom/base/test/test_bug403868.xml new file mode 100644 index 0000000000..cb2ababff4 --- /dev/null +++ b/dom/base/test/test_bug403868.xml @@ -0,0 +1,85 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=403868 +--> +<head> + <title>Test for Bug 403868</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=403868">Mozilla Bug 403868</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ + +/** Test for Bug 403868 **/ +function createSpan(id, insertionPoint) { + var s = document.createElementNS("http://www.w3.org/1999/xhtml", "span"); + s.id = id; + $("content").insertBefore(s, insertionPoint); + return s; +} + +var s1a = createSpan("test1", null); +is(document.getElementById("test1"), s1a, + "Only one span with id=test1 in the tree; should work!"); + +var s2a = createSpan("test1", null); +is(document.getElementById("test1"), s1a, + "Appending span with id=test1 doesn't change which one comes first"); + +var s3a = createSpan("test1", s2a); +is(document.getElementById("test1"), s1a, + "Inserting span with id=test1 not at the beginning; doesn't matter"); + +var s4a = createSpan("test1", s1a); +is(document.getElementById("test1"), s4a, + "Inserting span with id=test1 at the beginning changes which one is first"); + +s4a.parentNode.removeChild(s4a); +is(document.getElementById("test1"), s1a, + "First-created span with id=test1 is first again"); + +s1a.parentNode.removeChild(s1a); +is(document.getElementById("test1"), s3a, + "Third-created span with id=test1 is first now"); + +// Start the id hashtable +for (var i = 0; i < 256; ++i) { + document.getElementById("no-such-id-in-the-document" + i); +} + +var s1b = createSpan("test2", null); +is(document.getElementById("test2"), s1b, + "Only one span with id=test2 in the tree; should work!"); + +var s2b = createSpan("test2", null); +is(document.getElementById("test2"), s1b, + "Appending span with id=test2 doesn't change which one comes first"); + +var s3b = createSpan("test2", s2b); +is(document.getElementById("test2"), s1b, + "Inserting span with id=test2 not at the beginning; doesn't matter"); + +var s4b = createSpan("test2", s1b); +is(document.getElementById("test2"), s4b, + "Inserting span with id=test2 at the beginning changes which one is first"); + +s4b.parentNode.removeChild(s4b); +is(document.getElementById("test2"), s1b, + "First-created span with id=test2 is first again"); + +s1b.parentNode.removeChild(s1b); +is(document.getElementById("test2"), s3b, + "Third-created span with id=test2 is first now"); +]]> +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug405182.html b/dom/base/test/test_bug405182.html new file mode 100644 index 0000000000..70ca5ffedd --- /dev/null +++ b/dom/base/test/test_bug405182.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=405182 +--> +<head> + <title>Test for Bug 405182</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=405182">Mozilla Bug 405182</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 405182 **/ + +function do_test() +{ + var dE = document.documentElement; + + document.addEventListener("DOMNodeRemoved", newScript, false); + + document.removeChild(dE); + + function newScript() + { + var ns = document.createElementNS("http://www.w3.org/1999/xhtml", "script"); + var nt = document.createTextNode("42;"); + ns.appendChild(nt); + dE.appendChild(ns); + ok(true, "Test is successful if we get here without crashing"); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(do_test); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug409380.html b/dom/base/test/test_bug409380.html new file mode 100644 index 0000000000..695de5f917 --- /dev/null +++ b/dom/base/test/test_bug409380.html @@ -0,0 +1,378 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=409380 +--> +<head> + <title>Test for Bug 409380</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=409380">Mozilla Bug 409380</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 409380 **/ + +function runRangeTest() +{ + // Bug 336381 + // This is a case which can't be supported (at least not at the moment) + // because DOM Range requires that when the start boundary point is text node, + // it must be splitted. But in this case boundary point doesn't have parent, + // so splitting doesn't work. + var zz = document.getElementById("connectedDiv").firstChild; + zz.parentNode.removeChild(zz); + var range = document.createRange(); + var hadException = false; + try { + range.setStart(zz, 0); + range.setEnd(zz, 0); + } catch (ex) { + hadException = true; + } + ok(!hadException , + "It should be possible to select text node even if the node is not in DOM."); + hadException = false; + try { + range.insertNode(document.createTextNode('5')); + } catch (ex) { + hadException = true; + } + ok(hadException, + "It shouldn't be possible to insert text node to a detached range."); + + // Bug 409380 + var element = document.createElement('div'); + var elementContent = "This is the element content"; + element.innerHTML = elementContent; + range = element.ownerDocument.createRange(); + hadException = false; + try { + range.selectNodeContents(element); + } catch (ex) { + hadException = true; + } + ok(!hadException, + "It should be possible to select node contents of a detached element."); + ok(range.toString() == elementContent, "Wrong range selection"); + + // range.selectNode can't succeed because selectNode sets boundary points + // to be parentNode, which in this testcase is null. + element = document.createElement('div'); + range = element.ownerDocument.createRange(); + hadException = false; + try { + range.selectNode(element); + } catch (ex) { + hadException = true; + } + ok(hadException, "It shouldn't be possible to select a detached element."); + + // Testing contextual fragment. + range = element.ownerDocument.createRange(); + var cf = null; + var testContent = "<span>foo</span><span>bar</span>"; + try { + range.selectNodeContents(element); + cf = range.createContextualFragment(testContent); + element.appendChild(cf); + } catch (ex) { + } + ok(cf, "Creating contextual fragment didn't succeed!"); + ok(element.innerHTML == testContent, "Wrong innerHTML!"); + + element = document.createElement('div'); + element.textContent = "foobar"; + range = element.ownerDocument.createRange(); + try { + range.selectNodeContents(element); + element.firstChild.insertData(3, " "); + } catch (ex) { + } + ok(range.toString() == "foo bar"); + + // Testing contextual fragment, but inserting element to document + // after creating range. + element = document.createElement('div'); + range = element.ownerDocument.createRange(); + document.body.appendChild(element); + cf = null; + testContent = "<span>foo</span><span>bar</span>"; + try { + range.selectNodeContents(element); + cf = range.createContextualFragment(testContent); + element.appendChild(cf); + } catch (ex) { + } + ok(cf, "Creating contextual fragment didn't succeed!"); + ok(element.innerHTML == testContent, "Wrong innerHTML!"); + + // Testing contextual fragment, but inserting element to document + // before creating range. + element = document.createElement('div'); + document.body.appendChild(element); + range = element.ownerDocument.createRange(); + cf = null; + testContent = "<span>foo</span><span>bar</span>"; + try { + range.selectNodeContents(element); + cf = range.createContextualFragment(testContent); + element.appendChild(cf); + } catch (ex) { + } + ok(cf, "Creating contextual fragment didn't succeed!"); + ok(element.innerHTML == testContent, "Wrong innerHTML!"); + + element = document.createElement('div'); + var range2 = element.ownerDocument.createRange(); + hadException = false; + try { + range2.selectNodeContents(element); + } catch (ex) { + hadException = true; + } + ok(!hadException, + "It should be possible to select node contents of a detached element."); + + // Now the boundary points of range are in DOM, but boundary points of + // range2 aren't. + hadException = false; + try { + range.compareBoundaryPoints(range.START_TO_START, range2); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range.compareBoundaryPoints(range.START_TO_END, range2); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range.compareBoundaryPoints(range.END_TO_START, range2); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range.compareBoundaryPoints(range.END_TO_END, range2); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.START_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.START_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.END_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.END_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + // range3 will be in document + element = document.createElement('div'); + document.body.appendChild(element); + range3 = element.ownerDocument.createRange(); + hadException = false; + try { + range3.selectNodeContents(element); + } catch (ex) { + hadException = true; + } + ok(!hadException, + "It should be possible to select node contents of a detached element."); + + hadException = false; + try { + range3.compareBoundaryPoints(range.START_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range3.compareBoundaryPoints(range.START_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range3.compareBoundaryPoints(range.END_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range3.compareBoundaryPoints(range.END_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + // range4 won't be in document + element = document.createElement('div'); + var range4 = element.ownerDocument.createRange(); + hadException = false; + try { + range4.selectNodeContents(element); + } catch (ex) { + hadException = true; + } + ok(!hadException, + "It should be possible to select node contents of a detached element."); + + hadException = false; + try { + range4.compareBoundaryPoints(range.START_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.START_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range4.compareBoundaryPoints(range.END_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + hadException = false; + try { + range4.compareBoundaryPoints(range.END_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(hadException, "Should have got an exception!"); + + // Compare range to itself. + hadException = false; + try { + range.compareBoundaryPoints(range.START_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range.compareBoundaryPoints(range.START_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range.compareBoundaryPoints(range.END_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range.compareBoundaryPoints(range.END_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + // Attach startContainer of range2 to document. + ok(range2.startContainer == range2.endContainer, "Wrong container?"); + document.body.appendChild(range2.startContainer); + + hadException = false; + try { + range2.compareBoundaryPoints(range.START_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.START_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.END_TO_START, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + hadException = false; + try { + range2.compareBoundaryPoints(range.END_TO_END, range); + } catch (ex) { + hadException = true; + } + ok(!hadException, "Shouldn't have got an exception!"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runRangeTest); + +</script> +</pre> +<div id="connectedDiv">zz</div> +</body> +</html> + diff --git a/dom/base/test/test_bug410229.html b/dom/base/test/test_bug410229.html new file mode 100644 index 0000000000..cf44983555 --- /dev/null +++ b/dom/base/test/test_bug410229.html @@ -0,0 +1,108 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=410229 +--> +<head> + <title>Test for Bug 410229</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410229">Mozilla Bug 410229</a> +<p id="display"></p> + +<span id="s"><span id="inner">Hello</span> +<div>My</div> +Kitty</span> + +<br> +<span id="s2">Hello<div>My</div><span id="inner2">Kitty</span></span> + +<br> +<span id="s3"><div id="inner3block">My</div><span id="inner3">Kitty</span></span> + +<br> +<span id="s4"><div id="inner4block">My</div></span> + +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var s = document.getElementById("s"); +var inner = document.getElementById("inner"); +var rects = s.getClientRects(); +is(s.getBoundingClientRect().top, inner.getBoundingClientRect().top, + "'"+s.id+"' "+"IB-split span should start where its first line starts"); +is(s.getClientRects().length, 3, + "'"+s.id+"' "+"IB-split span should have three CSS boxes"); +ok(rects[0].left < rects[0].right && rects[0].top < rects[0].bottom, + "'"+s.id+"' "+"IB-split span should have a non-zero width first rect"); +ok(rects[1].left < rects[1].right && rects[1].top < rects[1].bottom, + "'"+s.id+"' "+"IB-split span should have a non-zero width second rect"); +ok(rects[2].left < rects[2].right && rects[2].top < rects[2].bottom, + "'"+s.id+"' "+"IB-split span should have a non-zero width second rect"); +is(s.getBoundingClientRect().top, rects[0].top, + "'"+s.id+"' "+"IB-split span should start where its first rect starts"); +is(s.getBoundingClientRect().bottom, rects[2].bottom, + "'"+s.id+"' "+"IB-split span should end where its last rect ends"); + +s = document.getElementById("s2"); +inner = document.getElementById("inner2"); +rects = s.getClientRects(); +is(s.getBoundingClientRect().bottom, inner.getBoundingClientRect().bottom, + "'"+s.id+"' "+"IB-split span should end where its last line ends"); +is(s.getClientRects().length, 3, + "'"+s.id+"' "+"IB-split span should have three CSS boxes"); +is(s.getBoundingClientRect().bottom, rects[2].bottom, + "'"+s.id+"' "+"IB-split span should end where its last rect ends"); + +s = document.getElementById("s3"); +inner = document.getElementById("inner3"); +var block = document.getElementById("inner3block"); +rects = s.getClientRects(); +is(s.getBoundingClientRect().top, block.getBoundingClientRect().top, + "'"+s.id+"' "+"IB-split span should start where its first line starts"); +is(s.getBoundingClientRect().bottom, inner.getBoundingClientRect().bottom, + "'"+s.id+"' "+"IB-split span should end where its last line ends"); +is(s.getClientRects().length, 3, + "'"+s.id+"' "+"IB-split span should have three CSS boxes"); +is(rects[0].left, rects[0].right, + "'"+s.id+"' "+"IB-split span should have a zero width first rect"); +is(s.getBoundingClientRect().top, rects[1].top, + "'"+s.id+"' "+"IB-split span should start where its second rect starts"); + +s = document.getElementById("s4"); +block = document.getElementById("inner4block"); +rects = s.getClientRects(); +is(s.getBoundingClientRect().top, block.getBoundingClientRect().top, + "'"+s.id+"' "+"IB-split span should start where its first line starts"); +is(s.getBoundingClientRect().bottom, block.getBoundingClientRect().bottom, + "'"+s.id+"' "+"IB-split span should end where its last line ends"); +is(s.getClientRects().length, 3, + "'"+s.id+"' "+"IB-split span should have three CSS boxes"); +is(rects[0].left, rects[0].right, + "'"+s.id+"' "+"IB-split span should have a zero width first rect"); +is(s.getBoundingClientRect().bottom, rects[1].bottom, + "'"+s.id+"' "+"IB-split span should end where its block rect ends"); +/* +ok(rects[2].left == rects[2].right, + "'"+s.id+"' "+"IB-split span should have a zero width last rect"); +*/ + +/* +alert("'"+s.id+"' bounding rect:\n"+ + ' left='+s.getBoundingClientRect().left+' right='+s.getBoundingClientRect().right+' top='+s.getBoundingClientRect().top+' bottom='+s.getBoundingClientRect().bottom + '\nclient rects:\n' + + ' left='+rects[0].left+' right='+rects[0].right+' top='+rects[0].top+' bottom='+rects[0].bottom + '\n' + + ' left='+rects[1].left+' right='+rects[1].right+' top='+rects[1].top+' bottom='+rects[1].bottom + '\n' + + ' left='+rects[2].left+' right='+rects[2].right+' top='+rects[2].top+' bottom='+rects[2].bottom + '\n'); +*/ + +</script> +</pre> +</body> + +</html> diff --git a/dom/base/test/test_bug413974.html b/dom/base/test/test_bug413974.html new file mode 100644 index 0000000000..35b469d408 --- /dev/null +++ b/dom/base/test/test_bug413974.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=413974 +--> +<head> + <title>Test for Bug 413974</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=413974">Mozilla Bug 413974</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 413974 **/ +var req = new XMLHttpRequest(); +req.open("POST", window.location.href); +req.setRequestHeader("Content-Type", "text/plain; boundary=01234567890"); +req.send("Some text"); + +is(SpecialPowers.wrap(req).channel + .QueryInterface(SpecialPowers.Ci.nsIHttpChannel) + .getRequestHeader("Content-Type"), + "text/plain; boundary=01234567890", + "Charset should come before boundary"); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug414190.html b/dom/base/test/test_bug414190.html new file mode 100644 index 0000000000..09a48b9f04 --- /dev/null +++ b/dom/base/test/test_bug414190.html @@ -0,0 +1,85 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=414190 +--> +<head> + <title>Test for Bug 414190</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=414190">Mozilla Bug 414190</a> +<p id="display"></p> + +<table id="table" border="0" cellspacing="0" cellpadding="0" + style="width:100px; border:10px solid silver;"> + <tr><td id="cell" style="height:100px;"></td></tr> + <caption id="caption" style="caption-side:bottom; width:50px; height:70px; background:yellow;"></caption> +</table> + +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function isEqualRect(r1, r2, r1border, s) { + is(r1.left + r1border, r2.left, s + " (left)"); + is(r1.right - r1border, r2.right, s + " (right)"); + is(r1.top + r1border, r2.top, s + " (top)"); + is(r1.bottom - r1border, r2.bottom, s + " (bottom)"); +} + +var table = document.getElementById("table"); +var cell = document.getElementById("cell"); +var caption = document.getElementById("caption"); +var tableRects = table.getClientRects(); +var tableBoundingRect = table.getBoundingClientRect(); +var cellBoundingRect = cell.getBoundingClientRect(); +var captionBoundingRect = caption.getBoundingClientRect(); + +is(tableRects.length, 2, "Table should have rects for body and caption"); +isEqualRect(tableRects[0], cellBoundingRect, 10, + "Table first rect should be cell rect"); +isEqualRect(tableRects[1], captionBoundingRect, 0, + "Table second rect should be caption rect"); +is(cellBoundingRect.right - cellBoundingRect.left, 80, "Cell incorrect width"); +is(cellBoundingRect.bottom - cellBoundingRect.top, 100, "Cell incorrect height"); +is(captionBoundingRect.right - captionBoundingRect.left, 50, "Caption incorrect width"); +is(captionBoundingRect.bottom - captionBoundingRect.top, 70, "Caption incorrect height"); +is(captionBoundingRect.top, cellBoundingRect.bottom + 10, "Discontiguous vertical geometry"); + +is(tableBoundingRect.top, cellBoundingRect.top - 10, "Table top error"); +is(tableBoundingRect.left, cellBoundingRect.left - 10, "Table left error"); +is(tableBoundingRect.bottom, captionBoundingRect.bottom, "Table bottom error"); +is(tableBoundingRect.right, cellBoundingRect.right + 10, "Table right error"); + +caption.style.captionSide = "left"; + +tableRects = table.getClientRects(); +tableBoundingRect = table.getBoundingClientRect(); +cellBoundingRect = cell.getBoundingClientRect(); +captionBoundingRect = caption.getBoundingClientRect(); + +is(tableRects.length, 2, "Table should have rects for body and caption"); +isEqualRect(tableRects[0], cellBoundingRect, 10, + "Table first rect should be cell rect plus border"); +isEqualRect(tableRects[1], captionBoundingRect, 0, + "Table second rect should be caption rect"); +is(cellBoundingRect.right - cellBoundingRect.left, 80, "Cell incorrect width"); +is(cellBoundingRect.bottom - cellBoundingRect.top, 100, "Cell incorrect height"); +is(captionBoundingRect.right - captionBoundingRect.left, 50, "Caption incorrect width"); +is(captionBoundingRect.bottom - captionBoundingRect.top, 70, "Caption incorrect height"); +is(captionBoundingRect.right + 10, cellBoundingRect.left, "Discontiguous horizontal geometry"); +is(tableBoundingRect.top, cellBoundingRect.top - 10, "Table top error"); +is(tableBoundingRect.left, captionBoundingRect.left, "Table left error"); +is(tableBoundingRect.bottom, cellBoundingRect.bottom + 10, "Table bottom error"); +is(tableBoundingRect.right, cellBoundingRect.right + 10, "Table right error"); + +</script> +</pre> +</body> + +</html> diff --git a/dom/base/test/test_bug415860.html b/dom/base/test/test_bug415860.html new file mode 100644 index 0000000000..336bf654f5 --- /dev/null +++ b/dom/base/test/test_bug415860.html @@ -0,0 +1,240 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=415860 +--> +<head> + <title>Test for Bug 415860</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=415860">Mozilla Bug 415860</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="testdata"> </div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 415860 **/ + +function tests() { + // #text node + n = document.getElementById('testdata').firstChild; + s = getSelection(); + + // Initial text.. + n.textContent = "Hello!"; + + // select the second last character + r = document.createRange(); + r.setStart(n, 4); + r.setEnd(n, 5); + s.addRange(r); + + ok(s == "o", "Should have selected 'o'"); + ok(r.toString() == "o", "Range should be 'o'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + + // Update the text + n.textContent = "Hello!"; + + ok(s == "", "Should have selected ''"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + + // select the last character + r = document.createRange(); + r.setStart(n, 5); + r.setEnd(n, 6); + s.addRange(r); + + ok(s == "!", "Should have selected '!'"); + ok(r.toString() == "!", "Range should be '!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + + // Update the text + n.textContent = "Hello!"; + ok(s == "", "Should have selected ''"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + + r = document.createRange(); + r.setStart(n, 5); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "!", "Range should be '!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + r.setStart(n, 0); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "Hello!", "Range should be 'Hello!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.deleteData(0, 1); + ok(n.nodeValue == "ello!", "Node value should be 'ello!'"); + ok(r.toString() == "ello!", "Range should be 'ello!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.deleteData(0, 4); + ok(n.nodeValue == "!", "Node value should be '!'"); + ok(r.toString() == "!", "Range should be '!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 0); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "Hello!", "Range should be 'Hello!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.replaceData(0, 6, "hELLO?"); + ok(n.nodeValue == "hELLO?", "Node value should be 'hELLO?'"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 1); + r.setEnd(n, 3); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "el", "Range should be 'el'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.replaceData(2, 6, "END"); + ok(n.nodeValue == "HeEND", "Node value should be 'HeEND!'"); + ok(r.toString() == "e", "Range should be 'e'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 1); + r.setEnd(n, 5); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "ello", "Range should be 'ello'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.replaceData(2, 1, "MID"); + ok(n.nodeValue == "HeMIDlo!", "Node value should be 'HeMIDlo!'"); + ok(r.toString() == "eMIDlo", "Range should be 'eMIDlo'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 0); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "Hello!", "Range should be 'Hello!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "hELLO?..."; + ok(n.nodeValue == "hELLO?...", "Node value should be 'hELLO?...'"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 1); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "ello!", "Range should be 'ello!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 0); + r.setEnd(n, 5); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "Hello", "Range should be 'Hello'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "hELLO?..."; + ok(n.nodeValue == "hELLO?...", "Node value should be 'hELLO?...'"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 0); + r.setEnd(n, 5); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "Hello", "Range should be 'Hello'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "..."; + ok(n.nodeValue == "...", "Node value should be '...'"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 1); + r.setEnd(n, 5); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "ello", "Range should be 'ello'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "..."; + ok(n.nodeValue == "...", "Node value should be '...'"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + + n.textContent = "$"; + r.setStart(n, 0); + r.setEnd(n, 1); + ok(n.nodeValue == "$", "Node value should be $'"); + ok(r.toString() == "$", "Range should be '$'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "?"; + ok(n.nodeValue == "?", "Node value should be '?'"); + ok(r.toString() == "", "Range should be ''"); + ok(r.collapsed == true, "Range should be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 3); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "lo!", "Range should be 'lo!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.replaceData(1, 4, "MID"); + ok(n.nodeValue == "HMID!", "Node value should be 'HMID!'"); + ok(r.toString() == "MID!", "Range should be 'MID!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "Hello!"; + r.setStart(n, 3); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", "Node value should be 'Hello!'"); + ok(r.toString() == "lo!", "Range should be 'lo!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.replaceData(1, 2, "MID"); + ok(n.nodeValue == "HMIDlo!", "Node value should be 'HMIDlo!'"); + ok(r.toString() == "MIDlo!", "Range should be 'MIDlo!'"); + ok(r.collapsed == false, "Range shouldn't be collapsed"); + + n.textContent = "Hello!"; + r = document.createRange(); + r.setStart(n, 6); + r.setEnd(n, 6); + ok(n.nodeValue == "Hello!", " Node value should be 'Hello!'"); + ok(r.toString() == "", " Range should be ''"); + ok(r.startOffset == 6, "Start offset should be 6"); + ok(r.endOffset == 6, "End offset should be 6"); + + n.textContent = "Hello!"; + ok(n.nodeValue == "Hello!", " Node value should be 'Hello!'"); + ok(r.toString() == "", " Range should be ''"); + ok(r.startOffset == 0, "Start offset should be 0"); + ok(r.endOffset == 0, "End offset should be 0"); +} + +tests(); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug416317-1.html b/dom/base/test/test_bug416317-1.html new file mode 100644 index 0000000000..84bdc17863 --- /dev/null +++ b/dom/base/test/test_bug416317-1.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=416317 +--> +<head> + <title>Test for Bug 416317</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script> + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestLongerTimeout(3); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=416317">Mozilla Bug 416317</a> +<p id="display"> + <iframe src="file_bug416317.xhtml#target"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 416317 **/ +// Subframe handles the test +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug416317-2.html b/dom/base/test/test_bug416317-2.html new file mode 100644 index 0000000000..b0ed8e3376 --- /dev/null +++ b/dom/base/test/test_bug416317-2.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=416317 +--> +<head> + <title>Test for Bug 416317</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script> + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=416317">Mozilla Bug 416317</a> +<p id="display"> + <iframe style="display: none" src="file_bug416317.xhtml#target"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 416317 **/ +SimpleTest.requestLongerTimeout(3); +// Subframe handles the test +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug416383.html b/dom/base/test/test_bug416383.html new file mode 100644 index 0000000000..741fbf8780 --- /dev/null +++ b/dom/base/test/test_bug416383.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=416383 +--> +<head> + <title>Test for Bug 416383</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=416383">Mozilla Bug 416383</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="test_parent"><div someattr="foo"></div></div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 416383 **/ + +function runTest() { + var testParent = document.getElementById("test_parent"); + var attrs = testParent.firstChild.attributes; + ok(attrs != null, "Element should have attributes!"); + var attr = testParent.firstChild.getAttributeNode("someattr"); + ok(attr.value == "foo", "The value of the attribute should be 'foo'!"); + testParent.removeChild(testParent.firstChild); + SpecialPowers.gc(); + ok(true, "Browser should not crash!") + +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); +addLoadEvent(SimpleTest.finish); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug417255.html b/dom/base/test/test_bug417255.html new file mode 100644 index 0000000000..36be15b438 --- /dev/null +++ b/dom/base/test/test_bug417255.html @@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=417255 +--> +<head> + <title>Test for Bug 417255</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style> + .spacer { display:inline-block; height:10px; } + </style> +</head> +<body> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=417255">Mozilla Bug 417255</a> +<div id="display" style="width:800px"></div> + +<div><span id="s1" style="border:2px dotted red;"><span class="spacer" style="width:100px"></span> +<div style="width:500px; height:100px; background:yellow;"></div> +<span class="spacer" style="width:200px"></span></span></div> + +<div><span id="s2" style="border:2px dotted red;"><span class="spacer" style="width:100px"></span> +<div style="width:150px; height:100px; background:yellow;"></div> +<span class="spacer" style="width:200px"></span></span></div> + +<!-- test nested spans around the IB split --> +<div><span id="s3" style="border:2px dotted red;"><span><span class="spacer" style="width:100px"></span> +<div style="width:500px; height:100px; background:yellow;"></div> +<span class="spacer" style="width:200px"></span></span></span></div> + +<div id="content" style="display: none"> + +</div> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function getWidth(box) { + return box.right - box.left; +} + +function doTest(id, boundsWidth, w1, w2, w3) { + var s = document.getElementById(id); + is(s.offsetWidth, boundsWidth, "bad offsetWidth"); + is(getWidth(s.getBoundingClientRect()), boundsWidth, "bad getBoundingClientRect width"); + is(getWidth(s.getClientRects()[0]), w1, "bad getClientRects width"); + is(getWidth(s.getClientRects()[1]), w2, "bad getClientRects width"); + is(getWidth(s.getClientRects()[2]), w3, "bad getClientRects width"); +} + +doTest("s1", 500, 102, 500, 202); +doTest("s2", 202, 102, 150, 202); +doTest("s3", 500, 102, 500, 202); + +</script> +</pre> +</body> + +</html> diff --git a/dom/base/test/test_bug417384.html b/dom/base/test/test_bug417384.html new file mode 100644 index 0000000000..866bb88cc2 --- /dev/null +++ b/dom/base/test/test_bug417384.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=417384 +--> +<head> + <title>Test for Bug 417384</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=417384">Mozilla Bug 417384</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 417384 **/ + +var expectedSerialization = "about:blank document"; +function testSerializer() { + var doc = document.getElementById('test_iframe').contentDocument; + doc.body.textContent = expectedSerialization; + var head1 = doc.createElement("head"); + doc.body.appendChild(head1); + var span = doc.createElement("span"); + head1.appendChild(span); + span.appendChild(doc.createTextNode("before inner head\n")); + span.appendChild(doc.createElement("head")); + span.appendChild(doc.createTextNode("\nafter inner head")); + + var encoder = + SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + encoder.init(doc, "text/plain", 0); + encoder.setCharset("UTF-8"); + var out = encoder.encodeToString(); + ok(out == expectedSerialization, "Wrong serialization!"); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(testSerializer); +addLoadEvent(SimpleTest.finish); + +</script> +</pre> +<iframe id="test_iframe" src="about:blank"></iframe> +</body> +</html> + diff --git a/dom/base/test/test_bug418214.html b/dom/base/test/test_bug418214.html new file mode 100644 index 0000000000..cc0e798ff3 --- /dev/null +++ b/dom/base/test/test_bug418214.html @@ -0,0 +1,101 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=418214 +--> +<head> + <title>Test for Bug 418214</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418214">Mozilla Bug 418214</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var str = '<root xmlns:html="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:math="http://www.w3.org/1998/Math/MathML"><html:div id="d" style="border:: invalid"/><svg:svg id="s" style="border:: invalid"/><math:math id="m" style="border:: invalid"/></root>'; + +/** Test for Bug 418214 **/ +var doc = (new DOMParser()).parseFromString(str, "text/xml"); +var d = doc.getElementById("d"); +var s = doc.getElementById("s"); +var m = doc.getElementById("m"); + +is(d.getAttribute("style"), "border:: invalid", + "Shouldn't be parsing style on HTML in data documents"); +is(s.getAttribute("style"), "border:: invalid", + "Shouldn't be parsing style on SVG in data documents"); +is(m.getAttribute("style"), "border:: invalid", + "Shouldn't be parsing style on MathML in data documents"); + +var d2 = d.cloneNode(true); +var s2 = s.cloneNode(true); +var m2 = m.cloneNode(true); + +is(d2.getAttribute("style"), "border:: invalid", + "Shouldn't be parsing style on HTML on clone"); +is(s2.getAttribute("style"), "border:: invalid", + "Shouldn't be parsing style on SVG on clone"); +is(m2.getAttribute("style"), "border:: invalid", + "Shouldn't be parsing style on MathML on clone"); + +d2.style; +s2.style; +m2.style; + +is(d2.getAttribute("style"), "border:: invalid", + "Getting .style shouldn't affect style attribute on HTML"); +is(s2.getAttribute("style"), "border:: invalid", + "Getting .style shouldn't affect style attribute on SVG"); +is(m2.getAttribute("style"), "border:: invalid", + "Getting .style shouldn't affect style attribute on MathML"); + +d2.style.color = "green"; +s2.style.color = "green"; +is (m2.style, undefined, ".style shouldn't exist on MathML"); + +is(d2.getAttribute("style"), "color: green;", + "Adjusting .style should parse style on HTML"); +is(s2.getAttribute("style"), "color: green;", + "Getting .style should parse style on SVG"); + +d = document.adoptNode(d); +s = document.adoptNode(s); +m = document.adoptNode(m); + +is(d.getAttribute("style"), "border:: invalid", + "Adopting should not parse style on HTML"); +is(s.getAttribute("style"), "border:: invalid", + "Adopting should not parse style on SVG"); +is(m.getAttribute("style"), "border:: invalid", + "Adopting should not parse style on MathML"); + +$("display").appendChild(d); +$("display").appendChild(s); +$("display").appendChild(m); + +is(d.getAttribute("style"), "border:: invalid", + "Adopting should not parse style on HTML"); +is(s.getAttribute("style"), "border:: invalid", + "Adopting should not parse style on SVG"); +is(m.getAttribute("style"), "border:: invalid", + "Adopting should not parse style on MathML"); + +d.style.color = "green"; +s.style.color = "green"; +is (m.style, undefined, ".style shouldn't exist on MathML"); + +is(d.getAttribute("style"), "color: green;", + "Adjusting .style should parse style on HTML"); +is(s.getAttribute("style"), "color: green;", + "Adjusting .style should parse style on SVG"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug418986-1.html b/dom/base/test/test_bug418986-1.html new file mode 100644 index 0000000000..3ffa19fa98 --- /dev/null +++ b/dom/base/test/test_bug418986-1.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=418986 +--> +<head> + <meta charset="utf-8"> + <title>Test 1/3 for Bug 418986 - Resist fingerprinting by preventing exposure of screen and system info</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript;version=1.7" src="chrome/bug418986-1.js"></script> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418986">Bug 418986</a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"></pre> + <script> + window.onload = function() { + test(true); + }; + </script> +</body> +</html> diff --git a/dom/base/test/test_bug419132.html b/dom/base/test/test_bug419132.html new file mode 100644 index 0000000000..f38c5e08ff --- /dev/null +++ b/dom/base/test/test_bug419132.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=419132 +--> +<head> + <title>Test for Bug 419132</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=419132">Mozilla Bug 419132</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<iframe id="i"></iframe> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 419132 **/ + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + var iframe = document.getElementById("i"); + var loadCounts = 4; + iframe.addEventListener("load", function() { + if (--loadCounts == 0) { + ok(true, "This is a mochikit version of a crash test. To complete is to pass."); + SimpleTest.finish(); + } else { + // Garbage collect after every other load + if ((loadCounts % 2) == 1) { + SpecialPowers.gc(); + } + setTimeout(function() { + iframe.contentWindow.location.reload(); + }, 0); + } + }, false); + iframe.src = "bug419132.html"; +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug419527.xhtml b/dom/base/test/test_bug419527.xhtml new file mode 100644 index 0000000000..c468af0aed --- /dev/null +++ b/dom/base/test/test_bug419527.xhtml @@ -0,0 +1,74 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=419527 +--> +<head> + <title>Test for Bug 419527</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <bindings xmlns="http://www.mozilla.org/xbl" + xmlns:html="http://www.w3.org/1999/xhtml"> + <binding id="rangebinding"> + <content><html:span>Foo</html:span> + </content> + <implementation> + <constructor> + var win = XPCNativeWrapper.unwrap(window); + var span = document.getAnonymousNodes(this)[0]; + win.ok(span.localName == "span", "Wrong anon node!"); + var range = document.createRange(); + range.selectNode(span.firstChild); + win.ok(range.startContainer == span, "Wrong start container!"); + win.ok(range.endContainer == span, "Wrong end container!"); + var newSubTree = XPCNativeWrapper(win.newSubTree); + newSubTree.appendChild(this); + range.setStart(newSubTree.firstChild, 0); + win.ok(range.startContainer == newSubTree.firstChild, + "Range should have been collapsed to newSubTree.firstChild!"); + win.ok(range.endContainer == newSubTree.firstChild, + "Range should have been collapsed to newSubTree.firstChild!"); + //XXX This should just call SimpleTest.finish(), bugs 478528, 499735. + setTimeout(win.finish, 0); + </constructor> + </implementation> + </binding> + </bindings> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=419527">Mozilla Bug 419527</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ + +/** Test for Bug 419527 **/ + +var d; + +function runRangeTest() { + window.newSubTree = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); + newSubTree.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "div")); + + d = document.createElementNS("http://www.w3.org/1999/xhtml", "div"); + d.style.MozBinding = "url('" + window.location + "#rangebinding" + "')"; + document.body.appendChild(d); +} + +function finish() { + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +setTimeout(runRangeTest, 0); + + +]]> +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug420609.xhtml b/dom/base/test/test_bug420609.xhtml new file mode 100644 index 0000000000..aaa38e4399 --- /dev/null +++ b/dom/base/test/test_bug420609.xhtml @@ -0,0 +1,34 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=420609
+-->
+<head>
+ <title>Test for Bug 420609</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=420609">Mozilla Bug 420609</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ —¹…
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+
+/** Test for Bug 420609 **/
+ var request = new XMLHttpRequest();
+ request.open("GET", window.location.href, false);
+ request.send(null);
+
+ ok(request.responseXML && request.responseXML.documentElement.tagName == "html", "XMLHttpRequest should load XHTML document with entities");
+ is(document.getElementById("content").textContent, request.responseXML.getElementById("content").textContent, "Entities should be expanded in the document loaded by XMLHttpRequest");
+]]>
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/dom/base/test/test_bug420700.html b/dom/base/test/test_bug420700.html new file mode 100644 index 0000000000..c52391bb29 --- /dev/null +++ b/dom/base/test/test_bug420700.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=420700 +--> +<head> + <title>Test for Bug 420700</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=420700">Mozilla Bug 420700</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + var r = document.createRange(); + r.selectNode(document.documentElement); + + var df = r.createContextualFragment("<p>BAD</p>"); + + var display = document.getElementById("display"); + display.innerHTML = "<p>GOOD</p>"; + + var p = display.firstChild; + + is(p.textContent, "GOOD", "createContextualFragment tests"); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug421602.html b/dom/base/test/test_bug421602.html new file mode 100644 index 0000000000..eda74d02f6 --- /dev/null +++ b/dom/base/test/test_bug421602.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=421602 +--> +<head> + <title>Test for Bug 421602</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=421602">Mozilla Bug 421602</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 421602 **/ +SimpleTest.waitForExplicitFinish(); + +var img1loaded = false; +var img1errored = false; + +// Our test image +function loadTestImage() { + var img1 = new Image(); + img1.onload = function() { + img1loaded = true; + finishTest(); + } + img1.onerror = function() { + img1errored = true; + finishTest(); + } + img1.src = window.location.href + "?image1=true"; +} +loadTestImage(); + +// Probably overkill to gc() more than once, but let's be safe +SpecialPowers.gc(); SpecialPowers.gc(); SpecialPowers.gc(); + +function finishTest() { + is(img1errored, true, "Image 1 should error"); + is(img1loaded, false, "Image 1 should not load"); + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug422403-1.html b/dom/base/test/test_bug422403-1.html new file mode 100644 index 0000000000..fa6cbbd84a --- /dev/null +++ b/dom/base/test/test_bug422403-1.html @@ -0,0 +1,204 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for XHTML serializer</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422043">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<!-- IMPORTANT: This iframe needs to actually be displayed, so the serializer + sees the relevant styles for <pre> elements. --> +<iframe id="testframe" src="file_xhtmlserializer_1.xhtml"></iframe> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + +function loadFileContent(aFile, aCharset) { + //if(aAsIso == undefined) aAsIso = false; + if(aCharset == undefined) + aCharset = 'UTF-8'; + + var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1'] + .createInstance(SpecialPowers.Ci.nsIURI); + baseUri.spec = window.location.href; + + var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1'] + .getService(SpecialPowers.Ci.nsIIOService); + var chann = ios.newChannel2(aFile, + aCharset, + baseUri, + null, // aLoadingNode + SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(), + null, // aTriggeringPrincipal + SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER); + + var cis = SpecialPowers.Ci.nsIConverterInputStream; + + var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"] + .createInstance(cis); + inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER); + var str = {}, content = ''; + while (inputStream.readString(4096, str) != 0) { + content += str.value; + } + return content; +} + + +function testHtmlSerializer_1 () { + const de = SpecialPowers.Ci.nsIDocumentEncoder + var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=application/xhtml+xml"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + + var doc = SpecialPowers.wrap($("testframe")).contentDocument; + var out, expected; + + // in the following tests, we must use the OutputLFLineBreak flag, to avoid + // to have the default line break of the platform in the result, so the test + // can pass on all platform + + //------------ no flags + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_noflag.xhtml"); + is(out, expected, "test no flags"); + + //------------- unsupported flags + // since the following flags are not supported, we should + // have a result like the one without flag + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputPreformatted); + out = encoder.encodeToString(); + is(out, expected, "test OutputPreformatted"); + + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputFormatFlowed); + out = encoder.encodeToString(); + is(out, expected, "test OutputFormatFlowed"); + + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputNoScriptContent); + out = encoder.encodeToString(); + is(out, expected, "test OutputNoScriptContent"); + + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputNoFramesContent); + out = encoder.encodeToString(); + is(out, expected, "test OutputNoFramesContent"); + + + //------------ OutputWrap + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputWrap); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_wrap.xhtml"); + is(out, expected, "test OutputWrap"); + + //------------ OutputFormatted + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputFormatted); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_format.xhtml"); + is(out, expected, "test OutputFormatted"); + + //------------ OutputRaw + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputRaw); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_raw.xhtml"); + is(out, expected, "test OutputRaw"); + + //------------ OutputBodyOnly + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputBodyOnly); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_bodyonly.xhtml"); + is(out, expected, "test OutputBodyOnly"); + + + //------------ OutputAbsoluteLinks + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputAbsoluteLinks); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_links.xhtml").trim('\n'); + is(out, expected, "test OutputAbsoluteLinks"); + + //------------ OutputLFLineBreak + encoder.init(doc, "application/xhtml+xml",de.OutputLFLineBreak); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_linebreak.xhtml"); + is(out, expected, "test OutputLFLineBreak"); + + //------------ OutputCRLineBreak + encoder.init(doc, "application/xhtml+xml",de.OutputCRLineBreak); + out = encoder.encodeToString(); + expected = expected.replace(/\n/mg, "\r"); + is(out, expected, "test OutputCRLineBreak"); + + //------------ OutputLFLineBreak + OutputCRLineBreak + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputCRLineBreak); + out = encoder.encodeToString(); + expected = expected.replace(/\r/mg, "\r\n"); + is(out, expected, "test OutputLFLineBreak + OutputCRLineBreak"); + + //------------ OutputNoFormattingInPre + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputNoFormattingInPre); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_noformatpre.xhtml"); + is(out, expected, "test OutputNoFormattingInPre"); + + // ------------- nested body elements + var body2 = doc.createElement('body'); + var p = doc.createElement('p'); + p.appendChild(doc.createTextNode("this is an other body element")); + body2.appendChild(p); + var body = doc.getElementsByTagName('body')[0]; + body.appendChild(body2); + + is(doc.getElementsByTagName('body').length, 2); // to be sure we have two body elements + + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_nested_body.xhtml"); + is(out, expected, "test with two nested body elements"); + + // ------------- two body elements + body.parentNode.insertBefore(body2, body); + + is(doc.getElementsByTagName('body').length, 2); // to be sure we have two body elements + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_sibling_body.xhtml"); + is(out, expected, "test with two body elements"); + + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputBodyOnly); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_sibling_body_only_body.xhtml"); + is(out, expected, "test with two body elements, and output body only"); + + // --------------- no body element + doc.documentElement.removeChild(body); + doc.documentElement.removeChild(body2); + + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_1_no_body.xhtml"); + is(out, expected, "test with no body element"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlSerializer_1); + +</script> +</pre> +</body> +</html> + + diff --git a/dom/base/test/test_bug422403-2.xhtml b/dom/base/test/test_bug422403-2.xhtml new file mode 100644 index 0000000000..755cd72532 --- /dev/null +++ b/dom/base/test/test_bug422403-2.xhtml @@ -0,0 +1,296 @@ +<!DOCTYPE HTML> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +--> +<head> + <title>Test XHTML serializer with entities and selection</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422043">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="testframe" src="file_xhtmlserializer_2.xhtml"> + </iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +//<![CDATA[ + +function loadFileContent(aFile, aCharset) { + //if(aAsIso == undefined) aAsIso = false; + if(aCharset == undefined) + aCharset = 'UTF-8'; + + var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1'] + .createInstance(SpecialPowers.Ci.nsIURI); + baseUri.spec = window.location.href; + + var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1'] + .getService(SpecialPowers.Ci.nsIIOService); + var chann = ios.newChannel2(aFile, + aCharset, + baseUri, + null, // aLoadingNode + SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(), + null, // aTriggeringPrincipal + SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER); + + var cis = SpecialPowers.Ci.nsIConverterInputStream; + + var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"] + .createInstance(cis); + inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER); + var str = {}, content = ''; + while (inputStream.readString(4096, str) != 0) { + content += str.value; + } + return content; +} + + +function testHtmlSerializer_1 () { + const de = SpecialPowers.Ci.nsIDocumentEncoder + var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=application/xhtml+xml"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + + var doc = $("testframe").contentDocument; + var out, expected; + + // in the following tests, we must use the OutputLFLineBreak flag, to avoid + // to have the default line break of the platform in the result, so the test + // can pass on all platform + + //------------ OutputEncodeW3CEntities + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputEncodeW3CEntities); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_2_basic.xhtml"); + is(out, expected, "test OutputEncodeW3CEntities"); + + //------------ OutputEncodeBasicEntities + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputEncodeBasicEntities); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_2_basic.xhtml"); + is(out, expected, "test OutputEncodeBasicEntities"); + + //------------ OutputEncodeLatin1Entities + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputEncodeLatin1Entities); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_2_basic.xhtml"); + is(out, expected, "test OutputEncodeLatin1Entities"); + + //------------ OutputEncodeHTMLEntities + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputEncodeHTMLEntities); + out = encoder.encodeToString(); + expected = loadFileContent("file_xhtmlserializer_2_basic.xhtml"); + is(out, expected, "test OutputEncodeHTMLEntities"); + + // tests on the serialization of selections + + var node = document.getElementById('draggable'); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = 'This is a <em xmlns=\"http://www.w3.org/1999/xhtml\">draggable</em> bit of text.'; + is(out, expected, "test selection"); + + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(null); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = 'This is a <em xmlns=\"http://www.w3.org/1999/xhtml\">draggable</em> bit of text.'; + is(out, expected, "test container node"); + + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<div xmlns=\"http://www.w3.org/1999/xhtml\" id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>"; + is(out, expected, "test node"); + + node = document.getElementById('aList'); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '\n <li xmlns=\"http://www.w3.org/1999/xhtml\">Lorem ipsum dolor</li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">sit amet, <strong>consectetuer</strong> </li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">adipiscing elit</li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">aptent taciti</li>\n'; + is(out, expected, "test list selection"); + + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(null); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = '\n <li xmlns=\"http://www.w3.org/1999/xhtml\">Lorem ipsum dolor</li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">sit amet, <strong>consectetuer</strong> </li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">adipiscing elit</li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li xmlns=\"http://www.w3.org/1999/xhtml\">aptent taciti</li>\n'; + is(out, expected, "test list container node"); + + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<ol xmlns=\"http://www.w3.org/1999/xhtml\" id=\"aList\">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>"; + is(out, expected, "test list node"); + + var liList = node.getElementsByTagName("li"); + var range = document.createRange(); + + // selection start at the first child of the ol, and end after the element ol + range.setStart(node, 1); + range.setEnd(node.parentNode, 2); + select.removeAllRanges(); + select.addRange(range); + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol xmlns=\"http://www.w3.org/1999/xhtml\" id="aList"><li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the first child of the ol, and end after the element ol"); + + // selection start at the third child of the ol, and end after the element ol + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol xmlns=\"http://www.w3.org/1999/xhtml\" id="aList"><li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol"); + + + // selection start at the third child of the ol, and end after the element ol + ol start at the value 5 + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + node.setAttribute("start","5"); + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol xmlns=\"http://www.w3.org/1999/xhtml\" id="aList" start="5"><li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol + ol start at the value 5"); + + + // selection contains only some child of the ol + node.removeAttribute("start"); + range.setStart(node, 3); + range.setEnd(node, 5); + encoder.init(document, "application/xhtml+xml", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li xmlns=\"http://www.w3.org/1999/xhtml\">sit amet, <strong>consectetuer</strong> </li>\n '; + is(out, expected, "test list selection with range: selection contains only some child of the ol"); + + + // test on short attributes + + node = document.getElementById('shortattr1'); + encoder.init(document, "application/xhtml+xml",de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<input xmlns="http://www.w3.org/1999/xhtml" id="shortattr1" checked="checked" value="" disabled="disabled" ismap="ismap" readonly="readonly" foo:checked="" xmlns:foo="http://mozilla.org/ns/any" foo:disabled="" />'; + is(out, expected, "test short attr #1"); + + node = document.getElementById('shortattr2'); + encoder.init(document, "application/xhtml+xml",de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<ol xmlns="http://www.w3.org/1999/xhtml" id="shortattr2" compact="compact"><li></li></ol>'; + is(out, expected, "test short attr #2"); + + node = document.getElementById('shortattr3'); + encoder.init(document, "application/xhtml+xml",de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<object xmlns="http://www.w3.org/1999/xhtml" id="shortattr3" declare="declare"></object>'; + is(out, expected, "test short attr #3"); + + node = document.getElementById('shortattr4'); + encoder.init(document, "application/xhtml+xml",de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<script xmlns="http://www.w3.org/1999/xhtml" id="shortattr4" defer="defer"></script>'; + is(out, expected, "test short attr #4"); + + node = document.getElementById('shortattr5'); + encoder.init(document, "application/xhtml+xml",de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<select xmlns="http://www.w3.org/1999/xhtml" id="shortattr5" multiple="multiple"><option selected="selected">aaa</option></select>'; + is(out, expected, "test short attr #5"); + + node = document.getElementById('shortattr6'); + encoder.init(document, "application/xhtml+xml",de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<hr xmlns="http://www.w3.org/1999/xhtml" id="shortattr6" noshade="noshade" />'; + is(out, expected, "test short attr #6"); + + node = document.getElementById('shortattr7'); + encoder.init(document, "application/xhtml+xml",de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<div xmlns="http://www.w3.org/1999/xhtml" id="shortattr7"><foo:bar xmlns:foo="http://mozilla.org/ns/any" checked="" value="" disabled="" ismap="" readonly=""/></div>'; + is(out, expected, "test short attr #7"); + + // test on _moz and -moz attr + node = document.getElementById('mozattr'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<div id="mozattr" __moz_b="b"> lorem ipsum</div>'; + is(out, expected, "test -moz/_moz attr"); + + node.setAttribute('_moz_c','barc'); + node.setAttribute('_-moz_d','bard'); + node.setAttribute('__moz_e','bare'); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<div id="mozattr" __moz_b="b" _-moz_d="bard" __moz_e="bare"> lorem ipsum</div>'; + is(out, expected, "test -moz/_moz attr #2"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlSerializer_1); +//]]> +</script> +</pre> +<div style="display: none"> + +<div id="draggable" ondragstart="doDragStartSelection(event)">This is a <em>draggable</em> bit of text.</div> + +</div> +<div style="display: none"> + +<ol id="aList"> + <li>Lorem ipsum dolor</li> + <li>sit amet, <strong>consectetuer</strong> </li> + <li>adipiscing elit</li> + <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li> + <li>aptent taciti</li> +</ol> + +<!-- test for some short attr --> +<div id="shortattr" xmlns:foo="http://mozilla.org/ns/any"> + <input id="shortattr1" checked="" value="" disabled="" ismap="" readonly="" foo:checked="" foo:disabled=""/> + <ol id="shortattr2" compact=""><li></li></ol> + <object id="shortattr3" declare="" /> + <script id="shortattr4" defer="" /> + <select id="shortattr5" multiple=""><option selected="">aaa</option></select> + <hr id="shortattr6" noshade=""/> + <div id="shortattr7"><foo:bar checked="" value="" disabled="" ismap="" readonly="" /></div> + <div id="mozattr" _moz_a="a" __moz_b="b"> lorem ipsum</div> +</div> + +</div> +</body> +</html> + + diff --git a/dom/base/test/test_bug422537.html b/dom/base/test/test_bug422537.html new file mode 100644 index 0000000000..351fcfa242 --- /dev/null +++ b/dom/base/test/test_bug422537.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=422537 +--> +<head> + <title>Test for bug 422537</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422537">Mozilla Bug 422537</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 422537 **/ +var isupports_string = SpecialPowers.Cc["@mozilla.org/supports-string;1"] + .createInstance(SpecialPowers.Ci.nsISupportsString); +isupports_string.data = "foo"; + +const url = "http://mochi.test:8888"; +var body = [ + document, + "foo", + isupports_string +]; + +for (var i of body) { + var xhr = new XMLHttpRequest(); + xhr.open("POST", url, true); + if (i == isupports_string) + SpecialPowers.wrap(xhr).send(i); + else + xhr.send(i); + var chan = SpecialPowers.wrap(xhr).channel; + if (!SpecialPowers.call_Instanceof(chan, SpecialPowers.Ci.nsIUploadChannel)) + throw "Must be an upload channel"; + var stream = chan.uploadStream; + if (!stream || !SpecialPowers.call_Instanceof(stream, SpecialPowers.Ci.nsISeekableStream)) + throw "Stream must be seekable"; + // the following is a no-op, but should not throw an exception + stream.seek(SpecialPowers.Ci.nsISeekableStream.NS_SEEK_CUR, 0); +} + +ok(true, "xhr is seekable"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug424212.html b/dom/base/test/test_bug424212.html new file mode 100644 index 0000000000..ae8c2236c0 --- /dev/null +++ b/dom/base/test/test_bug424212.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=424212 +--> +<head> + <title>Test for Bug 424212</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=424212">Mozilla Bug 424212</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 424212 **/ +var fired = false; +var xhr = new XMLHttpRequest(); +xhr.open("GET", window.location.href + "?" + Math.random()); +xhr.send(""); +xhr.onreadystatechange = function () { + fired = true; + is(xhr.status, 0, "Unexpected status"); +} +xhr.abort(); +is(fired, true, "No onreadystatechange handling?"); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug424359-1.html b/dom/base/test/test_bug424359-1.html new file mode 100644 index 0000000000..1ee8164f6e --- /dev/null +++ b/dom/base/test/test_bug424359-1.html @@ -0,0 +1,213 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for HTML serializer</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=424359">Mozilla Bug </a> +<p id="display"></p> +<!-- IMPORTANT: This iframe needs to actually be displayed, so the serializer + sees the relevant styles for <pre> elements. --> +<iframe id="testframe" src="file_htmlserializer_1.html"></iframe> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + +function loadFileContent(aFile, aCharset) { + //if(aAsIso == undefined) aAsIso = false; + if(aCharset == undefined) + aCharset = 'UTF-8'; + + var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1'] + .createInstance(SpecialPowers.Ci.nsIURI); + baseUri.spec = window.location.href; + + var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1'] + .getService(SpecialPowers.Ci.nsIIOService); + var chann = ios.newChannel2(aFile, + aCharset, + baseUri, + null, // aLoadingNode + SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(), + null, // aTriggeringPrincipal + SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER); + + var cis = SpecialPowers.Ci.nsIConverterInputStream; + + var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"] + .createInstance(cis); + inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER); + var str = {}, content = ''; + while (inputStream.readString(4096, str) != 0) { + content += str.value; + } + return content; +} + +function isRoughly(actual, expected, message) { + return is(actual.replace("<!DOCTYPE HTML", "<!DOCTYPE html"), + expected, + message); +} + +function testHtmlSerializer_1 () { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + + var doc = $("testframe").contentDocument; + var out, expected; + + // in the following tests, we must use the OutputLFLineBreak flag, to avoid + // to have the default line break of the platform in the result, so the test + // can pass on all platform + + //------------ no flags + encoder.init(doc, "text/html", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_noflag.html"); + isRoughly(out, expected, "test no flags"); + + //------------- unsupported flags + // since the following flags are not supported, we should + // have a result like the one without flag + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputPreformatted); + out = encoder.encodeToString(); + isRoughly(out, expected, "test OutputPreformatted"); + + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputFormatFlowed); + out = encoder.encodeToString(); + isRoughly(out, expected, "test OutputFormatFlowed"); + + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputNoScriptContent); + out = encoder.encodeToString(); + isRoughly(out, expected, "test OutputNoScriptContent"); + + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputNoFramesContent); + out = encoder.encodeToString(); + isRoughly(out, expected, "test OutputNoFramesContent"); + + + //------------ OutputWrap + encoder.init(doc, "text/html", de.OutputLFLineBreak |de.OutputWrap); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_wrap.html"); + isRoughly(out, expected, "test OutputWrap"); + + //------------ OutputFormatted + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputFormatted); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_format.html"); + isRoughly(out, expected, "test OutputFormatted"); + + //------------ OutputRaw + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputRaw); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_raw.html"); + isRoughly(out, expected, "test OutputRaw"); + + //------------ OutputBodyOnly + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputBodyOnly); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_bodyonly.html"); + isRoughly(out, expected, "test OutputBodyOnly"); + + + + //------------ OutputAbsoluteLinks + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputAbsoluteLinks); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_links.html").trim('\n'); + isRoughly(out, expected, "test OutputAbsoluteLinks"); + + //------------ OutputLFLineBreak + encoder.init(doc, "text/html",de.OutputLFLineBreak); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_linebreak.html"); + isRoughly(out, expected, "test OutputLFLineBreak"); + + //------------ OutputCRLineBreak + encoder.init(doc, "text/html",de.OutputCRLineBreak); + out = encoder.encodeToString(); + expected = expected.replace(/\n/mg, "\r"); + isRoughly(out, expected, "test OutputCRLineBreak"); + + //------------ OutputLFLineBreak + OutputCRLineBreak + encoder.init(doc, "text/html",de.OutputLFLineBreak | de.OutputCRLineBreak); + out = encoder.encodeToString(); + expected = expected.replace(/\r/mg, "\r\n"); + isRoughly(out, expected, "test OutputLFLineBreak + OutputCRLineBreak"); + + //------------ OutputNoFormattingInPre + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputNoFormattingInPre); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_noformatpre.html"); + isRoughly(out, expected, "test OutputNoFormattingInPre"); + + // ------------- nested body elements + var body2 = doc.createElement('body'); + var p = doc.createElement('p'); + p.appendChild(doc.createTextNode("this is an other body element")); + body2.appendChild(p); + var body = doc.getElementsByTagName('body')[0]; + body.appendChild(body2); + + is(doc.getElementsByTagName('body').length, 2); // to be sure we have two body elements + + encoder.init(doc, "text/html", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_nested_body.html"); + isRoughly(out, expected, "test with two nested body elements"); + + // ------------- two body elements + body.parentNode.insertBefore(body2, body); + + is(doc.getElementsByTagName('body').length, 2); // to be sure we have two body elements + encoder.init(doc, "text/html", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_sibling_body.html"); + isRoughly(out, expected, "test with two body elements"); + + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputBodyOnly); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_sibling_body_only_body.html"); + isRoughly(out, expected, "test with two body elements, and output body only"); + + // --------------- no body element + doc.documentElement.removeChild(body); + doc.documentElement.removeChild(body2); + + encoder.init(doc, "text/html", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_1_no_body.html"); + isRoughly(out, expected, "test with no body element"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlSerializer_1); + +</script> +</pre> +<!--<h1>1</h1><h2>result</h2><textarea id="t1" cols="80" rows="20"></textarea> + <h2>expected</h2><textarea id="t1e" cols="80" rows="20"></textarea>--> + +</body> +</html> + + diff --git a/dom/base/test/test_bug424359-2.html b/dom/base/test/test_bug424359-2.html new file mode 100644 index 0000000000..5c62327185 --- /dev/null +++ b/dom/base/test/test_bug424359-2.html @@ -0,0 +1,320 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test HTML serializer with entities</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=424359">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="testframe" src="file_htmlserializer_2.html"> + </iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + +function loadFileContent(aFile, aCharset) { + //if(aAsIso == undefined) aAsIso = false; + if(aCharset == undefined) + aCharset = 'UTF-8'; + + var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1'] + .createInstance(SpecialPowers.Ci.nsIURI); + baseUri.spec = window.location.href; + + var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1'] + .getService(SpecialPowers.Ci.nsIIOService); + var chann = ios.newChannel2(aFile, + aCharset, + baseUri, + null, // aLoadingNode + SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(), + null, // aTriggeringPrincipal + SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER); + + var cis = SpecialPowers.Ci.nsIConverterInputStream; + + var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"] + .createInstance(cis); + inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER); + var str = {}, content = ''; + while (inputStream.readString(4096, str) != 0) { + content += str.value; + } + return content; +} + +function isRoughly(actual, expected, message) { + return is(actual.replace("<!DOCTYPE HTML", "<!DOCTYPE html"), + expected, + message); +} + +function testHtmlSerializer_1 () { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + + var doc = $("testframe").contentDocument; + var out, expected; + + // in the following tests, we must use the OutputLFLineBreak flag, to avoid + // to have the default line break of the platform in the result, so the test + // can pass on all platform + + //------------ OutputEncodeW3CEntities + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputEncodeW3CEntities); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_2_entw3c.html"); + isRoughly(out, expected, "test OutputEncodeW3CEntities"); + + //------------ OutputEncodeBasicEntities + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputEncodeBasicEntities); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_2_basic.html"); + isRoughly(out, expected, "test OutputEncodeBasicEntities"); + + //------------ OutputEncodeLatin1Entities + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputEncodeLatin1Entities); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_2_latin1.html"); + isRoughly(out, expected, "test OutputEncodeLatin1Entities"); + + //------------ OutputEncodeHTMLEntities + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputEncodeHTMLEntities); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_2_enthtml.html"); + isRoughly(out, expected, "test OutputEncodeHTMLEntities"); + + + // tests on the serialization of selections + + var node = document.getElementById('draggable'); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = 'This is a <em>draggable</em> bit of text.'; + is(out, expected, "test selection"); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(null); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = 'This is a <em>draggable</em> bit of text.'; + is(out, expected, "test container node"); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>"; + is(out, expected, "test node"); + + node = document.getElementById('aList'); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n'; + is(out, expected, "test list selection"); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(null); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = '\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n'; + is(out, expected, "test list container node"); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<ol id=\"aList\">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>"; + is(out, expected, "test list node"); + + var liList = node.getElementsByTagName("li"); + var range = document.createRange(); + + // selection start at the first child of the ol, and end after the element ol + range.setStart(node, 1); + range.setEnd(node.parentNode, 2); + select.removeAllRanges(); + select.addRange(range); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id="aList"><li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the first child of the ol, and end after the element ol"); + + // selection start at the third child of the ol, and end after the element ol + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id="aList"><li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol"); + + + // selection start at the third child of the ol, and end after the element ol + ol start at the value 5 + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + node.setAttribute("start","5"); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id="aList" start="5"><li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol + ol start at the value 5"); + + + // selection contains only some child of the ol + node.removeAttribute("start"); + range.setStart(node, 3); + range.setEnd(node, 5); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + is(out, expected, "test list selection with range: selection contains only some child of the ol"); + + // selection contains only some child of the ol + ol start at the value 5 + node.setAttribute("start","5"); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + is(out, expected, "test list selection with range: selection contains only some child of the ol + ol start at the value 5"); + + // selection contains only some child of the ol + a value is set on the first li + node.removeAttribute("start"); + liList[0].setAttribute("value","8"); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + is(out, expected, "test list selection with range: selection contains only some child of the ol + ol start at the value 5"); + + + + // test on short attributes + node = document.getElementById('shortattr1'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<input id="shortattr1" checked="checked" value="" disabled="disabled" ismap="ismap" readonly="readonly" foo="">'; + is(out, expected, "test short attr #1"); + + node = document.getElementById('shortattr2'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<ol id="shortattr2" compact="compact"><li></li></ol>'; + is(out, expected, "test short attr #2"); + + node = document.getElementById('shortattr3'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<object id="shortattr3" declare="declare"></object>'; + is(out, expected, "test short attr #3"); + + node = document.getElementById('shortattr4'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<script id="shortattr4" defer="defer"></'+ 'script>'; + is(out, expected, "test short attr #4"); + + node = document.getElementById('shortattr5'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<select id="shortattr5" multiple="multiple"><option selected="selected">aaa</option></select>'; + is(out, expected, "test short attr #5"); + + node = document.getElementById('shortattr6'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<hr id="shortattr6" noshade="noshade">'; + is(out, expected, "test short attr #6"); + + node = document.getElementById('shortattr7'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<div id="shortattr7"><foo checked="" value="" disabled="" ismap="" readonly=""></foo></div>'; + is(out, expected, "test short attr #7"); + + // test on _moz and -moz attr + node = document.getElementById('mozattr'); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<div id="mozattr" __moz_b="b"> lorem ipsum</div>'; + is(out, expected, "test -moz/_moz attr"); + + node.setAttribute('_moz_c','barc'); + node.setAttribute('_-moz_d','bard'); + node.setAttribute('__moz_e','bare'); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly | de.OutputRaw); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = '<div id="mozattr" __moz_b="b" _-moz_d="bard" __moz_e="bare"> lorem ipsum</div>'; + is(out, expected, "test -moz/_moz attr #2"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlSerializer_1); + +</script> +</pre> +<div style="display: none"> + +<div id="draggable" ondragstart="doDragStartSelection(event)">This is a <em>draggable</em> bit of text.</div> + +</div> +<div style="display: none"> + +<ol id="aList"> + <li>Lorem ipsum dolor</li> + <li>sit amet, <strong>consectetuer</strong> </li> + <li>adipiscing elit</li> + <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li> + <li>aptent taciti</li> +</ol> + + +<!-- test for some short attr --> +<div id="shortattr"> + <input id="shortattr1" checked="" value="" disabled="" ismap="" readonly="" foo=""> + <ol id="shortattr2" compact=""><li></li></ol> + <object id="shortattr3" declare=""></object> + <script id="shortattr4" defer=""></script> + <select id="shortattr5" multiple=""><option selected="">aaa</option></select> + <hr noshade="" id="shortattr6"> + <div id="shortattr7"><foo checked="" value="" disabled="" ismap="" readonly=""></div> + <div id="mozattr" _moz_a="a" __moz_b="b"> lorem ipsum</div> +</div> + + + +</div> +</body> +</html> diff --git a/dom/base/test/test_bug426308.html b/dom/base/test/test_bug426308.html new file mode 100644 index 0000000000..29367adc14 --- /dev/null +++ b/dom/base/test/test_bug426308.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=426308 +--> +<head> + <title>Test for Bug 426308</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=426308">Mozilla Bug 426308</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 426308 **/ + +const SJS_URL = "http://example.org:80/tests/dom/base/test/bug426308-redirect.sjs"; + +function startTest() { + var req = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + req.open("GET", SJS_URL + "?" + window.location.href, false); + req.send(null); + + is(req.status, 200, "Redirect did not happen"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], startTest); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug426646.html b/dom/base/test/test_bug426646.html new file mode 100644 index 0000000000..63aea6cd15 --- /dev/null +++ b/dom/base/test/test_bug426646.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=426646 +--> +<head> + <title>Test for Bug 426646</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=426646">Mozilla Bug 426646</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 426646 **/ + +var testNumber = 0; +var testCount = 2; + +function nextTest() { + if (++testNumber <= testCount) { + window.open("file_bug426646-" + testNumber + ".html", "", "width=100,height=100"); + } else { + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(nextTest); + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug428847.html b/dom/base/test/test_bug428847.html new file mode 100644 index 0000000000..e96e69e620 --- /dev/null +++ b/dom/base/test/test_bug428847.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=428847 +--> +<head> + <title>Test for Bug 428847</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="runtests();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=428847">Mozilla Bug 428847</a> +<script class="testbody" type="text/javascript"> +var iframe1Loaded = false; +var iframe2Loaded = false; + +function runtests() +{ + todo(iframe1Loaded, true, + "Iframe with cross-origin xslt stylesheet failed to load"); + is(iframe2Loaded, false, + "Iframe with invalid xslt stylesheet URI didn't fail to load"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +</script> +<iframe src="file_bug428847-1.xhtml"> +<iframe src="file_bug428847-2.xhtml"> +</body> +</html> + diff --git a/dom/base/test/test_bug429157.html b/dom/base/test/test_bug429157.html new file mode 100644 index 0000000000..1c01eb8806 --- /dev/null +++ b/dom/base/test/test_bug429157.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=429157 +--> +<head> + <title>Test for Bug 429157</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="runtests();"> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=429157">Mozilla Bug 429157</a> +<br> + +<script> +var missingPlugins = new Array(); +const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent; + +function pluginBindingAttached(event) +{ + var plugin = event.target; + plugin instanceof OBJLC; + if (SpecialPowers.wrap(plugin).pluginFallbackType == OBJLC.PLUGIN_UNSUPPORTED) + missingPlugins.push(plugin); +} + +document.addEventListener("PluginBindingAttached", pluginBindingAttached, true); +</script> + +<object id="obj1" type="image/png" >ALT image/png</object><br> +<object id="obj2" type="image/svg+xml">ALT image/svg+xml</object><br> +<object id="obj3" type="text/html" >ALT text/html</object><br> +<object id="obj4" type="text/plain" >ALT text/plain</object><br> + +<script class="testbody" type="text/javascript"> +function runtests() +{ + for (var obj of document.querySelectorAll("object")) { + obj.clientTop; + } + + SimpleTest.executeSoon(function () { + is(missingPlugins.length, 0, "There should be no missing plugins for this page"); + + SimpleTest.finish(); + }); +} + +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug431082.html b/dom/base/test/test_bug431082.html new file mode 100644 index 0000000000..081226bbbe --- /dev/null +++ b/dom/base/test/test_bug431082.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=431082 +--> +<head> + <title>Test for Bug 431082</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=431082">Mozilla Bug 431082</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 431082 **/ + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { ok(true, "browser should not crash."); }); +addLoadEvent(SimpleTest.finish); + +</script> +</pre> +<!-- +<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> +<box id="a" observes="b"> + <box id="b"/> +</box> + +<box id="a" src="javascript:"/> +<box id="b" src="javascript://"/> +<editor observes="a"/> + +<script> +function doe() { +window.addEventListener('DOMAttrModified', function() +{window.frameElement.parentNode.removeChild(window.frameElement);}, true); +document.documentElement.appendChild(document.getElementsByTagName('box')[0]); +} +setTimeout(doe,0); +</script> +</window> +--> +<iframe src="data:application/vnd.mozilla.xul+xml;charset=utf-8,%3Cwindow%20xmlns%3D%22http%3A//www.mozilla.org/keymaster/gatekeeper/there.is.only.xul%22%3E%0A%3Cbox%20%20id%3D%22a%22%20observes%3D%22b%22%3E%0A%20%20%3Cbox%20id%3D%22b%22/%3E%0A%3C/box%3E%0A%0A%3Cbox%20%20id%3D%22a%22%20%20src%3D%22javascript%3A%22/%3E%0A%3Cbox%20id%3D%22b%22%20src%3D%22javascript%3A//%22/%3E%0A%3Ceditor%20observes%3D%22a%22/%3E%0A%0A%3Cscript%3E%20%0Afunction%20doe%28%29%20%7B%0Awindow.addEventListener%28%27DOMAttrModified%27%2C%20function%28%29%20%7Bwindow.frameElement.parentNode.removeChild%28window.frameElement%29%3B%7D%2C%20true%29%3B%0Adocument.documentElement.appendChild%28document.getElementsByTagName%28%27box%27%29%5B0%5D%29%3B%0A%7D%0AsetTimeout%28doe%2C0%29%3B%0A%3C/script%3E%0A%3C/window%3E" style="width:1000px;height: 300px;"></iframe> +</body> +</html> + diff --git a/dom/base/test/test_bug431701.html b/dom/base/test/test_bug431701.html new file mode 100644 index 0000000000..19947c147e --- /dev/null +++ b/dom/base/test/test_bug431701.html @@ -0,0 +1,120 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=431701 +--> +<head> + <meta charset="windows-1252"> + <title>Test for Bug 431701</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=431701">Mozilla Bug 431701</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="one"></iframe> + <iframe id="two"></iframe> + <iframe id="three"></iframe> + <iframe id="four"></iframe> + <iframe id="five"></iframe> + <iframe id="six"></iframe> + <iframe id="seven"></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 431701 **/ +SimpleTest.waitForExplicitFinish(); + +var docSources = [ + "data:text/html,<html></html>", + "data:text/html;charset=UTF-8,<html></html>", + "data:text/html;charset=ISO-8859-1,<html></html>", + "data:text/xml,<html></html>", + "data:text/xml,<?xml version='1.0'?><html></html>", + "data:text/xml,<?xml version='1.0' encoding='UTF-8'?><html></html>", + "data:text/xml,<?xml version='1.0' encoding='ISO-8859-1'?><html></html>", +]; + +for (var i = 0; i < docSources.length; ++i) { + document.getElementsByTagName("iframe")[i].src = docSources[i]; +} + +function frameDoc(id) { + return function() { return $(id).contentDocument; }; +} + +function createDoc() { + return document.implementation.createDocument('', 'html', null); +} + +function xhrDoc(idx) { + return function() { + // Defy same-origin restrictions! + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open("GET", docSources[idx], false); + xhr.send(); + return xhr.responseXML; + }; +} + +// Each row has the document getter function, then the characterSet, +// inputEncoding expected for that document. + +var tests = [ + [ frameDoc("one"), "windows-1252" ], + [ frameDoc("two"), "UTF-8" ], + [ frameDoc("three"), "windows-1252" ], + [ frameDoc("four"), "UTF-8" ], + [ frameDoc("five"), "UTF-8" ], + [ frameDoc("six"), "UTF-8" ], + [ frameDoc("seven"), "windows-1252" ], + [ createDoc, "UTF-8" ], + [ xhrDoc(4), "UTF-8" ], + [ xhrDoc(5), "UTF-8" ], + [ xhrDoc(6), "windows-1252" ], +]; + +function doTest(idx) { + var [docGetter, expectedCharacterSet] = tests[idx]; + var doc = docGetter(); + + // Have to be careful here to catch null vs "" + is(doc.characterSet, expectedCharacterSet, "Test " + idx + " characterSet"); + is(doc.inputEncoding, expectedCharacterSet, + "Test " + idx + " inputEncoding"); +} + +addLoadEvent(function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], startTest); +}); + +function startTest() { + // sanity check + isnot("", null, "Shouldn't be equal!"); + + for (var i = 0; i < tests.length; ++i) { + doTest(i); + } + + // Now check what xhr does + var xhr = new XMLHttpRequest(); + xhr.open("POST", document.location.href); + xhr.send(createDoc()); + is(SpecialPowers.wrap(xhr).channel.QueryInterface(SpecialPowers.Ci.nsIHttpChannel) + .getRequestHeader("Content-Type"), + "application/xml;charset=UTF-8", "Testing correct type on the wire"); + xhr.abort(); + + SimpleTest.finish(); +}; + + + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug431833.html b/dom/base/test/test_bug431833.html new file mode 100644 index 0000000000..24c2367b64 --- /dev/null +++ b/dom/base/test/test_bug431833.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=431833 +--> +<head> + <title>Test for Bug 431833</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <script> + var loadsComplete = []; + function test(e) { + loadsComplete[e.target.id] = true; + } + window.addEventListener('DOMFrameContentLoaded',test,true); + </script> +</head> +<body> + +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=431833">Mozilla Bug 431833</a> +<p id="display"> + <iframe id="f1" src="data:text/html,1"></iframe> + <iframe id="f2" src="data:text/html,2"></iframe> + <iframe id="f3" src="data:text/html,<iframe id='f4' src='data:text/html,3'></iframe>"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 431833 **/ + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + function check(id) { + ok(loadsComplete[id], "DOMFrameContentLoaded didn't fire for " + id); + } + check("f1"); + check("f2"); + check("f3"); + check("f4"); + }); + +addLoadEvent(SimpleTest.finish); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug433533.html b/dom/base/test/test_bug433533.html new file mode 100644 index 0000000000..8eb13c73ae --- /dev/null +++ b/dom/base/test/test_bug433533.html @@ -0,0 +1,300 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=433533 +--> +<head> + <title>Test for Bug 433533</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=433533">Mozilla Bug 433533</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 433533 **/ + +var input = document.createElement("input"); +input.setAttribute("type", "hidden"); +is(input.getAttribute("type"), "hidden", "Setting type attribute didn't work!"); +input.setAttribute("type", "hiDDen"); +is(input.getAttribute("type"), "hiDDen", "Type attribute didn't store the original value"); +is(input.type, "hidden", "Wrong input.type!"); +input.setAttribute("type", "HIDDEN"); +is(input.getAttribute("type"), "HIDDEN", "Type attribute didn't store the original value"); +is(input.type, "hidden", "Wrong input.type!"); + +var td = document.createElement("td"); +td.setAttribute("scope", "rOW"); +is(td.getAttribute("scope"), "rOW", "Scope attribute didn't store the original value"); +td.setAttribute("scope", "row"); +is(td.getAttribute("scope"), "row", "Scope attribute didn't store the original value"); +td.setAttribute("colspan", "100k"); +is(td.getAttribute("colspan"), "100k", "Colspan attribute didn't store the original value"); +td.setAttribute("colspan", " 100 "); +is(td.getAttribute("colspan"), " 100 ", "Colspan attribute didn't store the original value"); +td.setAttribute("colspan", "100"); +is(td.getAttribute("colspan"), "100", "Colspan attribute didn't store the original value"); + +// Note, if colspan is negative, it is set to 1, because of backwards compatibility. +// @see nsHTMLTableCellElement::ParseAttribute +td.setAttribute("colspan", "-100k"); +is(td.getAttribute("colspan"), "-100k", "Colspan attribute didn't store the original value"); +td.setAttribute("colspan", " -100 "); +is(td.getAttribute("colspan"), " -100 ", "Colspan attribute didn't store the original value"); +is(td.colSpan, 1, "Colspan reflection should be correct for ' -100 '"); +td.setAttribute("colspan", "-100"); +is(td.getAttribute("colspan"), "-100", "Colspan attribute didn't store the original value"); +is(td.colSpan, 1, "Colspan reflection should be correct for '-100'"); + + +td.setAttribute("colspan", "foobar"); +is(td.getAttribute("colspan"), "foobar", "Colspan attribute didn't store the original value"); + +var iframe = document.createElement("iframe"); +iframe.setAttribute("marginwidth", "50%"); +is(iframe.getAttribute("marginwidth"), "50%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "50"); +is(iframe.getAttribute("marginwidth"), "50", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "0"); +is(iframe.getAttribute("marginwidth"), "0", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "0%"); +is(iframe.getAttribute("marginwidth"), "0%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "9999999999999999999999"); +is(iframe.getAttribute("marginwidth"), "9999999999999999999999", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "9999999999999999999999%"); +is(iframe.getAttribute("marginwidth"), "9999999999999999999999%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "-9999999999999999999999"); +is(iframe.getAttribute("marginwidth"), "-9999999999999999999999", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-9999999999999999999999%"); +is(iframe.getAttribute("marginwidth"), "-9999999999999999999999%", + "Marginwidth attribute didn't store the original value"); + + +// Test PRInt32 min/max value +iframe.setAttribute("marginwidth", "2147483647"); +is(iframe.getAttribute("marginwidth"), "2147483647", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "2147483647%"); +is(iframe.getAttribute("marginwidth"), "2147483647%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "-2147483648"); +is(iframe.getAttribute("marginwidth"), "-2147483648", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-2147483648%"); +is(iframe.getAttribute("marginwidth"), "-2147483648%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "2147483646"); +is(iframe.getAttribute("marginwidth"), "2147483646", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "2147483647%"); +is(iframe.getAttribute("marginwidth"), "2147483647%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "-2147483647"); +is(iframe.getAttribute("marginwidth"), "-2147483647", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-2147483647%"); +is(iframe.getAttribute("marginwidth"), "-2147483647%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "2147483648"); +is(iframe.getAttribute("marginwidth"), "2147483648", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "2147483648%"); +is(iframe.getAttribute("marginwidth"), "2147483648%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "-2147483649"); +is(iframe.getAttribute("marginwidth"), "-2147483649", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-2147483649%"); +is(iframe.getAttribute("marginwidth"), "-2147483649%", + "Marginwidth attribute didn't store the original value"); + +// some values 0 > x > NS_ATTRVALUE_INTEGERTYPE_MAXVALUE +iframe.setAttribute("marginwidth", "134217726"); +is(iframe.getAttribute("marginwidth"), "134217726", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "134217727"); +is(iframe.getAttribute("marginwidth"), "134217727", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "134217728"); +is(iframe.getAttribute("marginwidth"), "134217728", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "134217729"); +is(iframe.getAttribute("marginwidth"), "134217729", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "134217726%"); +is(iframe.getAttribute("marginwidth"), "134217726%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "134217727%"); +is(iframe.getAttribute("marginwidth"), "134217727%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "134217728%"); +is(iframe.getAttribute("marginwidth"), "134217728%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "134217729%"); +is(iframe.getAttribute("marginwidth"), "134217729%", + "Marginwidth attribute didn't store the original value"); + +// some values 0 < x < NS_ATTRVALUE_INTEGERTYPE_MINVALUE +iframe.setAttribute("marginwidth", "-134217727"); +is(iframe.getAttribute("marginwidth"), "-134217727", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-134217728"); +is(iframe.getAttribute("marginwidth"), "-134217728", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-134217729"); +is(iframe.getAttribute("marginwidth"), "-134217729", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-134217730"); +is(iframe.getAttribute("marginwidth"), "-134217730", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-134217727%"); +is(iframe.getAttribute("marginwidth"), "-134217727%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-134217728%"); +is(iframe.getAttribute("marginwidth"), "-134217728%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-134217729%"); +is(iframe.getAttribute("marginwidth"), "-134217729%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-134217730%"); +is(iframe.getAttribute("marginwidth"), "-134217730%", + "Marginwidth attribute didn't store the original value"); + +iframe.setAttribute("marginwidth", "-0"); +is(iframe.getAttribute("marginwidth"), "-0", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-0%"); +is(iframe.getAttribute("marginwidth"), "-0%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", " 0 "); +is(iframe.getAttribute("marginwidth"), " 0 ", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", " 0% "); +is(iframe.getAttribute("marginwidth"), " 0% ", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-50%"); +is(iframe.getAttribute("marginwidth"), "-50%", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "-50"); +is(iframe.getAttribute("marginwidth"), "-50", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", " -50% "); +is(iframe.getAttribute("marginwidth"), " -50% ", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", " -50 "); +is(iframe.getAttribute("marginwidth"), " -50 ", + "Marginwidth attribute didn't store the original value"); +iframe.setAttribute("marginwidth", "foobar"); +is(iframe.getAttribute("marginwidth"), "foobar", + "Marginwidth attribute didn't store the original value"); + +var bd = document.createElement("body"); +bd.setAttribute("bgcolor", "red"); +is(bd.getAttribute("bgcolor"), "red", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "red", ".bgColor didn't return the right value!"); + +bd.setAttribute("bgcolor", " red "); +is(bd.getAttribute("bgcolor"), " red ", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, " red ", ".bgColor didn't return the right value!"); + +bd.setAttribute("bgcolor", "#ff0000"); +is(bd.getAttribute("bgcolor"), "#ff0000", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "#ff0000", ".bgColor didn't return the right value!"); + +bd.setAttribute("bgcolor", "#f00"); +is(bd.getAttribute("bgcolor"), "#f00", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "#f00", ".bgColor didn't return the right value!"); + +bd.setAttribute("bgcolor", " #ff0000 "); +is(bd.getAttribute("bgcolor"), " #ff0000 ", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, " #ff0000 ", ".bgColor didn't return the right value!"); + +bd.setAttribute("bgcolor", "nonsense(complete)"); +is(bd.getAttribute("bgcolor"), "nonsense(complete)", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "nonsense(complete)", ".bgColor didn't return the right value!"); + +// same test again setting the prop +bd.bgColor = "red"; +is(bd.getAttribute("bgcolor"), "red", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "red", ".bgColor didn't return the right value!"); + +bd.bgColor = " red "; +is(bd.getAttribute("bgcolor"), " red ", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, " red ", ".bgColor didn't return the right value!"); + +bd.bgColor = "#ff0000"; +is(bd.getAttribute("bgcolor"), "#ff0000", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "#ff0000", ".bgColor didn't return the right value!"); + +bd.bgColor = "#f00"; +is(bd.getAttribute("bgcolor"), "#f00", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "#f00", ".bgColor didn't return the right value!"); + +bd.bgColor = " #ff0000 "; +is(bd.getAttribute("bgcolor"), " #ff0000 ", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, " #ff0000 ", ".bgColor didn't return the right value!"); + +bd.bgColor = "nonsense(complete)"; +is(bd.getAttribute("bgcolor"), "nonsense(complete)", "Bgcolor attribute didn't store the original value"); +is(bd.bgColor, "nonsense(complete)", ".bgColor didn't return the right value!"); + +// equal color, unequal string +var f1 = document.createElement("font"); +var f2 = document.createElement("font"); +var f3 = document.createElement("font"); +f1.color = "#f00"; +f2.color = "#ff0000"; +f3.color = "red"; +isnot(f1.color, f2.color, "#f00 and #ff0000 should not compare equal"); +isnot(f1.color, f3.color, "#f00 and red should not compare equal"); +isnot(f2.color, f3.color, "#ff0000 and red should not compare equal"); + +isnot(f1.getAttribute("color"), f2.getAttribute("color"), + "#f00 and #ff0000 should not compare equal [attr]"); +isnot(f1.getAttribute("color"), f3.getAttribute("color"), + "#f00 and red should not compare equal [attr]"); +isnot(f2.getAttribute("color"), f3.getAttribute("color"), + "#ff0000 and red should not compare equal [attr]"); + +var video = document.createElement("video"); +video.setAttribute("playbackrate", "1"); +is(video.getAttribute('playbackrate'), "1", + "Playbackrate attribute didn't store the original value"); +video.setAttribute("playbackrate", "1.5"); +is(video.getAttribute('playbackrate'), "1.5", + "Playbackrate attribute didn't store the original value"); +video.setAttribute("playbackrate", "999999999999999999"); +is(video.getAttribute('playbackrate'), "999999999999999999", + "Playbackrate attribute didn't store the original value"); +video.setAttribute("playbackrate", "-999999999999999999"); +is(video.getAttribute('playbackrate'), "-999999999999999999", + "Playbackrate attribute didn't store the original value"); +video.setAttribute("playbackrate", "foo"); +is(video.getAttribute('playbackrate'), "foo", + "Playbackrate attribute didn't store the original value"); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug433662.html b/dom/base/test/test_bug433662.html new file mode 100644 index 0000000000..ec30775a21 --- /dev/null +++ b/dom/base/test/test_bug433662.html @@ -0,0 +1,31 @@ +<!doctype html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=433662 +--> +<title>Test for Bug 433662</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=433662">Mozilla Bug 433662</a> +<script> + +/** Test for Bug 433662 **/ +var range = document.createRange(); +range.setStart(document.body, 0); +range.insertNode(document.createComment("abc")); +is(document.body.firstChild.nodeType, Node.COMMENT_NODE, + "Comment must be inserted (start of node)"); +is(document.body.firstChild.nodeValue, "abc", + "Comment must have right contents (start of node)"); +is(range.endOffset, 1, + "insertNode() needs to include the newly-added node (start of node)"); + +range.setStart(document.body, document.body.childNodes.length); +range.insertNode(document.createComment("def")); +is(document.body.lastChild.nodeType, Node.COMMENT_NODE, + "Comment must be inserted (end of node)"); +is(document.body.lastChild.nodeValue, "def", + "Comment must have right contents (end of node)"); +is(range.endOffset, document.body.childNodes.length, + "insertNode() needs to include the newly-added node (end of node)"); + +</script> diff --git a/dom/base/test/test_bug435425.html b/dom/base/test/test_bug435425.html new file mode 100644 index 0000000000..828931d67d --- /dev/null +++ b/dom/base/test/test_bug435425.html @@ -0,0 +1,432 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=435425 +--> +<head> + <title>Test for Bug 435425</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435425">Mozilla Bug 435425</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 435425 **/ + +var xhr = null; +var upload = null; +var currentEvents = null; +var expectedResponseText = null; +var uploadTotal = 0; +var currentProgress = -1; + +function logEvent(evt) { + var i = 0; + while ((currentEvents.length != i) && + currentEvents[i].optional && + ((currentEvents[i].type != evt.type) || + !(evt.target instanceof currentEvents[i].target))) { + ++i; + } + + if (evt.target instanceof XMLHttpRequestUpload) { + if (evt.type == "loadstart") { + uploadTotal = evt.total + } else { + if (evt.type == "progress") { + is(evt.lengthComputable, evt.total != 0, "event(" + evt.type + ").lengthComputable should be " + (evt.total != 0 ? true : false) + "."); + } + if (evt.total != uploadTotal && evt.total != 0) { + ok(false, "event(" + evt.type + ").total should not change during upload except to become 0 on error/abort/timeout."); + } + } + } + + // There can be any number of repeated progress events, so special-case this. + if (evt.type == "progress") { + // Progress events can repeat, but their "loaded" value must increase. + if (currentProgress >= 0) { + ok(currentProgress < evt.loaded, "Progress should increase, got " + + evt.loaded + " after " + currentProgress); + currentProgress = evt.loaded; + return; // stay at the currentEvent, since we got progress instead of it. + } + // Starting a new progress event group. + currentProgress = evt.loaded; + } else { + // Reset the progress indicator on any other event type. + currentProgress = -1; + } + + ok(i != currentEvents.length, "Extra or wrong event?"); + is(evt.type, currentEvents[i].type, "Wrong event!") + ok(evt.target instanceof currentEvents[i].target, + "Wrong event target [" + evt.target + "," + evt.type + "]!"); + + // If we handled non-optional event, remove all optional events before the + // handled event and then the non-optional event from the list. + if (!currentEvents[i].optional) { + for (;i != -1; --i) { + currentEvents.shift(); + } + } +} + +function hasPendingNonOptionalEvent(ev) { + var i = 0; + while (i < currentEvents.length) { + if (!currentEvents[i].optional && currentEvents[i].type == ev) + return true; + ++i; + } + return false; +} + +function maybeStop(evt) { + logEvent(evt); + if (!hasPendingNonOptionalEvent("loadend")) + nextTest(); +} + +function openXHR(xhr, method, url, privileged) { + if (privileged) + SpecialPowers.wrap(xhr).open(method, url); + else + xhr.open(method, url); +} + +function start(obj) { + xhr = new XMLHttpRequest(); + upload = xhr.upload; + currentEvents = obj.expectedEvents; + expectedResponseText = obj.withUpload; + currentProgress = -1; + xhr.onload = + function(evt) { + if (expectedResponseText) { + is(evt.target.responseText, expectedResponseText, "Wrong responseText"); + } + logEvent(evt); + } + xhr.onerror = + function(evt) { + logEvent(evt); + } + xhr.onabort = + function(evt) { + logEvent(evt); + } + xhr.onloadend = + function (evt) { + maybeStop(evt); + } + xhr.onloadstart = + function (evt) { + logEvent(evt); + } + xhr.onprogress = + function (evt) { + logEvent(evt); + } + + if ("upload" in xhr) { + xhr.upload.onloadstart = + function (evt) { + logEvent(evt); + } + xhr.upload.onprogress = + function (evt) { + logEvent(evt); + } + xhr.upload.onload = + function (evt) { + logEvent(evt); + } + xhr.upload.onerror = + function (evt) { + logEvent(evt); + } + xhr.upload.onabort = + function (evt) { + logEvent(evt); + } + xhr.upload.onloadend = + function (evt) { + maybeStop(evt); + } + } + + try { + var methodIsGet = (obj.method == "GET"); + var url; + var privileged = false; + if (obj.testRedirectError) { + url = "bug435425_redirect.sjs"; + } else if (obj.testNetworkError) { + url = "http://nosuchdomain.localhost"; + privileged = true; + } else { + url = "bug435425.sjs"; + if (obj.withUpload && methodIsGet) { + url += "?" + obj.withUpload; + } + } + openXHR(xhr, obj.method, url, privileged); + xhr.send(!methodIsGet ? obj.withUpload : null); + if (obj.testAbort) { + xhr.abort(); + } + } catch (ex) { + ok(false, ex); + } +} + +var none = null; +var small = ""; +var mid = ""; +var large = ""; + + +for (var smallLength = 0; smallLength < (0x00000000 + 2); ++smallLength) { + small += "A"; +} + +for (var midLength = 0; midLength < (0x00000FFF + 2); ++midLength) { + mid += "A"; +} + +for (var largeLength = 0; largeLength < (0x0000FFFF + 2); ++largeLength) { + large += "A"; +} + +const XHR = XMLHttpRequest; +const UPLOAD = XMLHttpRequestUpload; + +var tests = + [ + { method: "GET", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + + { method: "GET", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + + { method: "GET", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + + { method: "GET", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "GET", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + + { method: "POST", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + + { method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: false}, + {target: UPLOAD, type: "load", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: true}, + {target: UPLOAD, type: "abort", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: true}, + {target: UPLOAD, type: "error", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "error", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + + { method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: false}, + {target: UPLOAD, type: "load", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: true}, + {target: UPLOAD, type: "abort", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: true}, + {target: UPLOAD, type: "error", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "error", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + + { method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: false}, + {target: UPLOAD, type: "load", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "progress", optional: false}, + {target: XHR, type: "load", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: true}, + {target: UPLOAD, type: "abort", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "progress", optional: true}, + {target: XHR, type: "abort", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "progress", optional: true}, + {target: UPLOAD, type: "error", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, + { method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: true, + expectedEvents: [{target: XHR, type: "loadstart", optional: false}, + {target: UPLOAD, type: "loadstart", optional: false}, + {target: UPLOAD, type: "error", optional: false}, + {target: UPLOAD, type: "loadend", optional: false}, + {target: XHR, type: "error", optional: false}, + {target: XHR, type: "loadend", optional: false}]}, +]; + +function runTest() { + var test = tests.shift(); + start(test); +} + +function nextTest() { + if (tests.length) { + setTimeout("runTest()", 0); + } else { + SimpleTest.finish(); + } +} + +ok("upload" in (new XMLHttpRequest()), "XMLHttpRequest.upload isn't supported!"); +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug444030.xhtml b/dom/base/test/test_bug444030.xhtml new file mode 100644 index 0000000000..6ba2c6ec13 --- /dev/null +++ b/dom/base/test/test_bug444030.xhtml @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=444030 +--> +<head> + <title>Test for Bug 444030</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <bindings xmlns="http://www.mozilla.org/xbl"> + <binding id="e"> + <content>e</content> + </binding> + </bindings> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=444030">Mozilla Bug 444030</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ + +/** Test for Bug 444030 **/ + +function doTest() { + var anonTextNode = SpecialPowers.unwrap(SpecialPowers.wrap(document).getAnonymousNodes(document.getElementById("boundElement")))[0]; + var hadException = false; + try { + var wholeText = anonTextNode.wholeText; + } catch(e) { + hadException = true; + } + ok(hadException, + "Should have got an exception when using .wholeText with a text node child of the binding parent"); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(doTest); + +]]> +</script> +</pre> +<div style="-moz-binding: url(#e)" id="boundElement"></div> +</body> +</html> + diff --git a/dom/base/test/test_bug444322.html b/dom/base/test/test_bug444322.html new file mode 100644 index 0000000000..95866f0487 --- /dev/null +++ b/dom/base/test/test_bug444322.html @@ -0,0 +1,2588 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title>Firefox 3 Bug #444322 example</title> + +<script type="text/javascript" src="444322.js"></script> +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<script type="text/javascript"> +function getFile(url) { + if (window.XMLHttpRequest) { + AJAX=new XMLHttpRequest(); + } else { + AJAX=new ActiveXObject("Microsoft.XMLHTTP"); + } + if (AJAX) { + AJAX.open("GET", url, false); + AJAX.send(null); + return AJAX.responseText; + } else { + return false; + } +} +var text = getFile("444322.txt"); +var x = 'scott'; +</script> + </head> +<body> +<p id="display"></p> +<p>This page demonstrates the bug described in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=444322#c24" target="_blank">Bugzilla #444322</a>.</p> +<p>In the <head> section of the document, the global var x is set to "scott". In the <body>, a Javascript statement writes the value of x to the screen.</p> +<p>The expected output is: <b>scott</b>.</p> +<p>The actual output is: <b> + <script type="text/javascript">document.write(x); is(x, "scott", "x is correct")</script></b></p> +<p>This shows that the Javascript in the <head> is not completing before the script in the <body> is executed.</p> +<p>For this bug to occur, the following circumstances must be met: + <ol> + <li>An external Javascript file must be loaded on the page. It doesn't matter what code is in the file, and it can in fact be blank as test.js is in this example. + <li>A synchronous AJAX call must be made in the <head>. Again, the file being loaded can be empty. An alert() call will also work. + <li>The size of the .html (or whatever) file must be relatively large -- in our tests anything above 169,609 bytes did the trick (hence the large amount of text following this explanation). + </ol> +<p>On some occasions we saw the issue <i>not</i> occur if the page was not cached or if it was refreshed, but it would then occur if the page was hit again from a link or by pressing enter in the location bar. This example seems to cause the bug whether the page is cached or not.</p> +<br /> +<hr /> +<br /> +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras ac velit sed tellus facilisis euismod. Proin vel nulla vel turpis tristique dignissim. Donec lacus ipsum, eleifend ut, volutpat a, ultrices adipiscing, arcu. Etiam ligula dolor, adipiscing ut, porta vitae, bibendum non, dolor. Mauris ligula. Sed placerat tincidunt elit. Vestibulum non libero. Curabitur cursus tortor id sem. Integer consectetuer auctor lacus. Proin nisl nisi, pulvinar eget, pharetra at, aliquam eu, velit. Morbi fringilla. Quisque faucibus, mauris posuere vulputate interdum, lectus libero sollicitudin tellus, sit amet ultrices enim purus ac mauris. Pellentesque sit amet mauris eu ante aliquet egestas. Mauris dapibus, velit consectetuer tristique luctus, enim augue pulvinar libero, fringilla dictum lectus felis eu ligula. In ac lorem.<br /><br /> + +Integer laoreet. Ut ultricies arcu nec est. Aenean varius nisl ut odio. Nullam arcu. Vestibulum non pede. Proin vel est. Nam condimentum fermentum dui. Donec at arcu. Donec at libero adipiscing odio mattis dapibus. Suspendisse libero neque, faucibus sed, facilisis et, convallis sit amet, justo. Duis purus tortor, ornare ac, convallis ut, pretium et, tellus. Nam accumsan, ipsum eget accumsan mollis, sapien dolor adipiscing metus, id tincidunt ipsum metus sed nulla. Praesent hendrerit lectus eget tortor. Morbi id lectus et elit ultrices hendrerit. Cras gravida velit sed mauris. Proin lacinia tempus est. Sed sapien tortor, fringilla vel, elementum in, volutpat ac, ante. Vivamus eu tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Mauris in sem ac felis pretium placerat. Donec tempus cursus sem. Aliquam scelerisque porttitor sem. Curabitur consectetuer, pede vitae aliquam aliquet, sapien lacus vehicula neque, ut rhoncus nibh neque sed velit. In rhoncus, nulla eu dignissim egestas, diam nibh hendrerit mauris, condimentum laoreet sapien arcu quis mi. Sed euismod sem. Nulla non ligula sed lacus tempor molestie. Quisque varius. In hac habitasse platea dictumst. Sed felis ipsum, consequat et, blandit vitae, tincidunt id, quam. Nunc nunc. Duis gravida. In massa neque, cursus quis, rutrum sed, semper quis, erat. Donec enim. Suspendisse condimentum eros vel elit. Vestibulum adipiscing erat id lorem. Maecenas enim dui, cursus a, pulvinar ac, rutrum sed, sem. Suspendisse gravida ante vel lectus.<br /><br /> + +Vestibulum molestie, ante at dignissim venenatis, pede urna dictum arcu, vel ullamcorper ligula eros eget metus. Pellentesque nec nisl. Morbi ut nibh. Aenean mauris. Mauris rutrum justo nec velit. Nunc condimentum tortor id augue. Quisque semper massa eget nibh. Maecenas ac odio pretium lorem tincidunt faucibus. Sed congue. Cras sit amet orci ut ligula cursus congue. Etiam laoreet lacus sit amet tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vivamus accumsan. Ut gravida urna hendrerit leo. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.<br /><br /> + +Proin viverra augue in felis. Mauris sed neque. Proin libero. Donec elementum fermentum lacus. Nam et tortor eu purus porta interdum. Suspendisse eget erat et massa vehicula accumsan. Aliquam est. In sollicitudin sapien a tellus. Sed placerat tellus non velit. Nulla facilisi. Donec quam urna, tempus et, egestas ac, pretium ac, risus. Sed venenatis tempor dui. Nam condimentum, erat id fermentum pretium, ante ligula bibendum lorem, accumsan viverra dui augue a pede.<br /><br /> + +Nulla est dui, mattis id, scelerisque eu, hendrerit ut, tellus. Aliquam rhoncus. Vivamus lacinia tortor id justo. Pellentesque id nisi eget sem luctus venenatis. Nunc dolor. Aliquam consectetuer metus ac odio. Sed congue. Vivamus risus eros, bibendum et, congue quis, hendrerit vel, purus. Curabitur sed massa ut augue feugiat imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec enim orci, convallis sit amet, semper sed, vehicula at, turpis.<br /><br /> + +Nam quam mauris, iaculis eget, suscipit vel, laoreet eu, dui. Duis leo. Aenean sit amet nunc a metus fermentum ornare. In et est. Vestibulum vitae tortor. Nunc non risus. Nulla ullamcorper nulla nec eros. Ut mi neque, dapibus at, semper ut, faucibus faucibus, ligula. Suspendisse lectus lacus, consectetuer a, imperdiet id, eleifend quis, nibh. Vestibulum sit amet sem. Nam auctor feugiat augue. Nullam non nulla vitae mi ornare aliquet. In mollis. Pellentesque ac pede. Suspendisse placerat tellus pharetra augue. Sed massa magna, scelerisque non, lobortis ac, rhoncus in, purus. Vestibulum vitae quam vel est tristique fringilla. Fusce laoreet interdum mauris.<br /><br /> + +Cras lectus elit, pharetra ut, iaculis vel, mattis consectetuer, orci. Duis ut justo vitae massa scelerisque accumsan. Morbi et ipsum nec dolor tincidunt gravida. Donec ac sem. Pellentesque dictum erat. Vestibulum lobortis lorem vel nisi. Suspendisse potenti. Cras fermentum est a sem. Nunc suscipit, velit ac vestibulum aliquet, nulla orci fringilla lectus, ut imperdiet odio nunc nec ligula. Integer nisl lacus, interdum sit amet, tempor vitae, ultricies id, elit. Nam augue turpis, adipiscing at, vestibulum ut, vehicula vitae, urna. In hac habitasse platea dictumst. Suspendisse arcu ligula, imperdiet eu, vestibulum non, posuere id, enim. Nullam ornare erat at orci. Quisque eget purus. Nunc ultrices felis aliquam ipsum. Proin gravida. Sed ipsum.<br /><br /> + +Sed vehicula vehicula erat. Sed dui nulla, adipiscing a, ultricies sed, lacinia eget, justo. Sed nisi justo, gravida nec, placerat volutpat, sollicitudin eu, sapien. In orci. Nam convallis neque vitae eros. Curabitur mattis lectus eget tortor. Donec neque. Proin dui pede, ultrices hendrerit, volutpat nec, adipiscing ac, urna. Fusce aliquam condimentum felis. Etiam sodales varius risus. Nulla nisl diam, pharetra sit amet, vestibulum nec, tincidunt hendrerit, neque. Nullam nunc. Curabitur pellentesque, lacus at lobortis vehicula, erat lectus commodo enim, ut aliquet orci felis eget eros. Donec a augue sit amet lacus pharetra semper. Praesent porta dignissim nunc. Suspendisse ut leo at sapien convallis malesuada. Proin posuere interdum massa. Pellentesque mollis, dolor ut tincidunt euismod, nunc tellus adipiscing lectus, nec volutpat nulla nulla ac nulla.<br /><br /> + +Curabitur eu ante. Pellentesque nulla diam, feugiat nec, suscipit eget, blandit vel, odio. Cras ullamcorper metus vel lectus. Fusce pulvinar. Etiam convallis adipiscing ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum felis. Donec euismod purus sit amet dui. Ut iaculis. Curabitur non ipsum. Mauris augue. Proin lacinia. Suspendisse potenti. Suspendisse feugiat sodales leo. Aliquam erat volutpat. Mauris fermentum nisi non nisi. Aliquam velit. Donec iaculis, justo sit amet tempus iaculis, sapien nulla congue orci, a elementum massa sem non velit.<br /><br /> + +Etiam quis urna quis eros dapibus aliquam. Donec non risus. Curabitur pretium. Suspendisse fermentum ligula eu augue. Curabitur sollicitudin. Pellentesque porta mauris. In hac habitasse platea dictumst. Nullam cursus, arcu eu malesuada porta, magna lacus ultricies eros, sed lacinia erat justo vel nibh. Etiam ultricies placerat sem. Pellentesque nec erat. Etiam augue.<br /><br /> + +Quisque odio. Nullam eu libero in augue convallis pellentesque. Duis placerat. Curabitur porta leo eu orci. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean justo. Nam vehicula. Vivamus ante elit, iaculis a, rhoncus vel, interdum et, libero. Fusce in sem scelerisque libero vehicula rhoncus. Sed vitae nibh. Curabitur molestie dictum magna. Quisque tristique purus vel ante. Fusce et erat. Phasellus erat. Quisque pellentesque. Integer velit lacus, pretium et, auctor vel, molestie malesuada, purus.<br /><br /> + +Morbi purus enim, gravida vel, elementum et, aliquam in, ante. Nam eget massa. Donec quam diam, posuere at, volutpat sit amet, laoreet eu, tellus. Sed eu ipsum et nisi porta ullamcorper. In hac habitasse platea dictumst. Sed non dolor nec lorem hendrerit porta. Etiam sollicitudin ornare sapien. Pellentesque a mi. Mauris porttitor velit vel felis. Duis est. Donec sollicitudin. Cras vel justo adipiscing ligula bibendum pellentesque. Maecenas justo dolor, porttitor et, malesuada in, dictum sit amet, leo. Praesent molestie porta nibh. Aliquam facilisis.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus eget nisl. Curabitur libero nibh, iaculis non, vehicula non, gravida sit amet, augue. Praesent feugiat massa id ligula. Fusce non orci. Suspendisse fringilla dictum est. Nulla condimentum, risus sit amet accumsan fringilla, eros orci tristique risus, a sagittis ligula dolor in metus. Nunc sem dolor, sodales ac, tempor nec, commodo a, sapien. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin viverra nulla placerat est. Suspendisse at lectus. Proin tristique, nulla vitae tincidunt elementum, nisi urna pellentesque dui, nec egestas urna lacus ac nibh.<br /><br /> + +Morbi et nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur molestie. Cras mauris dui, fringilla ut, aliquam semper, condimentum vitae, tellus. Aliquam in nibh nec justo porta viverra. Duis consectetuer mi in nunc. Duis ac felis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur eros tortor, ultricies id, accumsan ut, ultrices ac, nisi. Fusce elementum pede id nisi. Mauris venenatis nibh quis enim.<br /><br /> + +Pellentesque sed odio a urna iaculis facilisis. Ut placerat faucibus nibh. Maecenas turpis pede, aliquet a, condimentum nec, dignissim et, nisl. Vivamus ac nulla. Nulla facilisi. Nam at lorem a ligula consequat semper. Nulla facilisi. Phasellus non nulla non diam faucibus blandit. Cras viverra, leo sit amet commodo dictum, enim ipsum scelerisque purus, ac malesuada ligula ligula ut metus. Ut vel nunc. Phasellus euismod ipsum et sem. Quisque luctus pretium arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras adipiscing viverra diam. Aenean sed ipsum id felis condimentum porta. Quisque eros dolor, fringilla ac, scelerisque ac, placerat eu, tortor.<br /><br /> + +Quisque aliquet, mi vulputate dignissim molestie, orci diam aliquam nulla, commodo euismod neque arcu eu enim. Sed sed mi. Donec scelerisque tincidunt arcu. Nunc augue elit, cursus id, ultrices ut, lobortis id, nibh. Quisque nulla sem, scelerisque sed, convallis ut, aliquam a, purus. Proin nulla nunc, scelerisque in, aliquet vel, gravida eu, pede. Donec eget nunc eu tortor adipiscing imperdiet. Vestibulum eu quam id lacus hendrerit ornare. In hac habitasse platea dictumst. Sed molestie mollis mauris. Nunc porta.<br /><br /> + +Maecenas condimentum ipsum eget elit. Donec sit amet mi. Nulla non neque in quam interdum lobortis. Suspendisse potenti. Cras orci dui, eleifend ut, ultrices at, volutpat at, orci. Mauris justo erat, pharetra vel, molestie a, varius ut, dolor. Etiam feugiat lacus id est. Vivamus lobortis, justo a cursus ultricies, turpis tellus tincidunt tortor, nec dignissim turpis nisl vel pede. Etiam eu turpis. Donec eget justo. Aenean gravida elit eget quam. Proin commodo, ligula sed mattis accumsan, risus erat pulvinar lorem, vitae consectetuer arcu magna in risus. Vivamus nulla. Suspendisse egestas nisl quis urna. Ut quis eros. Mauris ligula velit, aliquet non, venenatis et, rhoncus vitae, lectus. Nam ornare quam a augue.<br /><br /> + +Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut eros magna, rhoncus et, condimentum in, scelerisque commodo, ipsum. Nulla hendrerit, est a varius ornare, velit pede condimentum magna, eu rhoncus odio diam at sem. Sed cursus euismod libero. Maecenas sit amet mauris. Sed egestas ante vitae metus. Nulla lacus. In arcu ante, ultrices quis, suscipit ac, sagittis eu, neque. Duis laoreet. Maecenas mi. Quisque urna metus, tincidunt tincidunt, imperdiet sit amet, molestie at, odio. Etiam ac felis. Praesent ligula. Phasellus tempus nibh. Pellentesque dapibus. Curabitur ultricies leo a est. Praesent sit amet arcu. Suspendisse fermentum lectus eget arcu. Ut est. Aenean sit amet nisl non urna suscipit ornare.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur ut lacus id ipsum condimentum pellentesque. Nunc suscipit. Maecenas sagittis eros at lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris porttitor mi in tellus. Proin vel sem ac est euismod iaculis. Aliquam hendrerit nisl vitae nibh. Sed mollis. Nulla facilisi. Vivamus faucibus quam.<br /><br /> + +Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Ut et turpis non arcu fringilla pellentesque. Nullam interdum facilisis felis. Mauris tincidunt. Donec luctus, lorem sed lacinia ornare, enim quam sagittis lacus, ut porttitor nulla nisi eget mi. Nullam sagittis. Sed dapibus, turpis non eleifend sodales, risus massa hendrerit neque, volutpat aliquam nulla tellus eu dui. Pellentesque iaculis fermentum mi. Nam cursus ligula et nibh. Fusce tortor nibh, bibendum vitae, pharetra et, volutpat sed, urna.<br /><br /> + +Nulla facilisi. Nulla non ante. Etiam vel nunc. Cras luctus auctor nibh. Suspendisse varius arcu a risus. Duis interdum malesuada tortor. Sed vel mauris. Mauris sed lorem. Aliquam purus. Vivamus sit amet neque. Nulla ultrices, ante ac porttitor ultrices, enim dui varius ipsum, tincidunt malesuada felis turpis non turpis. Nullam egestas, massa venenatis dictum imperdiet, urna est rhoncus magna, a fermentum ligula dolor malesuada lacus. Proin ac dui.<br /><br /> + +Donec vestibulum magna quis enim. Nam dui nisl, lacinia non, dapibus at, mollis et, elit. Aliquam tempor nulla vitae metus. Integer varius convallis massa. Ut tempus, sem vel commodo aliquam, tellus justo placerat magna, ac mollis ipsum nulla ornare arcu. Cras risus nibh, eleifend in, scelerisque id, consequat quis, erat. Maecenas venenatis augue id odio. Cras libero. Donec sed eros. Etiam varius odio id nunc. Nam euismod urna a tellus. In non sem. In aliquet. Morbi sodales magna eu enim. Cras tristique.<br /><br /> + +Nam quis quam eu quam euismod tristique. Donec ac velit. Ut a velit. Suspendisse eu turpis. Integer eros leo, euismod eu, rutrum eget, imperdiet sed, risus. Donec congue sapien. Nulla venenatis magna ac quam. Fusce purus odio, pharetra eget, vulputate non, auctor quis, magna. Nulla facilisi. Ut sagittis, mauris at cursus aliquam, ipsum mi faucibus justo, vel pharetra metus felis ac dolor. Donec elementum arcu quis tellus. Quisque mattis sem eu metus. Duis tempor elit non sem. Cras ultrices risus.<br /><br /> + +Integer pulvinar. Vestibulum blandit dolor et lacus. Aliquam varius arcu ac arcu ornare pharetra. Phasellus ut sapien nec neque posuere feugiat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vivamus pharetra semper justo. Sed ut elit. Aenean aliquet euismod quam. Mauris turpis justo, lacinia at, blandit sit amet, molestie tristique, sapien. Integer et urna sit amet lectus facilisis pulvinar.<br /><br /> + +Phasellus vitae elit non odio pulvinar faucibus. Maecenas elementum. Fusce bibendum, odio eget rutrum aliquam, velit felis dapibus elit, in dapibus libero velit eget arcu. Sed dolor enim, porta eget, luctus in, cursus nec, erat. Duis pretium. Cras volutpat velit in dui. Fusce vitae enim. Nunc ornare dolor non purus. Maecenas pulvinar velit id mauris. Vestibulum in erat. Mauris in metus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin at dui nec ipsum suscipit ultricies.<br /><br /> + +Integer tristique enim sed neque. Sed sapien sapien, suscipit at, bibendum sed, iaculis a, eros. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus sagittis accumsan lectus. Maecenas tincidunt semper erat. In vitae arcu. Ut vulputate tempus magna. Nam erat. Sed mi. Vestibulum mauris. Maecenas et sem. Cras risus justo, hendrerit ut, cursus nec, pretium in, ipsum. Sed molestie lectus sed arcu consectetuer vulputate. Nunc mollis posuere dolor. Morbi nec velit a libero pharetra facilisis. Cras tincidunt.<br /><br /> + +Donec rutrum luctus augue. Donec mattis commodo erat. Aenean sodales. Duis convallis metus id massa. Integer eget lorem et lectus sodales cursus. Integer commodo, tellus ut consequat placerat, nibh nisi malesuada nulla, eu aliquet metus mauris id nulla. Sed sagittis. Nam in mauris. Quisque eget ipsum. Suspendisse enim arcu, semper vitae, tincidunt dapibus, malesuada ac, dolor. Donec adipiscing auctor sem. Phasellus vitae pede. Integer lectus risus, ultrices non, euismod sed, condimentum et, lacus. Suspendisse potenti. Praesent tristique iaculis nulla. Curabitur sagittis. Aliquam erat volutpat. Donec feugiat, lectus vel tincidunt blandit, nisi mauris venenatis mi, id vehicula quam ante eget massa. Suspendisse volutpat sodales lorem. Nunc leo odio, dictum a, rutrum ac, aliquam at, felis.<br /><br /> + +Vestibulum blandit. Sed volutpat mi nec massa. Aliquam erat volutpat. Nam eu erat et turpis accumsan semper. Nam justo. Sed lacinia. Pellentesque dignissim diam. Suspendisse consectetuer mattis massa. Praesent feugiat orci a augue. Donec eget tellus. Vestibulum suscipit neque vel eros. Nunc libero. Sed scelerisque nunc et sapien. Nulla sit amet ante convallis felis dapibus consectetuer. Pellentesque iaculis erat eu purus viverra facilisis. Duis vestibulum, felis ac sollicitudin interdum, augue eros tincidunt felis, sit amet eleifend quam nibh eu sem.<br /><br /> + +Duis fermentum, urna et commodo porta, nisl ante egestas ante, in varius sem lacus eget turpis. Nullam dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque bibendum velit quis lorem. Nulla facilisi. Nunc rutrum diam eu magna. Phasellus eleifend, tellus ut elementum fringilla, turpis neque ornare elit, et gravida nisi odio ac lacus. Integer non velit vitae pede laoreet molestie. Nullam in tellus at turpis interdum rhoncus. Donec ut purus vel elit lobortis rutrum. Nullam est leo, porta eu, facilisis et, tempus vel, massa. Vivamus eu purus. Sed volutpat consectetuer tortor. Aliquam nec lacus. Aliquam purus est, tempor in, auctor vel, ornare nec, diam. Duis ipsum erat, vestibulum lacinia, tincidunt eget, sodales nec, nibh. Maecenas convallis vulputate est. Quisque enim.<br /><br /> + +Aenean ut dui. Sed eleifend ligula sit amet odio. Aliquam mi. Integer metus ante, commodo quis, ullamcorper non, euismod in, est. In hac habitasse platea dictumst. Donec pede erat, venenatis a, pretium et, placerat vitae, velit. Cras lectus diam, ultricies a, interdum quis, placerat at, diam. Nam aliquet orci in velit luctus ornare. Donec a diam quis mi iaculis aliquam. Suspendisse iaculis. Duis nec lorem. Sed vehicula massa et urna. Morbi lorem. Proin et eros eget tellus eleifend viverra. Sed suscipit.<br /><br /> + +Ut id leo sed tortor porttitor tincidunt. In nec felis. Maecenas tempus nunc et tortor. Fusce arcu. Mauris at leo. Nunc ultricies augue a quam. Duis quis mi sed leo hendrerit hendrerit. Vestibulum eros. Nam felis. Donec felis. Suspendisse egestas dictum augue. Suspendisse nec ligula non ipsum fermentum tempus. In velit felis, lobortis nec, porttitor nec, rutrum at, leo. Donec porta eleifend felis. Nunc ullamcorper est porta purus porttitor volutpat. Sed pharetra ligula et nisi. Donec vehicula sodales eros. Cras ut sem tincidunt turpis dignissim sollicitudin. Aliquam quis tellus.<br /><br /> + +Cras id arcu quis neque mollis laoreet. Nulla mattis. Pellentesque et lectus. Praesent id sem. Proin malesuada nunc quis est. Integer varius sodales purus. Ut tellus. Vestibulum sed sem rhoncus justo eleifend feugiat. Donec nisi massa, sagittis non, fringilla sed, adipiscing at, diam. Donec pellentesque orci facilisis nisi. Sed a leo id odio cursus dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla eu augue. Quisque consequat. Cras odio. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a nunc ac magna viverra pharetra. Donec at dolor. Nulla aliquet venenatis magna.<br /><br /> + +Vivamus tortor dolor, feugiat quis, aliquet eu, commodo at, felis. Vivamus venenatis nibh ac nunc. Pellentesque euismod. Duis arcu. Mauris nec metus vitae augue varius euismod. Mauris tellus. Quisque tristique euismod lacus. Proin eu quam vitae ipsum elementum tincidunt. Ut rutrum ultrices enim. Quisque fringilla pede quis ante pharetra fermentum. Nunc gravida. In augue massa, congue non, cursus quis, interdum vel, nisl. Pellentesque tempus, purus vel ornare semper, justo nibh consequat tortor, ac facilisis turpis nisi ut lorem. Duis sapien.<br /><br /> + +In hac habitasse platea dictumst. Sed egestas rhoncus dolor. Proin turpis nibh, mollis a, egestas ut, faucibus aliquet, est. Sed quam justo, lobortis vel, lacinia sed, ultrices ultricies, massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi bibendum diam nec massa. Morbi auctor. Fusce condimentum volutpat ante. Proin sed arcu in dui sollicitudin imperdiet. Donec feugiat faucibus diam. In auctor. Nunc tincidunt pellentesque massa. Maecenas nulla. Nam sapien neque, pretium sed, pulvinar vel, posuere nec, nibh. Vivamus sagittis, nunc eu placerat fringilla, ligula velit bibendum urna, molestie commodo magna magna nec lacus. Aenean vitae quam.<br /><br /> + +Aenean non dui. Aliquam rutrum tempor est. Cras fringilla lacus vitae sem. Suspendisse laoreet sodales magna. Curabitur posuere mi at magna. Ut fermentum, dui quis posuere sagittis, erat lorem feugiat nibh, a suscipit metus nulla vitae tellus. In eget velit. Nam iaculis dictum diam. Sed porttitor metus at nunc. Fusce quis pede adipiscing risus congue mollis. Ut dictum, mi at accumsan venenatis, orci nulla accumsan sem, ut aliquam felis libero quis quam. Nulla turpis diam, tempus ut, dictum sit amet, blandit sit amet, enim. Suspendisse potenti. Maecenas elit turpis, malesuada et, ultricies quis, congue et, enim. Maecenas ut sapien. Nullam hendrerit accumsan tellus.<br /><br /> + +Proin cursus orci eu dolor. Suspendisse sem magna, porta ac, feugiat in, pretium sed, felis. Nulla elementum commodo massa. Suspendisse consectetuer nibh in urna. Sed sit amet augue. Nam id ligula. Phasellus ullamcorper tellus ut eros. Vivamus arcu lectus, molestie at, posuere non, suscipit semper, eros. Donec sed augue a tellus tincidunt vulputate. Nullam elementum ante quis augue. Cras mauris felis, elementum sit amet, iaculis vitae, ornare nec, nisl. Nam venenatis orci et leo. Nam scelerisque. Praesent tellus diam, vehicula et, volutpat at, sollicitudin aliquet, dui. Phasellus tellus velit, malesuada id, semper ac, venenatis sit amet, nibh. Duis convallis lorem a erat.<br /><br /> + +Pellentesque tincidunt eleifend ligula. Aenean turpis justo, ornare in, mattis sit amet, eleifend ac, odio. Maecenas nec metus vitae velit eleifend pretium. Donec dui orci, tempus sed, malesuada tempor, dignissim et, ante. Fusce egestas, dolor mollis faucibus sollicitudin, nisl felis porta libero, eget varius justo libero id mauris. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi auctor gravida massa. Nullam sed elit. Nullam pulvinar. In dignissim cursus purus. Phasellus non ante sed turpis venenatis dignissim. Nam libero pede, laoreet sed, vulputate quis, egestas ac, risus.<br /><br /> + +Vivamus sagittis facilisis libero. Pellentesque velit erat, ornare a, consectetuer et, congue sed, pede. Nullam justo massa, volutpat et, blandit ut, pharetra vel, leo. Aliquam rutrum. Vestibulum blandit varius ipsum. Nullam vel velit. In non lectus ut sem consectetuer luctus. Ut feugiat massa vel nibh. Sed vitae turpis vitae eros pharetra posuere. Sed non neque. Ut auctor odio a quam eleifend vestibulum. Maecenas tincidunt risus vel ipsum. Morbi euismod cursus turpis. Nam quis dolor non libero facilisis lacinia. Pellentesque ultrices. Aenean ullamcorper, purus at sollicitudin imperdiet, urna augue bibendum ligula, eget placerat diam mi a mauris. Donec porttitor varius augue.<br /><br /> + +Pellentesque fringilla erat in ante. Pellentesque orci tellus, varius vitae, tempus sed, vehicula placerat, dolor. Praesent nisi diam, pharetra nec, laoreet tempor, elementum in, tortor. In accumsan. Fusce ut mi ac ligula venenatis sollicitudin. Donec vulputate mollis nisl. Aenean nec purus nec lorem dapibus semper. In at enim nec orci consequat imperdiet. Curabitur vestibulum sapien id tellus. Phasellus iaculis lectus. Ut non turpis. Donec vitae ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Vestibulum eget erat eu massa laoreet vestibulum. Donec convallis erat eu ipsum. Donec libero massa, lacinia nec, mollis eu, tempus a, enim. Cras eu leo. Sed massa nunc, scelerisque sit amet, faucibus quis, blandit in, nunc. Aliquam posuere enim nec nibh. Duis quis velit tempor eros interdum interdum.<br /><br /> + +Aenean tempus, leo at vehicula varius, lectus elit facilisis tellus, sit amet ornare metus metus ut metus. In eros. Aenean eget est. Curabitur egestas. Sed ut elit. Mauris iaculis accumsan ligula. Aliquam imperdiet, libero et iaculis semper, mi augue posuere velit, id pretium nunc justo nec enim. Mauris lobortis turpis sit amet lacus. Quisque eu risus eget nibh mollis tristique. Mauris vestibulum. Etiam dui massa, condimentum a, tempus et, convallis vulputate, ante. Curabitur porta ultricies tortor. Praesent rutrum volutpat ipsum. In accumsan vestibulum lacus.<br /><br /> + +Ut in justo vel enim viverra euismod. Phasellus ultrices semper urna. Aenean mauris tellus, vulputate feugiat, cursus ac, dignissim vel, nulla. In hac habitasse platea dictumst. In euismod, risus et pellentesque vulputate, nibh est sollicitudin felis, in accumsan diam metus sit amet diam. Fusce turpis lectus, ultricies euismod, pellentesque non, ullamcorper in, nunc. Vestibulum accumsan, lorem nec malesuada adipiscing, ante augue pellentesque magna, quis laoreet neque eros vel sapien. Phasellus feugiat. Curabitur gravida mauris eget augue. Praesent bibendum. Aenean sit amet odio ut arcu pellentesque scelerisque. Donec luctus venenatis eros. Phasellus tempus enim nec tortor. Sed ac lorem. Proin ut dui. Aliquam ipsum.<br /><br /> + +Nunc varius dui sit amet tellus tincidunt facilisis. Mauris molestie varius purus. Vivamus gravida, est sed auctor tincidunt, risus justo euismod tortor, sed rhoncus nunc ipsum ac turpis. Nullam lacus sapien, ornare nec, placerat quis, commodo sit amet, ante. Etiam non urna vitae ligula hendrerit pharetra. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aliquam erat volutpat. Integer feugiat, mi non egestas suscipit, pede sapien mattis pede, et tristique dui risus posuere erat. Nulla nunc odio, consequat feugiat, fermentum in, dignissim id, dolor. Donec rutrum purus sit amet dolor. Vestibulum molestie. Nulla pulvinar, mi ac eleifend cursus, pede eros ultrices sapien, sed consequat est mi eget mauris. Sed nibh metus, luctus vitae, volutpat sit amet, consectetuer nec, neque. Mauris rutrum dapibus nunc. Ut iaculis turpis at mauris. In hac habitasse platea dictumst. Sed congue fringilla orci. Sed turpis pede, vehicula sed, imperdiet ac, porttitor vestibulum, metus. Nunc cursus. Nam turpis ipsum, ultricies nec, cursus sit amet, rhoncus molestie, mi.<br /><br /> + +Suspendisse potenti. Donec massa ante, porttitor id, ornare vel, rutrum sed, mauris. Donec auctor risus non elit. Donec pretium congue elit. Aliquam varius. Aliquam eget lacus. Vestibulum sed mauris eu erat ornare adipiscing. Proin congue. Nulla facilisi. Sed orci libero, tincidunt id, mattis non, volutpat in, ligula. Fusce ut odio. Aliquam semper eleifend felis. Nunc orci. Nulla facilisi.<br /><br /> + +Morbi dolor nisi, pulvinar ut, feugiat at, rutrum nec, lectus. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc gravida, libero a pulvinar iaculis, mi nulla adipiscing quam, ut gravida quam nunc quis nibh. Mauris ac nunc ut sem aliquet rhoncus. Vivamus urna. Nulla semper. Vivamus laoreet. Sed scelerisque condimentum dui. Phasellus libero metus, iaculis vel, elementum vel, scelerisque mattis, dui. In hac habitasse platea dictumst. Pellentesque ac nisi. Integer gravida. Praesent pharetra sem vitae justo. Praesent tempor nulla eget metus. Cras at dui. Nulla ultrices sem. Nam facilisis lectus malesuada orci. Vestibulum porttitor, neque ut tristique aliquet, dui libero venenatis augue, ac convallis nibh sem ac orci. Suspendisse potenti. Mauris suscipit dapibus mauris.<br /><br /> + +Morbi sapien. Integer leo erat, blandit at, convallis eget, luctus eu, arcu. Sed urna metus, dignissim pulvinar, viverra sed, lacinia at, mi. Mauris congue feugiat mi. Mauris libero urna, blandit non, fermentum non, semper eu, erat. Pellentesque nec lacus. Fusce ut elit. Fusce sagittis, magna vel luctus suscipit, est ligula imperdiet leo, vulputate porta nisl sem ut erat. Vestibulum arcu turpis, tincidunt in, faucibus quis, pharetra at, elit. Vivamus imperdiet magna sit amet neque. Vestibulum vel leo. Suspendisse semper congue magna. Donec eleifend rhoncus lacus. Morbi tellus nunc, hendrerit sit amet, fringilla at, commodo vitae, sem. Maecenas vestibulum eros sagittis ipsum. Curabitur elit felis, rutrum vel, viverra vitae, vulputate et, arcu.<br /><br /> + +Quisque ac augue quis tellus dictum ornare. Quisque vitae orci eu mi cursus feugiat. Nulla facilisi. In dui magna, ultricies eget, tempor sed, malesuada in, sapien. Duis mi. In hac habitasse platea dictumst. Nunc ultricies. Nulla accumsan, libero sed ullamcorper porttitor, eros lectus aliquam erat, in aliquet massa metus ac purus. Pellentesque enim odio, facilisis sed, sagittis vitae, scelerisque id, arcu. Aenean ante lectus, cursus non, rutrum vel, faucibus porta, tortor. Nam vitae neque. Morbi non turpis. Etiam facilisis. Mauris et urna. Cras tempor. Nullam rutrum, nisl eu cursus tristique, velit tellus aliquam pede, quis interdum massa sem id lorem. Fusce posuere. Quisque in leo venenatis dui facilisis sodales. In orci augue, bibendum et, viverra id, vehicula vitae, augue.<br /><br /> + +Etiam malesuada est vel dolor. Integer suscipit volutpat libero. Cras semper dui sit amet dui. Quisque imperdiet leo vitae felis. Morbi volutpat nisi. Vestibulum sit amet eros a odio pellentesque lobortis. Sed dapibus est quis ante. Ut lobortis. Maecenas ullamcorper libero vel lacus. Aenean ut turpis vel elit tempor congue. Morbi sed sem. Aliquam odio neque, cursus sit amet, sollicitudin eu, vestibulum ac, turpis. Donec sed mauris. Pellentesque ut enim a sem lobortis euismod. Ut tellus odio, dapibus sed, iaculis sed, congue vel, massa. Phasellus tempus orci non orci. Proin erat ante, ornare ac, ornare commodo, elementum sit amet, libero. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed aliquam ornare dui. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras quis ante et felis porta porttitor. Aliquam erat volutpat. Phasellus et lacus. Morbi augue augue, sollicitudin at, tristique eget, porta vel, neque. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Mauris id velit a erat molestie venenatis. Cras pellentesque. Maecenas tincidunt sem ut odio. Proin at ante. Cras fringilla, erat ac varius dapibus, lacus dui posuere mauris, at interdum lacus nisi ac pede.<br /><br /> + +Pellentesque tristique. Donec eleifend. Nam tempus, mauris eu fermentum scelerisque, mauris nisl gravida nisl, sit amet pulvinar magna neque eget sapien. Etiam eu diam eu enim commodo scelerisque. Suspendisse potenti. Sed vitae sapien. Proin vel dui in augue tempus facilisis. Aenean nibh erat, interdum id, dictum ac, pharetra ac, eros. Suspendisse magna. Sed aliquet tellus non leo. Curabitur velit. Suspendisse sapien leo, pretium a, vehicula vel, faucibus nec, mi. Maecenas tincidunt volutpat diam. Proin vitae quam at dui gravida placerat. Sed eu nulla. Integer iaculis massa ac lacus. Praesent auctor ultricies quam. Suspendisse ut sapien. Morbi varius quam vel nisl.<br /><br /> + +Nulla facilisi. Donec lobortis urna at mi. Mauris vulputate, enim sed auctor molestie, nisi elit vehicula mi, ac sollicitudin felis turpis nec ante. Praesent rutrum, arcu non semper euismod, magna sapien rutrum elit, eu varius turpis erat at eros. Morbi porta malesuada massa. Etiam fermentum, urna non sagittis gravida, lacus ligula blandit massa, vel scelerisque nunc odio vitae turpis. Morbi et leo. Pellentesque a neque nec nibh rhoncus ultricies. Curabitur hendrerit velit non velit. Sed mattis lacus vel urna. Integer ultricies sem non elit consequat consequat.<br /><br /> + +Fusce imperdiet. Etiam semper vulputate est. Aenean posuere, velit dapibus dapibus vehicula, magna ante laoreet mauris, quis tempus neque nunc quis ligula. Nulla fringilla dignissim leo. Nulla laoreet libero ut urna. Nunc bibendum lorem vitae diam. Duis mi. Phasellus vitae diam. Morbi quis urna. Pellentesque rutrum est et magna. Integer pharetra. Phasellus ante velit, consectetuer sed, volutpat auctor, varius eu, enim. Maecenas fringilla odio et dui. Quisque tempus, est non cursus lacinia, turpis massa consequat purus, a pellentesque sem felis sed augue.<br /><br /> + +Pellentesque semper rhoncus odio. Ut at libero. Praesent molestie. Cras odio dui, vulputate quis, ultrices in, pellentesque et, ipsum. Nunc fermentum. Nulla et purus. Sed libero nisl, tempor a, posuere nec, accumsan ut, urna. Praesent facilisis lobortis lectus. Curabitur viverra feugiat turpis. Curabitur ante magna, vulputate sodales, hendrerit nec, interdum in, odio. Vivamus accumsan felis eleifend massa. Suspendisse pharetra.<br /><br /> + +Suspendisse at odio ac lorem hendrerit luctus. In dolor nibh, sodales quis, consectetuer id, mattis ut, arcu. Nullam diam nisl, congue vel, bibendum sit amet, fringilla sed, tortor. Praesent mattis dui non nibh. Donec ipsum nulla, tempor in, pellentesque nec, auctor ut, risus. Praesent metus lacus, mattis vel, varius et, feugiat vitae, metus. Donec nec leo. Ut velit nibh, porta id, tempus in, mattis ac, lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sed felis. Pellentesque luctus. Vivamus elit. In ultricies lacinia ipsum. Pellentesque venenatis ante eget tortor. Duis lacus. Nulla pretium libero nec nunc. Sed pede.<br /><br /> + +Fusce ligula. Cras dui enim, tincidunt nec, ultricies sit amet, vehicula vitae, orci. Cras nec erat. Praesent non nulla. Proin commodo hendrerit quam. Aliquam sed massa ut elit venenatis hendrerit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis porttitor ante ac nisl fringilla sollicitudin. Quisque nec nibh et nunc gravida posuere. Sed eget libero ut eros faucibus ultricies. Vivamus gravida augue sit amet leo suscipit tempor. Maecenas elementum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec condimentum diam non elit. In porttitor consectetuer nisi. Praesent vitae nulla et eros porttitor ornare. Quisque eu purus quis pede suscipit elementum. Proin tempor tincidunt tortor. Etiam tellus.<br /><br /> + +Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce cursus. Mauris non leo. Pellentesque ullamcorper justo in lectus. Cras ut purus eu enim consectetuer rhoncus. Nulla facilisi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In placerat pellentesque arcu. Sed volutpat, lectus sed ullamcorper adipiscing, nunc nisl molestie orci, ac commodo nunc metus congue urna. Aliquam tortor nunc, tristique eget, bibendum eu, pharetra id, massa. Nunc non tellus. Pellentesque venenatis. Nunc consequat, urna at pellentesque blandit, ante orci consectetuer metus, eu fringilla arcu turpis in lacus. Mauris rhoncus risus nec massa. Proin rhoncus facilisis ligula. Quisque imperdiet porta nisl.<br /><br /> + +Sed quis risus eget sem consectetuer pretium. Maecenas et erat ac lorem fermentum fermentum. Nulla elementum. Fusce semper tincidunt ipsum. Donec interdum mauris ac nibh. Nulla eget purus. Donec convallis, lorem nec tincidunt viverra, quam purus malesuada orci, nec gravida purus risus vel diam. Nullam quis tortor. Fusce eget tellus. Sed cursus lorem. Etiam ornare rhoncus augue. Nullam auctor pede et lacus.<br /><br /> + +Nullam pellentesque condimentum ligula. Donec ullamcorper, enim a fringilla elementum, ante lacus malesuada risus, vitae vulputate dolor tellus in nisl. Pellentesque diam eros, tempor pharetra, suscipit vel, tincidunt et, dui. Aenean augue tortor, semper aliquam, euismod eu, posuere id, ante. Aenean consequat. Ut turpis pede, auctor eget, mollis vitae, euismod id, leo. Phasellus urna. Sed rutrum, eros sed porta placerat, nisl mauris auctor lorem, quis ultricies metus sapien eget nulla. Phasellus quis nisi sed dolor fermentum dictum. Ut pretium pede quis sapien. In hac habitasse platea dictumst. Suspendisse volutpat, urna ac pretium malesuada, risus ligula dictum ligula, vel fringilla diam metus et nisl. Mauris at massa at ante venenatis vehicula. Proin rhoncus dui nec nibh. Sed vel felis ornare erat bibendum mattis.<br /><br /> + +Nunc iaculis venenatis nisl. Mauris faucibus imperdiet nibh. Donec tristique mattis lectus. Aliquam erat volutpat. Donec et mauris a pede cursus lobortis. Pellentesque dictum malesuada augue. Pellentesque malesuada, lorem et fringilla posuere, libero nulla cursus pede, eget adipiscing nisl magna id diam. Morbi tortor. Ut et urna. Duis quis massa.<br /><br /> + +Quisque eu eros ut tortor dapibus auctor. Pellentesque commodo tellus vitae tortor. Praesent accumsan auctor ligula. Vestibulum convallis molestie justo. Praesent et ipsum. Vestibulum neque quam, ornare eu, cursus at, sollicitudin eget, nulla. Fusce leo massa, euismod cursus, scelerisque nec, mollis nec, est. Morbi iaculis tempor risus. In hac habitasse platea dictumst. Pellentesque malesuada libero. Nulla facilisi. Nam ante. Maecenas tincidunt eros ut justo. Morbi sollicitudin pulvinar elit. Aenean nisl.<br /><br /> + +Morbi dapibus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce at lectus. Cras vulputate. Duis velit sapien, vehicula ut, consectetuer nec, pretium in, metus. Praesent quis mi. Fusce rhoncus enim nec nibh. Suspendisse dictum nunc. Duis ut metus sed est tempor semper. Nullam elit dolor, facilisis nec, gravida in, dictum sed, sapien. In laoreet. Sed quis nulla id mi mollis congue. Ut ante massa, commodo nec, ornare quis, blandit at, elit. In hac habitasse platea dictumst. Mauris neque nisi, porta non, eleifend fringilla, scelerisque porta, urna. Proin euismod cursus erat. Etiam non lorem et ipsum volutpat posuere. Donec ante justo, fringilla at, fermentum quis, sagittis nec, ante.<br /><br /> + +Proin lobortis. Sed a tellus ut nulla vestibulum gravida. Suspendisse potenti. Fusce at nisi. Ut risus. Duis velit. In hac habitasse platea dictumst. Suspendisse augue eros, condimentum sit amet, vulputate id, volutpat in, orci. Praesent tempor, pede eu fermentum pharetra, ante metus pretium velit, accumsan varius risus erat vitae enim. Nullam sapien dui, malesuada sit amet, hendrerit eget, viverra sed, augue. Vivamus vulputate justo sed metus. Proin lacus. Cras erat augue, adipiscing nec, semper fermentum, varius id, urna. Quisque mi nunc, fringilla ut, pellentesque in, commodo sit amet, urna. Nunc luctus.<br /><br /> + +Maecenas elementum eros ac justo. Proin felis. Duis pretium sagittis nisi. Praesent ac nulla. Nullam dui tellus, vestibulum nec, condimentum nec, dapibus in, mauris. Duis felis. Mauris sodales, nibh at viverra eleifend, libero ante hendrerit enim, non congue massa dolor sit amet orci. Sed urna leo, ullamcorper a, luctus ut, tincidunt at, ipsum. Duis placerat ullamcorper sapien. Cras a quam eget libero venenatis viverra.<br /><br /> + +Curabitur hendrerit blandit massa. Suspendisse ligula urna, aliquet sit amet, accumsan in, porttitor nec, dolor. Praesent sodales orci vitae diam. Ut convallis ipsum egestas ligula. Aenean feugiat pede sit amet nulla. Suspendisse enim ante, porta eu, imperdiet in, congue nec, enim. Phasellus vitae velit nec risus hendrerit pharetra. Suspendisse potenti. Donec rutrum ultricies diam. Nulla nisl. Etiam justo enim, bibendum sit amet, mollis ac, fringilla ut, nunc. Proin euismod pede vitae ligula. Proin ante eros, commodo eu, ultrices eu, sagittis sed, nisi. Nullam et leo. Fusce consectetuer orci eget odio. Maecenas accumsan posuere mauris. Maecenas adipiscing. Nulla ut tellus at ante tristique vulputate. Fusce erat.<br /><br /> + +Donec quis orci non nulla consectetuer placerat. Aliquam tincidunt auctor lacus. Fusce nisi metus, mattis id, mollis eget, laoreet vel, dui. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean faucibus mollis nibh. Fusce dapibus leo. Ut lacinia elit in turpis. Vivamus sapien sem, imperdiet eu, facilisis ut, blandit quis, purus. Vivamus urna. Vivamus non nibh sed erat ultricies sodales. Maecenas molestie sem ac pede. Etiam consequat commodo sem.<br /><br /> + +Sed vitae metus et lacus euismod malesuada. Maecenas bibendum nunc at dui. Maecenas luctus, turpis nec tincidunt convallis, arcu nisi gravida diam, vitae imperdiet mi nisl a odio. Integer vitae massa non magna ultrices ullamcorper. Morbi quis ligula in purus gravida ultrices. Nunc varius posuere diam. Mauris eget ante. Maecenas nunc. Quisque quam metus, vulputate a, tristique non, malesuada nec, pede. Sed interdum consectetuer urna. Vivamus tincidunt libero vitae nulla. Pellentesque lobortis eleifend magna. Duis vehicula gravida lorem. Vivamus tortor massa, varius ut, gravida euismod, posuere faucibus, eros. Etiam aliquam, quam sed pretium lacinia, nulla mi auctor ante, et porttitor lorem nulla vitae enim. Donec justo. Maecenas lorem. Pellentesque faucibus dapibus eros. Vivamus mollis leo id neque fringilla elementum. Phasellus convallis scelerisque ipsum.<br /><br /> + +Sed sapien dui, pharetra a, fringilla interdum, vestibulum nec, tellus. Suspendisse ultrices diam quis lectus. Nulla neque felis, tincidunt vitae, suscipit at, gravida euismod, felis. Sed elementum eros eu nisl. Pellentesque imperdiet. Donec vehicula. Duis eu purus molestie diam volutpat lacinia. Phasellus ultricies pharetra pede. Suspendisse varius leo non dui. Aliquam erat volutpat. Nam nisi. Vivamus pellentesque congue eros. Integer risus. Nullam lectus. Sed vel sapien. Praesent blandit neque eu enim.<br /><br /> + +Nunc dictum venenatis velit. Ut aliquam velit. In dapibus, nisl vel elementum auctor, erat metus elementum ligula, vel molestie lectus nulla nec nulla. Sed tempus elit eget diam. Suspendisse potenti. Mauris tempus ante eu magna. Suspendisse potenti. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut iaculis tristique pede. Cras vel mauris sed mi accumsan blandit. Nulla vel tortor. Etiam lacinia. Suspendisse eget lectus sed nisl sodales ultricies. Aliquam venenatis ante quis tortor. Fusce a lorem.<br /><br /> + +Mauris euismod sagittis urna. Pellentesque pulvinar tellus id libero. Morbi id magna ut libero vehicula sodales. Nulla pretium. Sed mauris leo, scelerisque a, varius a, commodo convallis, erat. In tellus. Suspendisse velit felis, sodales non, lacinia quis, iaculis eu, tortor. Nunc pellentesque. In iaculis est a mi viverra tincidunt. Etiam eleifend mi a ante. Nullam et risus. Etiam tempor enim id nunc vehicula vestibulum. Pellentesque mollis, felis eu laoreet feugiat, tortor enim convallis eros, non mollis justo ipsum et sem. Cras egestas massa. Sed molestie, turpis ac imperdiet tristique, turpis arcu rhoncus elit, vitae imperdiet enim massa at lorem. Donec aliquam laoreet nunc.<br /><br /> + +Cras arcu justo, fringilla sit amet, ultricies eu, condimentum gravida, urna. In erat. Vivamus rhoncus ipsum quis quam. In eu tortor et eros accumsan malesuada. Curabitur hendrerit quam et risus ultrices porta. Maecenas pulvinar turpis vel arcu. Cras erat. Mauris tempus. Nunc a risus id nulla ultricies ullamcorper. Aenean nec mi ut dolor elementum iaculis. Sed nisi. Donec nisl lectus, condimentum nec, commodo ac, imperdiet id, nibh. Morbi ante sapien, laoreet eget, auctor et, tempus nec, elit. Aliquam luctus est eu elit.<br /><br /> + +Sed malesuada interdum purus. Aenean id odio sed dolor sagittis porttitor. Sed nec ipsum. Nullam porttitor nunc sit amet leo. Praesent condimentum sapien quis tortor. Sed dapibus ipsum id risus. Fusce dapibus fringilla nunc. Cras tristique mauris sit amet diam. Suspendisse molestie, nisl ut scelerisque pharetra, lorem leo rutrum quam, in vestibulum felis nulla vitae sapien. Integer elementum velit quis eros adipiscing scelerisque. Etiam ac purus sit amet est laoreet porttitor. Etiam gravida pretium felis. Aenean sapien. Sed est tellus, hendrerit pellentesque, imperdiet sed, tempus at, dolor. Integer feugiat lectus vulputate metus. Mauris at neque.<br /><br /> + +Nunc nec orci in dui aliquet placerat. Aenean ultrices diam quis nisl. Phasellus tempor lorem sed orci. Nam mauris erat, congue ac, condimentum quis, accumsan eget, lectus. Cras vulputate pulvinar lorem. Proin non mi ac orci gravida gravida. Fusce urna. Proin suscipit dui ultrices justo. Nullam pretium nibh quis dui. Cras sem magna, lacinia sit amet, laoreet id, pretium sed, nisi. Suspendisse et pede bibendum erat porttitor blandit. Vestibulum condimentum nisi pellentesque eros.<br /><br /> + +Proin tellus. Pellentesque eu nulla ut lorem dictum tincidunt. Duis non enim. Sed ornare magna dignissim lectus. Curabitur ligula. Maecenas varius. Pellentesque condimentum bibendum diam. Ut sed nibh ut libero consectetuer rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer ligula. Etiam accumsan. Ut vestibulum auctor mi. In hac habitasse platea dictumst. Nunc mollis. Aenean velit metus, auctor ac, lacinia sit amet, facilisis sed, risus. Nam aliquam volutpat elit. Quisque quis diam sed felis mollis feugiat. Aliquam luctus. Donec nec magna.<br /><br /> + +Morbi porttitor viverra tellus. Duis elit lectus, convallis nec, rutrum nec, accumsan vel, tellus. Duis venenatis nisl in velit. Donec mauris. Morbi a diam at felis molestie dignissim. Praesent consectetuer leo sed tortor. Aliquam volutpat, eros vitae facilisis rhoncus, nibh massa sagittis magna, sed placerat metus turpis a ligula. Proin at purus ut erat feugiat consequat. Nam ornare libero nec turpis. Aenean eget quam vitae diam convallis faucibus. Duis molestie turpis vel lacus semper convallis.<br /><br /> + +Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed tempus turpis eget quam fringilla fermentum. Curabitur risus magna, congue vel, commodo sed, tempus sit amet, lacus. Curabitur quam nulla, bibendum in, hendrerit eu, ultricies vitae, ligula. Curabitur nisl. Mauris nulla justo, laoreet non, faucibus sit amet, vulputate sit amet, lectus. Maecenas pharetra ligula quis nisl. Suspendisse suscipit tortor ac eros. Ut non urna tincidunt sapien aliquet consectetuer. Etiam convallis. Proin tempor tellus et dui. Donec sit amet lorem. Etiam et eros id nisl fermentum varius. Aenean ultricies. Donec leo. Vivamus adipiscing tempus dolor.<br /><br /> + +Vestibulum convallis venenatis quam. Quisque sed ante. Pellentesque auctor ipsum sed mi. Integer gravida. Sed molestie nisi tempus quam. In varius. Curabitur feugiat, erat sed imperdiet interdum, ante justo convallis diam, at condimentum nunc odio a nulla. Nam turpis enim, sodales at, cursus varius, volutpat sed, risus. Nunc malesuada suscipit dui. Donec tincidunt molestie diam. Phasellus mattis congue neque. Maecenas in lorem. Maecenas ultricies rhoncus arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce varius purus in nibh.<br /><br /> + +Curabitur lobortis mi fermentum nisi. Donec sed augue at nisl euismod interdum. Nam ultrices mi sit amet quam. Quisque luctus sem id lorem. Phasellus mattis neque id arcu. Aliquam pellentesque iaculis mi. Ut at libero ut felis iaculis dapibus. Proin mauris. Etiam vel orci nec magna vehicula lacinia. Vivamus eu nulla. Aenean vehicula, nunc ac cursus dictum, elit odio tempor mauris, ultrices porta ligula erat ac nibh. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc ac nibh placerat massa dapibus lobortis. Maecenas et mi. Etiam vel ipsum. Nam nisl. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec laoreet massa egestas lectus. Maecenas dictum. Integer at purus.<br /><br /> + +Phasellus nisi. Duis ullamcorper justo in est. Suspendisse potenti. Nunc velit est, ultricies eu, facilisis sed, condimentum ut, ligula. Phasellus a metus. Fusce ac elit adipiscing justo tincidunt varius. Quisque pede. Nulla porta ante eget nunc. Pellentesque viverra. Nunc eleifend. Nulla facilisi. Mauris molestie est a arcu. Pellentesque aliquam, sapien id tincidunt feugiat, lectus massa porttitor pede, id accumsan ipsum nisi vel ligula. Integer eu enim et dui suscipit varius.<br /><br /> + +Aliquam a odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus rhoncus posuere nisi. Integer et tellus in odio ultrices euismod. Vestibulum facilisis placerat nisl. Fusce sed lectus. Aenean semper enim. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec congue tortor accumsan erat. Pellentesque diam erat, congue congue, tristique ac, auctor a, sem. Donec feugiat leo id augue.<br /><br /> + +Sed tempor est non augue. Suspendisse pretium fermentum erat. Quisque dapibus tellus vitae sapien. Vivamus feugiat libero non nunc. Phasellus ornare aliquet arcu. Sed faucibus. Phasellus hendrerit tortor vitae elit pellentesque malesuada. Donec eu tortor quis lacus fermentum congue. Pellentesque adipiscing risus at felis. Quisque est. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales nisl non pede. Etiam ac libero. Morbi euismod libero faucibus velit dignissim tempor.<br /><br /> + +Nam tempor, velit in condimentum bibendum, arcu elit adipiscing sapien, vitae adipiscing enim lectus nec tortor. Aliquam varius egestas arcu. Duis nisl libero, commodo egestas, ultrices sed, convallis non, lectus. Proin semper. Donec pretium. In bibendum luctus metus. Quisque et tortor. Sed ultricies. Sed libero. Phasellus vel lacus at eros pretium dignissim. Phasellus risus nisi, sodales at, ultricies eleifend, laoreet in, neque. Suspendisse accumsan gravida lectus. Donec sed nulla. Pellentesque lobortis lorem at felis. Morbi ultricies volutpat turpis.<br /><br /> + +Donec nisl risus, vulputate ac, congue consequat, aliquam et, dolor. Proin accumsan lorem in augue. Donec non nisi. Ut blandit, ligula ut sagittis aliquam, felis dolor sodales odio, sit amet accumsan augue tortor vitae nulla. Nunc sit amet arcu id sapien mollis gravida. Etiam luctus dolor quis sem. Nullam in metus sed massa tincidunt porttitor. Phasellus odio nulla, ullamcorper quis, ornare non, pretium sed, dui. Quisque tincidunt. Proin diam sapien, imperdiet quis, scelerisque nec, scelerisque non, sapien. Nulla facilisi.<br /><br /> + +Donec tempor dolor sit amet elit. Maecenas nec ipsum eu quam consectetuer sodales. Duis imperdiet ante ac tellus. Vestibulum blandit porta ipsum. Aenean purus justo, mollis eu, consectetuer vel, sodales sollicitudin, leo. Mauris sollicitudin ullamcorper odio. Maecenas metus turpis, fringilla nec, tincidunt sed, pellentesque ut, libero. Suspendisse bibendum. Phasellus risus nibh, luctus ac, sagittis in, sagittis a, libero. Etiam fringilla, dui tristique fringilla sollicitudin, urna odio malesuada sapien, ut dictum augue lorem ac eros. Phasellus lobortis neque eget ipsum. Proin neque ipsum, posuere in, semper eu, tempor eu, leo.<br /><br /> + +Pellentesque ante nulla, sodales in, euismod vel, eleifend vitae, turpis. Sed nunc. Sed eleifend elit non ipsum. Quisque posuere sapien vel metus. Nullam euismod eleifend nunc. Vestibulum ligula urna, posuere sit amet, posuere ac, rutrum id, libero. Mauris lorem metus, porta at, elementum quis, tempor ut, nibh. Aenean porttitor magna quis odio. Praesent pulvinar varius leo. Maecenas vitae risus tristique mauris imperdiet congue. Duis ullamcorper venenatis velit. Phasellus eleifend. Maecenas nec velit. Aliquam eget turpis. Cras iaculis volutpat nulla. Donec luctus, diam eu varius convallis, diam justo venenatis erat, convallis mattis mauris mauris vitae lacus. Pellentesque id leo. Donec at massa vitae mi bibendum vehicula. Proin placerat.<br /><br /> + +Mauris convallis dui sit amet enim. Nullam dui. Integer convallis. Nunc ac sapien. Curabitur et felis. Sed velit odio, porta vitae, malesuada sed, convallis sed, turpis. Praesent eget magna. Maecenas at risus. Curabitur dictum. Maecenas ligula lectus, viverra ut, pulvinar sed, pulvinar at, diam. Suspendisse bibendum urna id odio. Mauris adipiscing. Donec accumsan lorem nec nunc. Sed commodo.<br /><br /> + +Nulla facilisi. Morbi eget mauris sit amet augue varius imperdiet. Donec viverra erat eget metus. Proin pharetra condimentum quam. Nunc vel odio. Mauris elementum augue nec metus. Vivamus quam. Donec nec quam. Integer lacus odio, placerat sed, tempus nec, bibendum in, justo. Nulla aliquam, neque vel sagittis adipiscing, lectus massa gravida quam, ut pulvinar tellus massa lobortis massa.<br /><br /> + +Curabitur vitae nisi et lectus porttitor euismod. Morbi ultricies convallis nunc. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla lobortis faucibus nulla. Maecenas pharetra turpis commodo dolor. Donec dolor neque, consectetuer non, dignissim at, blandit ultricies, felis. Nunc quis justo. Maecenas faucibus. Sed eget purus. Aenean dui eros, luctus a, rhoncus non, vestibulum bibendum, pede. Proin imperdiet sollicitudin sem.<br /><br /> + +Suspendisse nisi nisl, commodo a, aliquam ut, commodo bibendum, neque. Donec blandit. Mauris tortor. Proin lectus ipsum, venenatis non, auctor vel, interdum vel, lacus. Nullam tempor ipsum a enim. Duis elit elit, cursus vel, venenatis in, dignissim vitae, neque. Morbi erat. Proin rutrum hendrerit massa. Pellentesque ultrices, ligula eu molestie auctor, tellus elit rhoncus turpis, at aliquet ante pede id ipsum. Aenean vitae est. Aliquam non neque. Ut nunc. Nulla at elit eu nunc molestie suscipit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent nec ipsum. Vivamus elit arcu, faucibus non, pulvinar vel, vehicula et, massa. Aenean non sapien vitae sapien porttitor pretium. Sed vestibulum, lorem id venenatis hendrerit, mi nunc gravida ligula, sed euismod justo felis sit amet dolor. Duis molestie, nunc mattis feugiat accumsan, nibh est posuere nibh, volutpat consectetuer risus eros eget lectus.<br /><br /> + +Vivamus non mauris. Nullam ornare convallis magna. In congue feugiat velit. Proin tellus magna, congue eu, scelerisque ut, hendrerit ac, lorem. Suspendisse potenti. Sed rhoncus, nunc sed tempus venenatis, eros dolor ultricies felis, nec tincidunt pede sem eget orci. Sed consequat leo. In porta turpis eget nibh. Aliquam sem tortor, gravida eu, fermentum vulputate, vestibulum in, nibh. Vivamus volutpat eros ac eros posuere tristique. Nam posuere erat vitae eros. Suspendisse potenti. Integer mattis dolor ac purus. Donec est turpis, lacinia non, vulputate non, pellentesque eu, sem. Morbi mollis volutpat lacus. Donec vitae justo. Aliquam mattis lacus in ipsum cursus sollicitudin. Sed bibendum rutrum odio. Donec nulla justo, pulvinar et, faucibus eget, tempus non, quam.<br /><br /> + +Morbi malesuada augue ac libero pellentesque faucibus. Donec egestas turpis ac nunc. Integer semper. Nam auctor justo ac enim. Curabitur diam elit, tristique ac, viverra eget, placerat ac, nisl. Aenean faucibus auctor diam. Nam sed augue. Duis posuere massa vel nulla. Integer diam sem, fermentum quis, dignissim eget, egestas quis, ante. Donec sit amet mauris. Mauris id mauris quis purus sagittis malesuada. Suspendisse in justo at ipsum pharetra pellentesque. In quis eros. Phasellus cursus, libero eu vulputate molestie, felis eros tempor dui, vel viverra nulla pede in dui. Nulla tortor massa, eleifend sed, dapibus et, mollis sollicitudin, diam. Integer vitae ipsum ac velit egestas dictum. Fusce sed neque ac erat sagittis elementum. Nulla convallis, sem id ullamcorper rhoncus, pede lorem imperdiet pede, eu pharetra nisi tortor ac felis.<br /><br /> + +Donec fringilla. Mauris elit felis, tempor aliquam, fringilla quis, tempor et, ipsum. Mauris vestibulum, ante commodo tempus gravida, lectus sem volutpat magna, et blandit ante urna eget justo. Curabitur fermentum, ligula at interdum commodo, nibh nunc pharetra ante, eu dictum justo ligula sed tortor. Donec interdum eleifend sapien. Pellentesque pellentesque erat eu nunc. Vivamus vitae ligula sit amet mauris porta luctus. Nullam tortor. Aenean eget augue. Donec ipsum metus, pulvinar eget, consectetuer ac, luctus id, risus. Aliquam interdum eros molestie sapien. Vivamus et enim. Donec adipiscing cursus ante.<br /><br /> + +Phasellus turpis elit, suscipit non, pellentesque nec, imperdiet eget, ante. Sed mauris nulla, tempus ut, fringilla id, tempus vitae, magna. Pellentesque luctus justo nec augue. Aliquam pharetra mollis magna. Nunc dui augue, sollicitudin ut, cursus eget, vestibulum eget, sem. Donec ac dolor eget enim sodales cursus. Morbi interdum. Cras vel eros non elit faucibus aliquet. Donec quis lectus ut libero sagittis lacinia. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec ante. Nam odio. Mauris turpis. Ut dolor. Aenean suscipit tellus a turpis.<br /><br /> + +Ut mollis dolor ut felis. Aliquam euismod odio in dui. Donec tincidunt. Etiam malesuada velit nec lacus. Etiam ullamcorper feugiat odio. Sed quis urna. Morbi vehicula erat at sapien. Suspendisse potenti. Ut auctor sem ac odio. Nulla nec nisi. Aliquam iaculis ipsum non elit. Cras feugiat egestas lacus. Aenean eget nulla ac nisl feugiat scelerisque. Aenean posuere iaculis tellus. Duis posuere suscipit magna. Duis sagittis, massa sit amet fringilla tempus, nulla mi lobortis leo, in blandit quam felis in quam.<br /><br /> + +Donec orci. Pellentesque purus. Suspendisse diam erat, posuere quis, tempor vestibulum, cursus in, mi. In vehicula urna ut lacus. Etiam sollicitudin purus vitae metus. In eget nisi ac enim mattis dictum. Duis quis nunc. Fusce ac neque eu sem aliquam porttitor. Integer at nisl vitae odio dictum gravida. Quisque laoreet, neque ac ultrices accumsan, arcu nibh dignissim justo, eu eleifend nibh pede non purus. Duis molestie eros eget risus. Curabitur nibh. Nunc at ipsum ultricies urna posuere sollicitudin. Nullam placerat. Aliquam varius ipsum sed nisl. Fusce condimentum, mauris a ornare venenatis, lorem risus vulputate leo, ac pellentesque ligula ligula vel lacus. Quisque at diam. Proin gravida mauris sed tellus. Curabitur enim.<br /><br /> + +Vivamus luctus, erat a varius pellentesque, augue purus porttitor eros, non sollicitudin purus lorem et dui. Nunc magna. Nam in pede. Donec molestie justo eu ligula feugiat vulputate. Nunc euismod. Donec accumsan, velit vitae aliquet suscipit, massa augue mattis magna, a interdum nisi eros sit amet lacus. Suspendisse euismod enim sed leo. Donec nunc. Suspendisse tristique arcu ac elit. Suspendisse blandit dui. Suspendisse potenti. Integer mollis, nisi vitae lobortis dignissim, mauris arcu sagittis est, quis sodales turpis est a lacus. Morbi lacinia eros a velit. Aenean blandit, ligula ut facilisis facilisis, neque lectus interdum magna, vel dictum tortor leo non nisl. Quisque enim. Donec ut turpis. Phasellus cursus. Aenean sem. Suspendisse potenti. Vestibulum neque.<br /><br /> + +Cras pulvinar tempus justo. Nulla facilisi. Sed id lorem consequat quam suscipit tincidunt. Donec ac ante. Duis leo lacus, ultrices et, mattis et, fringilla sit amet, tellus. Donec tincidunt. Nam non ligula et leo pellentesque hendrerit. Integer auctor consequat est. Morbi id magna. Nam massa nunc, dignissim ut, tincidunt nec, aliquet ac, purus. Etiam accumsan. Phasellus mattis sem in nibh. Morbi faucibus ligula eget lectus. Mauris libero felis, accumsan et, tincidunt quis, suscipit et, elit. Ut luctus, turpis ut iaculis tincidunt, lorem metus tempus sem, a lacinia quam metus nec justo. Integer molestie sapien vitae leo. Suspendisse tristique. Curabitur elit ante, vulputate ac, euismod in, vehicula tincidunt, metus. Quisque ac risus. Nunc est libero, pulvinar ac, sodales at, scelerisque at, nibh.<br /><br /> + +Praesent id lacus. Sed vitae metus. Mauris iaculis luctus tellus. Phasellus dictum nunc. In metus orci, pellentesque sit amet, dictum et, tincidunt aliquam, dolor. Nulla malesuada. Phasellus lacus. Suspendisse leo risus, tincidunt vitae, varius sed, scelerisque id, massa. Suspendisse id elit. In vel justo eu sem vulputate molestie. Maecenas rhoncus imperdiet augue. Sed est justo, mattis dictum, dapibus eu, rhoncus vel, velit. Aenean velit urna, congue quis, convallis ullamcorper, aliquam id, tortor. Morbi tempor.<br /><br /> + +Nunc mollis pede vitae sem. Nulla facilisi. Etiam blandit, magna sed ornare laoreet, est leo mattis sem, id dignissim orci nunc at nisl. In vel leo. Aliquam porttitor mi ut libero. Nulla eu metus. Integer et mi vitae leo adipiscing molestie. Ut in lacus. Curabitur eu libero. Vivamus gravida pharetra lectus. Quisque rutrum ultrices lectus. Integer convallis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec nisi dolor, rhoncus et, tristique id, lacinia id, massa.<br /><br /> + +Aenean elit. Praesent eleifend, lacus sed iaculis aliquet, nisl quam accumsan dui, eget adipiscing tellus lacus sit amet mauris. Maecenas iaculis, ligula sed pulvinar interdum, orci leo dignissim ante, id tempor magna enim nec metus. Cras ac nisl eu nisl auctor ullamcorper. Etiam malesuada ante nec diam. Quisque sed sem nec est lacinia tempor. Sed felis. Proin nec eros vitae odio blandit gravida. Proin ornare. Nunc eros. Nam enim. Nam lacinia. Quisque et odio sit amet turpis ultricies volutpat. Aenean varius. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Cras et mi. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec consequat imperdiet lacus. Morbi lobortis pellentesque sem.<br /><br /> + +Mauris id augue sed erat blandit rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Curabitur lectus velit, varius at, eleifend id, gravida nec, elit. Nulla facilisi. Vestibulum tempus turpis eget nulla. Cras nisl mi, iaculis vel, dapibus id, facilisis vitae, dolor. Praesent turpis. Vestibulum scelerisque, neque sed rhoncus tincidunt, tellus sem consectetuer quam, vel accumsan nisl ipsum ac diam. Nulla tellus massa, dapibus id, consequat vehicula, elementum ac, lorem. Vestibulum faucibus faucibus nisl. Quisque mauris enim, rutrum vestibulum, venenatis vel, venenatis nec, sapien. Quisque vel sem a nibh rutrum tincidunt. Praesent metus velit, pretium vel, ornare non, elementum ut, purus. Quisque mauris magna, scelerisque sed, condimentum dictum, auctor vitae, nisi. Mauris sed ligula. Proin purus diam, sollicitudin vel, rutrum nec, imperdiet sit amet, erat.<br /><br /> + +Aliquam a metus ac ipsum sagittis luctus. Quisque quis nisl in odio euismod pretium. Vestibulum quis mi. Maecenas imperdiet, mauris sit amet viverra aliquet, ligula augue imperdiet orci, a mollis dolor nisl nec arcu. Morbi metus magna, fringilla sed, mollis porttitor, condimentum ut, risus. Phasellus eu sapien eu felis auctor congue. Ut aliquam nisi ac dui. Morbi id leo eget nisi ultricies lobortis. Donec auctor. Praesent vulputate. Morbi viverra. Sed elementum arcu eu nibh. Fusce non velit nec dui lobortis posuere. Suspendisse pretium, tortor at cursus laoreet, elit lorem vulputate ipsum, at elementum nisi nisi non nunc. Vestibulum aliquam massa vitae neque. Praesent eget arcu sit amet lacus euismod interdum.<br /><br /> + +Duis lectus massa, luctus a, vulputate ut, consequat ut, enim. Proin nisi augue, consectetuer nec, bibendum eget, tempor nec, nulla. Suspendisse eu lorem. Praesent posuere. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin lorem. Integer vehicula. Curabitur lorem turpis, pulvinar a, commodo ut, scelerisque ac, tortor. Morbi id enim non est consectetuer aliquam. Etiam gravida metus porta orci. Vestibulum velit elit, bibendum non, consequat sit amet, faucibus non, lorem. Integer mattis, turpis nec hendrerit lacinia, pede urna tincidunt dui, vel lobortis lorem lorem ac magna.<br /><br /> + +Curabitur faucibus. Nam a urna in diam egestas luctus. Curabitur mi neque, tincidunt vel, iaculis id, iaculis in, quam. Praesent sodales bibendum orci. Nulla eu nunc ut purus eleifend aliquet. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Fusce vulputate lorem sit amet enim. Nulla feugiat pretium sapien. Curabitur eget eros. Aenean sagittis sagittis dui. Praesent vel eros vitae dolor varius malesuada. Mauris suscipit lacus at erat. Mauris vestibulum. In et enim nec eros ultricies ultricies. Maecenas tempus lorem.<br /><br /> + +Morbi metus elit, posuere id, rutrum et, porttitor a, mauris. Aliquam in orci in augue sodales venenatis. Ut ac purus. Fusce pharetra libero eget ligula. Praesent vel mi vitae nulla mollis dictum. Sed metus lorem, malesuada in, dictum ut, tincidunt a, dolor. Mauris rutrum sem fringilla massa adipiscing vestibulum. Cras viverra aliquet ligula. Aliquam quis leo. Nullam volutpat egestas odio. Nullam suscipit velit. Ut dapibus, ipsum ut dictum viverra, dui purus pharetra lectus, nec imperdiet ante metus sed dolor. Donec suscipit velit eu elit. Vestibulum eget lacus id tellus pharetra suscipit. Phasellus pede. Nulla posuere, odio ac congue placerat, arcu erat faucibus nisi, fringilla facilisis ligula quam a orci. Morbi mollis urna. Maecenas felis. Sed at arcu.<br /><br /> + +Nam sit amet orci vel libero sollicitudin facilisis. Nunc fermentum pretium est. Donec dictum massa ut nibh. In gravida ullamcorper mauris. Cras sed odio. Praesent dolor metus, mattis a, vestibulum ac, iaculis in, purus. Proin egestas cursus arcu. Nullam feugiat, diam pulvinar convallis aliquet, odio felis facilisis urna, eu commodo leo risus eget dui. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In sodales tellus eu lectus. Mauris pulvinar.<br /><br /> + +Etiam sed mi vitae felis pellentesque mattis. Nunc at metus et est porttitor pellentesque. Mauris ligula velit, faucibus eu, aliquet a, sodales sed, libero. Nulla vulputate. Duis enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Morbi mattis mattis eros. Nullam id tellus ut arcu convallis dictum. Vestibulum tempus facilisis sem. Maecenas tempor.<br /><br /> + +Pellentesque pellentesque vehicula lectus. Sed viverra adipiscing arcu. Proin auctor nisl id tellus. Nunc pulvinar viverra nibh. Aliquam posuere sapien non nunc. Maecenas tristique, tortor sed vulputate dictum, tortor elit consectetuer sapien, at malesuada nunc ligula mollis nisi. Curabitur nisi elit, scelerisque at, pharetra interdum, cursus sit amet, nisl. Mauris ornare, orci id convallis rutrum, purus justo laoreet ligula, at posuere sapien nisi quis dolor. Quisque viverra. Ut dapibus. Maecenas vulputate. Praesent bibendum metus vitae urna.<br /><br /> + +Aliquam eget quam eleifend augue dictum pellentesque. Pellentesque diam neque, sodales vestibulum, imperdiet vitae, posuere at, ligula. In ac felis. Cras nisl. Pellentesque lobortis augue quis sapien. Maecenas suscipit tempor elit. Nulla pellentesque. Pellentesque lacus. Cras dignissim tortor et lectus. Donec cursus mauris eget nulla. Aenean facilisis facilisis pede. Nullam aliquet volutpat ante. Maecenas libero ante, fermentum id, hendrerit vehicula, ultrices ac, erat. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi laoreet egestas felis. Nunc varius nulla id mauris. Maecenas id massa.<br /><br /> + +Praesent pellentesque libero et mi. Ut semper nulla eu elit. Vivamus nibh eros, vestibulum eget, luctus a, faucibus et, ante. Duis elementum dolor sed turpis. Aliquam elit. Etiam accumsan volutpat mauris. Integer interdum porta diam. Sed sed erat. Curabitur tristique. Praesent non nunc. Praesent quam est, tempus a, ornare vitae, pellentesque quis, orci. Vivamus id nulla. Nam pede lacus, placerat ut, sollicitudin ut, sodales id, augue. Nullam ultricies. Sed ac magna. Mauris eu arcu sit amet velit rutrum rutrum. Sed eu felis vitae ipsum sollicitudin gravida. Proin in arcu. Maecenas rhoncus, quam at facilisis fermentum, metus magna tempus metus, quis egestas turpis sem non tortor.<br /><br /> + +Ut euismod. Suspendisse tincidunt tincidunt nulla. In dui. Praesent commodo nibh. Pellentesque suscipit interdum elit. Ut vitae enim pharetra erat cursus condimentum. Sed tristique lacus viverra ante. Cras ornare metus sit amet nisi. Morbi sed ligula. Mauris sit amet nulla et libero cursus laoreet. Integer et dui. Proin aliquam, sapien vel tempor semper, lorem elit scelerisque nunc, at malesuada mi lorem vel tortor. Curabitur in sem. Pellentesque cursus. Curabitur imperdiet sapien. Aliquam vehicula consequat quam.<br /><br /> + +Aliquam erat volutpat. Donec lacinia porttitor mauris. Suspendisse porttitor. Integer ante. Ut et risus vitae lacus consectetuer porttitor. Curabitur posuere aliquam nulla. Pellentesque eleifend, mauris eu commodo tincidunt, ligula pede bibendum libero, ut aliquet nisi tellus at justo. Suspendisse quis lectus. Quisque iaculis dapibus libero. Fusce aliquet mattis risus.<br /><br /> + +Suspendisse rutrum purus a nibh. Etiam in urna. Pellentesque viverra rhoncus neque. Mauris eu nunc. Integer a risus et est suscipit condimentum. Nulla lectus mi, vulputate vitae, euismod at, facilisis a, quam. Quisque convallis mauris et ante. Nunc aliquet egestas lorem. Integer sodales ante et velit. Curabitur malesuada. Suspendisse potenti. Mauris accumsan odio in nulla. Vestibulum luctus eleifend lacus. Aenean diam. Nullam nec metus. Curabitur id eros a elit pulvinar mattis. Donec dignissim consequat sapien. Praesent dictum, metus eget malesuada pellentesque, risus ante ultrices neque, eu gravida augue mi a pede. Morbi ac justo.<br /><br /> + +Donec tempus consequat mauris. Sed felis lorem, lobortis et, sodales sit amet, adipiscing a, eros. Vestibulum vitae nunc non lectus porta bibendum. Curabitur nulla. Proin auctor nisl eget lacus. Donec dignissim venenatis nibh. Suspendisse ullamcorper tempus augue. Donec dictum sodales ipsum. Phasellus ac urna sit amet purus sagittis ullamcorper. Etiam orci.<br /><br /> + +Phasellus facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eros purus, auctor ac, auctor sed, placerat tincidunt, mi. Aliquam nibh est, congue sed, tempus vitae, pellentesque in, dui. Nullam mattis dapibus urna. Morbi at lorem. Praesent lobortis, sem et interdum suscipit, erat justo mattis nisl, vitae pulvinar quam leo in turpis. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam quis massa non sapien accumsan congue. Praesent adipiscing. Vivamus tempus aliquam nunc. Quisque id sem ac eros tincidunt mattis. Etiam magna augue, feugiat ut, pretium vitae, volutpat quis, turpis. Morbi leo. Ut tortor. Nunc non mi. Maecenas tincidunt massa eu ligula. Vestibulum at nibh.<br /><br /> + +Nunc vestibulum. Curabitur at nunc ac nisl vulputate congue. Suspendisse scelerisque. Integer mi. In hac habitasse platea dictumst. Donec nulla. Sed sapien. Aenean ac purus. Duis elit erat, hendrerit at, adipiscing in, fermentum ut, nibh. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;<br /><br /> + +Donec elit. Duis consequat purus vitae mauris. Mauris a tortor vel mi fringilla hendrerit. Curabitur mi. Aliquam arcu nibh, bibendum quis, bibendum sed, ultricies sit amet, ante. Morbi tincidunt, justo pellentesque feugiat rhoncus, est enim luctus pede, id congue metus odio eu mi. Fusce blandit nunc a lorem. Cras non risus. Nullam magna eros, elementum eu, mollis viverra metus. + </body> +</html> diff --git a/dom/base/test/test_bug444546.html b/dom/base/test/test_bug444546.html new file mode 100644 index 0000000000..3209f90549 --- /dev/null +++ b/dom/base/test/test_bug444546.html @@ -0,0 +1,160 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=444546 +--> +<head> + <title>Test for Bug 444546</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <style> + .up { + height: 14px; + width: 1px; + background: blue; + font-size: 11px; + color: white; + } + .down { + height: 14px; + width: 1px; + background: blue; + font-size: 11px; + color: white; + } + </style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=444546">Mozilla Bug 444546</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 444546 **/ + + var xhrCount = 5; + var xhrs = new Array(); + var uploads = new Array(); + var maxSize = 5000000; + var hugeString = new Array(maxSize + 1).join('a'); + + function updateProgress(evt) { + ++evt.target.pcounter; + var time = new Date().getTime(); + // 350 - 200 = 150ms + if ((time - evt.target.prevTime) < 150) { + evt.target.log.parentNode.style.background = "red"; + } + var diff = (time - evt.target.prevTime); + if (evt.target.min == -1 || evt.target.min > diff) { + evt.target.min = diff; + } + if (evt.target.max == -1 || evt.target.max < diff) { + evt.target.max = diff; + } + + evt.target.log.textContent = diff + "ms"; + evt.target.prevTime = time; + if (evt.lengthComputable) { + var loaded = (evt.loaded / evt.total); + if (loaded < 1) { + evt.target.log.style.width = (loaded * 400) + "px"; + } + } + } + + function loaded(evt) { + evt.target.log.style.width = "400px"; + evt.target.log.style.background = "green"; + if ("xhr" in evt.target) { + evt.target.xhr.prevTime = new Date().getTime(); + evt.target.xhr.startTime = evt.target.xhr.prevTime; + } + var total = new Date().getTime() - evt.target.startTime; + evt.target.log.textContent = "total:" + total + "ms"; + if (evt.target.pcounter) { + evt.target.log.textContent += " ," + evt.target.pcounter + "pe, avg:" + + parseInt((evt.target.prevTime - evt.target.startTime)/evt.target.pcounter) + "ms"; + } + if (evt.target.min != -1) { + ok(evt.target.min >= 150, "Events fired too fast!"); + evt.target.log.textContent += ", min:" + evt.target.min + "ms"; + } + if (evt.target.max != -1) { + // Disabled for now. + //ok(evt.target.max <= 550, "Events didn't fire fast enough!"); + evt.target.log.textContent += ", max:" + evt.target.max + "ms"; + } + if ("upload" in evt.target) { + is(evt.total, maxSize * 10, "Wrong data!"); + --xhrCount; + if (xhrCount == 0) { + // This is a hack. To get more progress events, server sends the data + // 10 times. + SimpleTest.finish(); + } else { + setTimeout(start, 10); + } + } else { + is(evt.total, maxSize, "Wrong data!"); + } + } + + function start() { + var xhr = new XMLHttpRequest(); + xhrs.push(xhr); + uploads.push(xhr.upload); + var container = document.createElement("tr"); + var td1 = document.createElement("td"); + container.appendChild(td1); + td1.textContent = xhrs.length + "."; + var td2 = document.createElement("td"); + container.appendChild(td2); + var td3 = document.createElement("td"); + container.appendChild(td3); + var uploadElement = document.createElement("div"); + td2.appendChild(uploadElement); + uploadElement.className = "up"; + var downloadElement = document.createElement("div"); + td3.appendChild(downloadElement); + downloadElement.className = "down"; + document.getElementById('tbody').appendChild(container); + xhr.log = downloadElement; + xhr.upload.log = uploadElement; + xhr.onprogress = updateProgress; + xhr.upload.onprogress = updateProgress; + xhr.onload = loaded; + xhr.upload.onload = loaded; + xhr.open("POST", "bug444546.sjs"); + xhr.upload.prevTime = new Date().getTime(); + xhr.upload.startTime = xhr.upload.prevTime; + xhr.upload.xhr = xhr; + xhr.pcounter = 0; + xhr.upload.pcounter = 0; + xhr.min = -1; + xhr.upload.min = -1; + xhr.max = -1; + xhr.upload.max = -1; + xhr.send(hugeString); + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(function() { setTimeout(start, 10); }); + +</script> +</pre> + <table> + <tbody id="tbody"> + <tr> + <td>XHR</td> + <td style="min-width: 410px;">upload</td> + <td style="min-width: 410px;">download</td> + </tr> + </tbody> + </table> +</body> +</html> diff --git a/dom/base/test/test_bug444722.html b/dom/base/test/test_bug444722.html new file mode 100644 index 0000000000..ff601b9f79 --- /dev/null +++ b/dom/base/test/test_bug444722.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=444722 +--> +<head> + <title>Test for Bug 444722</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=444722">Mozilla Bug 444722</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 444722 **/ +var counter = 0; +var testCount = 0; +var xhrs = new Array(); + +function loadHandler() { + ++counter; + ok(true, "load handler should have been called."); + if (counter == testCount) { + SimpleTest.finish(); + } +} + +function testXHR(method, hasData, data) { + ++testCount; + var xhr = new XMLHttpRequest(); + xhr.open(method, "file_XHR_pass1.xml"); + xhr.onload = loadHandler; + try { + if (hasData) { + xhr.send(data); + } else { + xhr.send(); + } + } catch(ex) { + --testCount; + ok(false, "Calling XMLHttpRequest.send failed: " + ex); + } + // Keep XHR alive. + xhrs.push(xhr); +} + +SimpleTest.waitForExplicitFinish(); + +testXHR("GET", false, null); +testXHR("GET", true, null); +testXHR("GET", true, "some data"); + +testXHR("POST", false, null); +testXHR("POST", true, null); +testXHR("POST", true, "some data"); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug448993.html b/dom/base/test/test_bug448993.html new file mode 100644 index 0000000000..96364ea5b5 --- /dev/null +++ b/dom/base/test/test_bug448993.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=448993 +--> +<head> + <title>Test for Bug 448993</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448993">Mozilla Bug 448993</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 448993 **/ + +function runTest() { + var a = document.getElementById("a"); + var b = document.getElementById("b"); + var c = document.getElementById("c") + var r = document.createRange(); + r.setStart(b, 0); + r.setEnd(a, 2); + c.appendChild(b); + r.extractContents(); + var s = document.createRange(); + s.setEnd(b, 0); + SpecialPowers.gc(); + s.deleteContents(); + ok(true, "test did not crash"); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + +</script> +</pre> +<div id="a"><span id="b"></span><span id="c"></span></div> +</body> +</html> diff --git a/dom/base/test/test_bug450160.html b/dom/base/test/test_bug450160.html new file mode 100644 index 0000000000..551da939a4 --- /dev/null +++ b/dom/base/test/test_bug450160.html @@ -0,0 +1,142 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=450160 +--> +<head> + <title>Test for Bug 450160</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=450160">Mozilla Bug 450160</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 450160 **/ + + +function testHTMLDocuments(ids, isXHTML) { + for (var i = 0; i < ids.length; ++i) { + var docType1 = + document.implementation.createDocumentType(isXHTML ? "html" : "HTML", + ids[i], + null); + ok(docType1, "No doctype?"); + ok(docType1.ownerDocument, "docType should have ownerDocument!"); + var doc1 = document.implementation.createDocument(null, null, docType1); + is(docType1.ownerDocument, doc1, "docType should have ownerDocument!"); + ok(!doc1.documentElement, "Document shouldn't have document element!"); + is(doc1.body, null, "Shouldn't have .body!"); + ok(doc1 instanceof HTMLDocument, + "Document should be an HTML document!"); + + var docType2 = + document.implementation.createDocumentType(isXHTML ? "html" : "HTML", + ids[i], + null); + var doc2 = document.implementation.createDocument( + "http://www.w3.org/1999/xhtml", "html", docType2); + is(docType2.ownerDocument, doc2, "docType should have ownerDocument!"); + ok(doc2.documentElement, "Document should have document element!"); + is(doc2.documentElement.localName, "html", "Wrong document element!"); + is(doc2.body, null, "Shouldn't have .body!"); + doc2.documentElement.appendChild(doc2.createElement("body")); + is(doc2.body, doc2.documentElement.firstChild, "Should have .body!"); + if (isXHTML) { + doc2.body.appendChild(doc2.createElementNS("http://www.w3.org/1999/xhtml", "form")); + } else { + doc2.body.appendChild(doc2.createElement("form")); + } + is(doc2.forms.length, 1, "Form wasn't added .forms"); + } +} + +function testSVGDocument() { + var docType1 = + document.implementation.createDocumentType("svg", + "-//W3C//DTD SVG 1.1//EN", + null); + ok(docType1, "No doctype?"); + ok(docType1.ownerDocument, "docType should have ownerDocument!"); + var doc1 = document.implementation.createDocument(null, null, docType1); + is(docType1.ownerDocument, doc1, "docType should have ownerDocument!"); + ok(!doc1.documentElement, "Document shouldn't have document element!"); + ok(!(doc1 instanceof HTMLDocument), + "Document shouldn't be an HTML document!"); + ok(doc1 instanceof XMLDocument, + "Document should be an XML document!"); + + // SVG documents have .documentElement. + ok("documentElement" in doc1, "No .documentElement in document"); + + var docType2 = + document.implementation.createDocumentType("svg", + "-//W3C//DTD SVG 1.1//EN", + null); + var doc2 = document.implementation.createDocument("http://www.w3.org/2000/svg", + "svg", docType2); + ok(doc2.documentElement, "Document should have document element!"); + is(doc2.documentElement.localName, "svg", "Wrong .documentElement!"); +} + +function testFooBarDocument() { + var docType1 = + document.implementation.createDocumentType("FooBar", "FooBar", null); + ok(docType1, "No doctype?"); + ok(docType1.ownerDocument, "docType should have ownerDocument!"); + var doc1 = document.implementation.createDocument(null, null, docType1); + is(docType1.ownerDocument, doc1, "docType should have ownerDocument!"); + ok(!doc1.documentElement, "Document shouldn't have document element!"); + ok(!(doc1 instanceof HTMLDocument), + "Document shouldn't be an HTML document!"); + + var docType2 = + document.implementation.createDocumentType("FooBar", "FooBar", null); + var doc2 = document.implementation.createDocument("FooBarNS", + "FooBar", docType2); + ok(doc2.documentElement, "Document should have document element!"); + is(doc2.documentElement.namespaceURI, "FooBarNS", "Wrong namespaceURI!"); + is(doc2.documentElement.localName, "FooBar", "Wrong localName!"); +} + +function testNullDocTypeDocument() { + var doc1 = document.implementation.createDocument(null, null, null); + ok(!doc1.documentElement, "Document shouldn't have document element!"); + ok(!(doc1 instanceof HTMLDocument), + "Document shouldn't be an HTML document!"); + + var doc2 = document.implementation.createDocument("FooBarNS", + "FooBar", null); + ok(doc2.documentElement, "Document should have document element!"); + is(doc2.documentElement.namespaceURI, "FooBarNS", "Wrong namespaceURI!"); + is(doc2.documentElement.localName, "FooBar", "Wrong localName!"); +} + +var htmlPublicIDs = + [ "-//W3C//DTD HTML 4.01//EN", + "-//W3C//DTD HTML 4.01 Transitional//EN", + "-//W3C//DTD HTML 4.01 Frameset//EN", + "-//W3C//DTD HTML 4.0//EN", + "-//W3C//DTD HTML 4.0 Transitional//EN", + "-//W3C//DTD HTML 4.0 Frameset//EN" ]; + +var xhtmlPublicIDs = + [ "-//W3C//DTD XHTML 1.0 Strict//EN", + "-//W3C//DTD XHTML 1.0 Transitional//EN", + "-//W3C//DTD XHTML 1.0 Frameset//EN" ]; + +testHTMLDocuments(htmlPublicIDs, false); +testHTMLDocuments(xhtmlPublicIDs, true); +testSVGDocument(); +testFooBarDocument(); +testNullDocTypeDocument(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug451376.html b/dom/base/test/test_bug451376.html new file mode 100644 index 0000000000..85dc4e5c7e --- /dev/null +++ b/dom/base/test/test_bug451376.html @@ -0,0 +1,86 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=451376 +--> +<head> + <title>Test for Bug 451376</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body onload="doTest()"> + <a target="_blank" + title="IAccessibleText::attributes provides incorrect info after a mis-spelled word" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=451376">Mozilla Bug 451376</a> + <p id="display"></p> + <div id="content" style="display:none"> + </div> + <pre id="test"> + + <div id="area"><button>btn1</button>text <button>btn2</button></div> + + <script class="testbody" type="text/javascript"> + SimpleTest.waitForExplicitFinish(); + + function testRange(aRangeID, + aStartNode, aStartOffset, + aEndNode, aEndOffset, + aBeforeRangeNode, aBeforeRangeOffset, + aInRangeNode, aInRangeOffset, + aAfterRangeNode, aAfterRangeOffset) + { + var range = document.createRange(); + + range.setStart(aStartNode, aStartOffset); + range.setEnd(aEndNode, aEndOffset); + + if (aBeforeRangeNode) + is(range.comparePoint(aBeforeRangeNode, aBeforeRangeOffset), -1, + "Wrong result for the point before the range '" + aRangeID + "'"); + if (aInRangeNode) + is(range.comparePoint(aInRangeNode, aInRangeOffset), 0, + "Wrong result for the point inside the range '" + aRangeID + "'"); + if (aAfterRangeNode) + is(range.comparePoint(aAfterRangeNode, aAfterRangeOffset), 1, + "Wrong result for the point after the range '" + aRangeID + "'"); + // Comparare also start and end point + is(range.comparePoint(aStartNode, aStartOffset), 0, + "Wrong result for the start point '" + aRangeID + "'"); + is(range.comparePoint(aEndNode, aEndOffset), 0, + "Wrong result for the end point '" + aRangeID + "'"); + ok(range.isPointInRange(aStartNode, aStartOffset), + "Wrong result for the start point '" + aRangeID + "'"); + ok(range.isPointInRange(aEndNode, aEndOffset), + "Wrong result for the end point '" + aRangeID + "'"); + } + + function doTest() + { + var area = document.getElementById("area"); + var btn1 = area.firstChild; + var text = btn1.nextSibling; + var btn2 = area.lastChild; + + testRange("range1", area, 0, area, 1, + null, 0, + area, 0, + area, 2); + + testRange("range2", text, 2, text, 4, + text, 0, + text, 3, + text, 5); + + testRange("range3", text, 4, area, 2, + text, 0, + text, 4, + area, 3); + + SimpleTest.finish(); + } + </script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug453521.html b/dom/base/test/test_bug453521.html new file mode 100644 index 0000000000..dc06d9718b --- /dev/null +++ b/dom/base/test/test_bug453521.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=453521 +--> +<head> + <title>Test for Bug 453521</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=453521">Mozilla Bug 453521</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 453521 **/ + + +var r = document.createRange(); +r.setStart(document.documentElement, 0); +r.setEnd(document.documentElement, 0); +ok(r.extractContents() != null, + "range.extractContents() shouldn't return null."); +is(r.extractContents().nodeType, Node.DOCUMENT_FRAGMENT_NODE, + "range.extractContents() should return a document fragment."); + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug453736.html b/dom/base/test/test_bug453736.html new file mode 100644 index 0000000000..804e0afdbc --- /dev/null +++ b/dom/base/test/test_bug453736.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=453736 +--> +<head> + <title>Test for Bug 453736</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=453736">Mozilla Bug 453736</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 453736 **/ +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + const scriptCreationFuncs = [ + function() { return document.createElement("script"); }, + function() { return document.createElementNS("http://www.w3.org/2000/svg", "script"); } + ]; + + const scriptContainers = ["div", "iframe", "noframes", "noembed"]; + for (var i = 0; i < scriptContainers.length; ++i) { + for (var func of scriptCreationFuncs) { + var cont = scriptContainers[i]; + var node = document.createElement(cont); + document.body.appendChild(node); + var s = func(); + s.setAttribute("type", "application/javascript"); + s.appendChild(document.createTextNode('window["'+cont+'ScriptRan"] = true')); + + window[cont+"ScriptRan"] = false; + node.appendChild(s); + is(window[cont+"ScriptRan"], true, + "Script created with " + func +" should run when inserting in <"+cont+">"); + + window[cont+"ScriptRan"] = false; + document.body.appendChild(s); + is(window[cont+"ScriptRan"], false, + "Script created with " + func + " shouldn't run when moving out of <"+cont+">"); + + window[cont+"ScriptRan"] = false; + document.body.appendChild(s.cloneNode(true)); + is(window[cont+"ScriptRan"], false, + "Clone of script inside <" + cont + "> created with " + func + " shouldn't run"); + } + } + + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug454325.html b/dom/base/test/test_bug454325.html new file mode 100644 index 0000000000..724cd4b549 --- /dev/null +++ b/dom/base/test/test_bug454325.html @@ -0,0 +1,147 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=454325 +--> +<head> + <title>Test for Bug 454325</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=454325">Mozilla Bug 454325</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 454325 **/ + +function testDocument1() { + var doc = document.implementation.createDocument("", "", null); + var html = doc.createElement('html'); + doc.appendChild(html); + var body = doc.createElement('body'); + html.appendChild(body); + var h1 = doc.createElement('h1'); + var t1 = doc.createTextNode('Hello '); + h1.appendChild(t1); + var em = doc.createElement('em'); + var t2 = doc.createTextNode('Wonderful'); + em.appendChild(t2); + h1.appendChild(em); + var t3 = doc.createTextNode(' Kitty'); + h1.appendChild(t3); + body.appendChild(h1); + var p = doc.createElement('p'); + var t4 = doc.createTextNode(' How are you?'); + p.appendChild(t4); + body.appendChild(p); + var r = doc.createRange(); + r.selectNodeContents(doc); + is(r.toString(), "Hello Wonderful Kitty How are you?", + "toString() on range selecting Document gave wrong output"); + r.setStart(h1, 3); + r.setEnd(p, 0); + // <html><body><h1>Hello <em>Wonder ful<\em> Kitty<\h1><p>How are you?<\p><\body></html> + // ^ -----^ + is(r.toString(), "", "toString() on range crossing text nodes gave wrong output"); + var c1 = r.cloneContents(); + is(c1.childNodes.length, 2, "Wrong child nodes"); + try { + is(c1.childNodes[0].localName, "h1", "Wrong child node"); + is(c1.childNodes[1].localName, "p", "Wrong child node"); + } catch(ex) { + ok(!ex, ex); + } + + r.setStart(t2, 6); + r.setEnd(p, 0); + // <html><body><h1>Hello <em>Wonder ful<\em> Kitty<\h1><p>How are you?<\p><\body></html> + // ^----------------------^ + is(r.toString(), "ful Kitty", "toString() on range crossing text nodes gave wrong output"); + var c2 = r.cloneContents(); + is(c2.childNodes.length, 2, "Wrong child nodes"); + try { + is(c1.childNodes[0].localName, "h1", "Wrong child node"); + is(c1.childNodes[1].localName, "p", "Wrong child node"); + } catch(ex) { + ok(!ex, ex); + } + + var e1 = r.extractContents(); + is(e1.childNodes.length, 2, "Wrong child nodes"); + try { + is(e1.childNodes[0].localName, "h1", "Wrong child node"); + is(e1.childNodes[1].localName, "p", "Wrong child node"); + } catch(ex) { + ok(!ex, ex); + } +} + +function testDocument2() { + var doc = document.implementation.createDocument("", "", null); + var html = doc.createElement('html'); + doc.appendChild(html); + var head = doc.createElement('head'); + html.appendChild(head); + var foohead = doc.createElement('foohead'); + html.appendChild(foohead); + var body = doc.createElement('body'); + html.appendChild(body); + var d1 = doc.createElement('div'); + head.appendChild(d1); + var t1 = doc.createTextNode("|||"); + d1.appendChild(t1); + var d2 = doc.createElement("div"); + body.appendChild(d2); + var d3 = doc.createElement("div"); + d2.appendChild(d3); + var d4 = doc.createElement("div"); + d2.appendChild(d4); + var r = doc.createRange(); + r.setStart(t1, 1); + r.setEnd(d2, 2); + is(r.toString(), "||", "Wrong range"); + var c1 = r.cloneContents(); + var e1 = r.extractContents(); + ok(c1.isEqualNode(e1), "Wrong cloning or extracting!"); +} + +function testSurroundContents() { + var div = document.createElement('div'); + document.body.appendChild(div); + div.innerHTML = '<div>hello</div>world'; + var innerDiv = div.firstChild; + var hello = innerDiv.firstChild; + var range = document.createRange(); + range.setStart(hello, 0); + range.setEnd(hello, 5); + range.surroundContents(document.createElement('code')); + is(innerDiv.childNodes.length, 3, "Wrong childNodes count"); + is(innerDiv.childNodes[0].nodeName, "#text", "Wrong node name (1)"); + is(innerDiv.childNodes[0].textContent, "", "Wrong textContent (1)"); + is(innerDiv.childNodes[1].nodeName, "CODE", "Wrong node name (2)"); + is(innerDiv.childNodes[1].textContent, "hello", "Wrong textContent (2)"); + is(innerDiv.childNodes[2].nodeName, "#text", "Wrong node name (3)"); + is(innerDiv.childNodes[2].textContent, "", "Wrong textContent (3)"); +} + +function runTest() { + testDocument1(); + testDocument2(); + testSurroundContents(); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug454326.html b/dom/base/test/test_bug454326.html new file mode 100644 index 0000000000..5541a10d07 --- /dev/null +++ b/dom/base/test/test_bug454326.html @@ -0,0 +1,135 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=454326 +--> +<head> + <title>Test for Bug 454326</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=454326">Mozilla Bug 454326</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> + +<div id="partial-text-selection">Hello Hello <div></div>World!</div> +<div id="partial-element-selection"><div id="begin">Hello Hello </div><div></div><div id="end">World!</div></div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 454326 **/ + + function reinitPartialTextSelection() { + var pts = document.getElementById("partial-text-selection"); + pts.textContent = null; + pts.appendChild(document.createTextNode("Hello Hello ")); + pts.appendChild(document.createElement("div")); + pts.appendChild(document.createTextNode("World!")); + } + + + function doTest() { + var pts = document.getElementById("partial-text-selection"); + var ex = null; + try { + var r1 = document.createRange(); + r1.setStart(pts.firstChild, 6); + r1.setEnd(pts.lastChild, 6); + is(r1.toString(), "Hello World!", "Wrong range!"); + r1.surroundContents(document.createElement("div")); + is(r1.toString(), "Hello World!", "Wrong range!"); + } catch(e) { + ex = e; + } + is(ex, null, "Unexpected exception!"); + + reinitPartialTextSelection(); + ex = null; + try { + var r2 = document.createRange(); + r2.setStart(pts.firstChild, 6); + r2.setEnd(pts, 2); + is(r2.toString(), "Hello ", "Wrong range!"); + r2.surroundContents(document.createElement("div")); + is(r2.toString(), "Hello ", "Wrong range!"); + } catch(e) { + ex = e; + } + is(ex, null, "Unexpected exception!"); + + reinitPartialTextSelection(); + ex = null; + try { + var r3 = document.createRange(); + r3.setStart(pts, 1); + r3.setEnd(pts.lastChild, 6); + is(r3.toString(), "World!", "Wrong range!"); + r3.surroundContents(document.createElement("div")); + is(r3.toString(), "World!", "Wrong range!"); + } catch(e) { + ex = e; + } + is(ex, null, "Unexpected exception!"); + + reinitPartialTextSelection(); + ex = null; + try { + var r3 = document.createRange(); + r3.setStart(pts.firstChild, 6); + r3.setEnd(pts.firstChild.nextSibling, 0); + is(r3.toString(), "Hello ", "Wrong range!"); + r3.surroundContents(document.createElement("div")); + is(r3.toString(), "Hello ", "Wrong range!"); + } catch(e) { + ex = e; + is(e.name, "InvalidStateError", "Didn't get InvalidStateError exception!"); + is(Object.getPrototypeOf(e), DOMException.prototype, "Didn't get DOMException!"); + is(e.code, 11, "Didn't get INVALID_STATE_ERR exception!"); + } + ok(ex, "There should have been an exception!"); + + reinitPartialTextSelection(); + ex = null; + try { + var r3 = document.createRange(); + r3.setStart(pts.firstChild.nextSibling, 0); + r3.setEnd(pts.lastChild, 6); + is(r3.toString(), "World!", "Wrong range!"); + r3.surroundContents(document.createElement("div")); + is(r3.toString(), "World!", "Wrong range!"); + } catch(e) { + ex = e; + is(e.name, "InvalidStateError", "Didn't get InvalidStateError exception!"); + is(Object.getPrototypeOf(e), DOMException.prototype, "Didn't get DOMException!"); + is(e.code, 11, "Didn't get INVALID_STATE_ERR exception!"); + } + ok(ex, "There should have been an exception!"); + + ex = null; + try { + var pes = document.getElementById("partial-element-selection"); + var r4 = document.createRange(); + r4.setStart(pes.firstChild.firstChild, 6); + r4.setEnd(pes.lastChild.firstChild, 6); + is(r4.toString(), "Hello World!", "Wrong range!"); + r4.surroundContents(document.createElement("div")); + is(r4.toString(), "Hello World!", "Wrong range!"); + } catch(e) { + ex = e; + is(e.name, "InvalidStateError", "Didn't get InvalidStateError exception!"); + is(Object.getPrototypeOf(e), DOMException.prototype, "Didn't get DOMException!"); + is(e.code, 11, "Didn't get INVALID_STATE_ERR exception!"); + } + ok(ex, "There should have been an exception!"); + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(doTest); + addLoadEvent(SimpleTest.finish); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug455472.html b/dom/base/test/test_bug455472.html new file mode 100644 index 0000000000..33fc24d876 --- /dev/null +++ b/dom/base/test/test_bug455472.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=455472 +--> +<head> + <title>Test for Bug 455472</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=455472">Mozilla Bug 455472</a> +<p id="display"></p> +<script> + var ran = [ false, false, false, false, false ]; +</script> +<div id="content" style="display: none"> + <iframe src="data:text/html,<script>parent.ran[0]=true</script>"></iframe> + <object type="text/html" data="data:text/html,<script>parent.ran[1]=true</script>"></object> + <embed type="image/svg+xml" src="data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20onload='parent.ran[2]=true'/>"> + <object type="text/html" data="data:application/octet-stream,<script>parent.ran[3]=true</script>"></object> + <embed type="image/svg+xml" src="data:application/octet-stream,<svg%20xmlns='http://www.w3.org/2000/svg'%20onload='parent.ran[4]=true'/>"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 455472 **/ +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + var expected = [ true, true, true, false, false ]; + is (expected.length, ran.length, "Length mismatch"); + for (var i = 0; i < expected.length; ++i) { + is(ran[i], expected[i], + "Unexpected behavior in object " + i + " (0-based)"); + } + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug455629.html b/dom/base/test/test_bug455629.html new file mode 100644 index 0000000000..eab16d67ef --- /dev/null +++ b/dom/base/test/test_bug455629.html @@ -0,0 +1,63 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=455629 +--> +<head> + <title>Test for Bug 455629</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=455629">Mozilla Bug 455629</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 455629 **/ +SimpleTest.waitForExplicitFinish(); + +var done = 0; +function doTest(name) { + var elem = $(name); + var doc = elem.getSVGDocument(); + try { + doc.foopy = 42; + fail("Able to set cross origin property!"); + } catch (e) { + ok(true, "unable to set non-allAccess property cross origin"); + } + + if (elem instanceof HTMLObjectElement) { + doc = elem.contentDocument; + try { + doc.foopy = 42; + fail("Able to set cross origin property!"); + } catch (e) { + ok(true, "unable to set non-allAccess property cross origin"); + } + } + + if (++done == 2) { + SimpleTest.finish(); + } +} +</script> + +<object id="obj" + type="image/svg+xml" + onload="doTest('obj')" + data="http://example.org/tests/dom/base/test/bug455629-helper.svg"> +</object> + +<embed id="emb" + type="image/svg+xml" + onload="doTest('emb')" + src="http://example.org/tests/dom/base/test/bug455629-helper.svg"> +</embed> + +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug456262.html b/dom/base/test/test_bug456262.html new file mode 100644 index 0000000000..ca050a9c83 --- /dev/null +++ b/dom/base/test/test_bug456262.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=456262 +--> +<head> + <title>Test for Bug 456262</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=456262">Mozilla Bug 456262</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 456262 **/ + +function runTest() { + document.expando = document; + document.documentElement.expando = document; + document.documentElement.setAttribute("foo", "bar"); + document.documentElement.getAttributeNode("foo").expando = document; + SpecialPowers.gc(); + ok(document.expando, "Should have preserved the expando!"); + ok(document.documentElement.expando, "Should have preserved the expando!"); + ok(document.documentElement.getAttributeNode('foo').expando, + "Should have preserved the expando!"); +} + +runTest(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug457746.html b/dom/base/test/test_bug457746.html new file mode 100644 index 0000000000..6cab45f4b6 --- /dev/null +++ b/dom/base/test/test_bug457746.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=457746 +--> +<head> + <title>Test for Bug 457746</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=457746">Mozilla Bug 457746</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 457746 **/ +SimpleTest.waitForExplicitFinish(); + +var xhr = new XMLHttpRequest(); +xhr.open("GET", "bug457746.sjs"); +xhr.send(""); +xhr.abort(); +xhr.open("GET", "bug457746.sjs"); +xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + is(xhr.responseText, "\u00c1", "Broken encoding conversion?"); + SimpleTest.finish(); + } +} +xhr.send(""); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug459424.html b/dom/base/test/test_bug459424.html new file mode 100644 index 0000000000..283d75b4b6 --- /dev/null +++ b/dom/base/test/test_bug459424.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=459424 +--> +<head> + <title>Test for Bug 459424</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=459424">Mozilla Bug 459424</a> +<p id="display" style="mask: url(no-such-document-I-tell-you#x)"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 459424 **/ +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + SpecialPowers.setFullZoom(window, 2); + is(true, true, "Gotta test something"); + SpecialPowers.setFullZoom(window, 1); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug461555.html b/dom/base/test/test_bug461555.html new file mode 100644 index 0000000000..b91ca98326 --- /dev/null +++ b/dom/base/test/test_bug461555.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=461555 +--> +<head> + <title>Test for Bug 461555</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=461555">Mozilla Bug 461555</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<script> + +SimpleTest.waitForExplicitFinish(); + +function writeIt(n) { + document.write("<span>" + n + "</span>"); +} + +function done() { + nodes = document.getElementsByTagName('span'); + is(nodes.length, 3, "wrong length"); + for (i = 0; i < nodes.length; ++i) { + is(nodes[i].textContent, String(i + 1), "wrong order"); + } + SimpleTest.finish(); +} + +document.addEventListener("DOMContentLoaded", function() { + done(); +}, false); + +writeIt(1); + +</script> +<script defer> +writeIt(2); +</script> +<script> +writeIt(3); +</script> diff --git a/dom/base/test/test_bug461735.html b/dom/base/test/test_bug461735.html new file mode 100644 index 0000000000..630c572f8a --- /dev/null +++ b/dom/base/test/test_bug461735.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=461735 +--> +<head> + <title>Test for Bug 461735</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=461735">Mozilla Bug 461735</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +var errorFired = false; +window.onerror = function(message, uri, line) { + is(message, "Script error.", "Should have empty error message"); + is(uri, + "http://mochi.test:8888/tests/dom/base/test/bug461735-redirect1.sjs", + "Should have pre-redirect error location URI"); + is(line, 0, "Shouldn't have a line here"); + errorFired = true; +} +</script> +<script src="bug461735-redirect1.sjs"></script> +<script> + is(errorFired, true, "Should have error in redirected different origin script"); + errorFired = false; +</script> +<script type="application/javascript"> +window.onerror = function(message, uri, line) { + is(message, "ReferenceError: c is not defined", "Should have correct error message"); + is(uri, + "http://mochi.test:8888/tests/dom/base/test/bug461735-redirect2.sjs", + "Unexpected error location URI"); + is(line, 3, "Should have a line here"); + errorFired = true; +} +</script> +<script src="bug461735-redirect2.sjs"></script> +<script> + is(errorFired, true, "Should have error in same origin script"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug465767.html b/dom/base/test/test_bug465767.html new file mode 100644 index 0000000000..3869653bbc --- /dev/null +++ b/dom/base/test/test_bug465767.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=465767 +--> +<head> + <title>Test for Bug 465767</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=465767">Mozilla Bug 465767</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 465767 **/ + +function runTest() { + var node = document.createElement("div"); + var e = null; + try { + document.implementation.createDocument("", "", null).adoptNode(node); + SpecialPowers.gc(); + document.implementation.createDocument("", "", null).adoptNode(node); + } catch(ex) { + e = ex; + } + is(e, null, ".adoptNode didn't succeed!"); + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug466080.html b/dom/base/test/test_bug466080.html new file mode 100644 index 0000000000..b889e899ff --- /dev/null +++ b/dom/base/test/test_bug466080.html @@ -0,0 +1,125 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test bug 466080</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="onWindowLoad()"> +<iframe id="frame1" + src="https://requireclientcert.example.com/tests/dom/base/test/bug466080.sjs" + onload="document.iframeWasLoaded = true"> + + This iframe should load the resource via the src-attribute from + a secure server which requires a client-cert. Doing this is + supposed to work, but further below in the test we try to load + the resource from the same url using a XHR, which should not work. + + TODO : What if we change 'src' from JS? Would/should it load? + +</iframe> + +<script class="testbody" type="text/javascript"> + +document.iframeWasLoaded = false; + +var alltests = [ + +// load resource from a relative url - this should work + { url:"bug466080.sjs", + status_check:"==200", + error:"XHR from relative URL"}, + +// TODO - load the resource from a relative url via https..? + +// load a non-existing resource - should get "404 Not Found" + { url:"bug466080-does-not.exist", + status_check:"==404", + error:"XHR loading non-existing resource"}, + +// load resource from cross-site non-secure server + { url:"http://test1.example.com/tests/dom/base/test/bug466080.sjs", + status_check:"==200", + error:"XHR from cross-site plaintext server"}, + +// load resource from cross-site secure server - should work since no credentials are needed + { url:"https://test1.example.com/tests/dom/base/test/bug466080.sjs", + status_check:"==200", + error:"XHR from cross-site secure server"}, + +// load resource from cross-site secure server - should work since the server just requests certs + { url:"https://requestclientcert.example.com/tests/dom/base/test/bug466080.sjs", + status_check:"==200", + error:"XHR from cross-site secure server requesting certificate"}, + +// load resource from cross-site secure server - should NOT work since the server requires cert +// note that this is the url which is used in the iframe.src above + { url:"https://requireclientcert.example.com/tests/dom/base/test/bug466080.sjs", + status_check:"!=200", + error:"XHR from cross-site secure server requiring certificate"}, + +// repeat previous, - should NOT work + { url:"https://requireclientcert.example.com/tests/dom/base/test/bug466080.sjs", + status_check:"==200", + error:"XHR w/ credentials from cross-site secure server requiring certificate", + withCredentials:"true"}, + +// repeat previous, but with credentials - should work + { url:"https://requireclientcert.example.com/tests/dom/base/test/bug466080.sjs", + status_check:"==200", + error:"XHR w/ credentials from cross-site secure server requiring certificate", + withCredentials:"true"}, + +// repeat previous, withCredentials but using a weird method to force preflight +// should NOT work since our preflight is anonymous and will fail with our simple server + { url:"https://requireclientcert.example.com/tests/dom/base/test/bug466080.sjs", + status_check:"!=200", + error:"XHR PREFLIGHT from cross-site secure server requiring certificate", + withCredentials:"true", + method:"XMETHOD"}, + +]; + +function onWindowLoad() { + // First, check that resource was loaded into the iframe + // This check in fact depends on bug #444165... :) + ok(document.iframeWasLoaded, "Loading resource via src-attribute"); + + + function runTest(test) { + + var xhr = new XMLHttpRequest(); + + var method = "GET"; + if (test.method != null) { method = test.method; } + xhr.open(method, test.url); + + xhr.withCredentials = test.withCredentials; + + SpecialPowers.wrap(xhr).setRequestHeader("Connection", "Keep-Alive", false); + + try { + xhr.send(); + } catch(e) { + } + + xhr.onloadend = function() { + var success = eval(xhr.status + test.status_check); + ok(success, test.error); + + if (alltests.length == 0) { + SimpleTest.finish(); + } else { + runTest(alltests.shift()); + } + }; + } + + runTest(alltests.shift()); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug466409.html b/dom/base/test/test_bug466409.html new file mode 100644 index 0000000000..0e44392389 --- /dev/null +++ b/dom/base/test/test_bug466409.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=466409 +--> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=466409">Mozilla Bug 466409</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="testframe"></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 466409 **/ + + +SimpleTest.waitForExplicitFinish(); +var testframe = document.getElementById('testframe'); + + + +SpecialPowers.pushPrefEnv({"set": [['intl.charset.detector', 'universal_charset_detector']]}, function() { + testframe.onload = function () { + ok(true, "page loaded successfully"); + SimpleTest.finish(); + }; + testframe.src = "bug466409-page.html"; +}); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug466751.xhtml b/dom/base/test/test_bug466751.xhtml new file mode 100644 index 0000000000..ad80ea7d5c --- /dev/null +++ b/dom/base/test/test_bug466751.xhtml @@ -0,0 +1,40 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=466751 +--> +<head> + <title>Test for Bug 466751</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=466751">Mozilla Bug 466751</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="test" /> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"><![CDATA[ + +/** Test for Bug 466751 **/ + +var el = $("test"); +var name, message; + +try { + el.innerHTML = '<div ">bla</div>'; +} catch (ex) { + name = ex.name; + message = ex.message; +} + +const NS_ERROR_DOM_SYNTAX_ERR = 0x8053000C; +ok(/An invalid or illegal string was specified/.test(message), "threw SyntaxError message"); +is(name, "SyntaxError", "threw SyntaxError"); + +]]> +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug469020.html b/dom/base/test/test_bug469020.html new file mode 100644 index 0000000000..a20cfa63d8 --- /dev/null +++ b/dom/base/test/test_bug469020.html @@ -0,0 +1,128 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=469020 +--> +<head> + <title>Test for Bug 469020</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469020">Mozilla Bug 469020</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 469020 **/ + + var range = null; + var anchor = null; + + function doRangeAnchor(elem, start, end) { + range = document.createRange(); + range.setStart(elem.firstChild, start); + end = end < elem.lastChild.length ? end : elem.lastChild.length + range.setEnd(elem.lastChild, end); + anchor = document.createElement('a'); + anchor.href = "javascript: void(0);"; + range.surroundContents(anchor); + } + + function undoRangeAnchor() { + var pnode = anchor.parentNode; + var range2 = document.createRange(); + range2.selectNodeContents(anchor); + var contents = range2.extractContents(); + pnode.replaceChild(contents,anchor); + } + +function serializeNode(node) { + var s; + var isElem = false; + if (node.nodeName == "#text") { + if (node.nodeValue) { + s = node.nodeValue + } else { + s = "<#empty>" + } + } else { + isElem = true; + s = "<" + node.nodeName + ">"; + } + for (var j = 0; j < node.childNodes.length; ++j) { + s += serializeNode(node.childNodes[j]); + } + if (isElem) { + s += "</" + node.nodeName + ">"; + } + return s; +} + +function runTest(elementID, start, end, expected1, expected2, expected3) { + var e = document.getElementById(elementID); + doRangeAnchor(e, start, end); + is(serializeNode(e), expected1, "Wrong range behavior!"); + document.getElementById('log').textContent += serializeNode(e) + "\n"; + undoRangeAnchor(); + is(serializeNode(e), expected2, "Wrong range behavior!"); + document.getElementById('log').textContent += serializeNode(e) + "\n"; + doRangeAnchor(e, start, end); + is(serializeNode(e), expected3, "Wrong range behavior!"); + document.getElementById('log').textContent += serializeNode(e) + "\n"; +} + +function runTests() { + runTest("test1", 0, 3, + "<P><#empty><A>http://www.<SPAN>mozilla.</SPAN>org</A><#empty></P>", + "<P><#empty>http://www.<SPAN>mozilla.</SPAN>org<#empty></P>", + "<P><#empty><A><#empty>http://www.<SPAN>mozilla.</SPAN>org<#empty></A><#empty></P>"); + + runTest("test2", 1, 3, + "<P>h<A>ttp://www.<SPAN>mozilla.</SPAN>org</A><#empty></P>", + "<P>http://www.<SPAN>mozilla.</SPAN>org<#empty></P>", + "<P>h<A><#empty>ttp://www.<SPAN>mozilla.</SPAN>org<#empty></A><#empty></P>"); + + runTest("test3", 0, 2, + "<P><#empty><A>http://www.<SPAN>mozilla.</SPAN>or</A>g</P>", + "<P><#empty>http://www.<SPAN>mozilla.</SPAN>org</P>", + "<P><#empty><A><#empty>http://www.<SPAN>mozilla.</SPAN>org</A><#empty></P>"); + + runTest("test4", 1, 2, + "<P>h<A>ttp://www.<SPAN>mozilla.</SPAN>or</A>g</P>", + "<P>http://www.<SPAN>mozilla.</SPAN>org</P>", + "<P>h<A><#empty>ttp://www.<SPAN>mozilla.</SPAN>org</A><#empty></P>"); + + runTest("test5", 11, 0, + "<P>http://www.<A><#empty><SPAN>mozilla.</SPAN><#empty></A>org</P>", + "<P>http://www.<#empty><SPAN>mozilla.</SPAN><#empty>org</P>", + "<P>http://www.<A><#empty><#empty><SPAN>mozilla.</SPAN><#empty><#empty></A>org</P>"); + + runTest("test6", 10, 1, + "<P>http://www<A>.<SPAN>mozilla.</SPAN>o</A>rg</P>", + "<P>http://www.<SPAN>mozilla.</SPAN>org</P>", + "<P>http://www<A><#empty>.<SPAN>mozilla.</SPAN>or</A>g</P>"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTests); + + + +</script> +</pre> +<p id="test1">http://www.<span>mozilla.</span>org</p> +<p id="test2">http://www.<span>mozilla.</span>org</p> +<p id="test3">http://www.<span>mozilla.</span>org</p> +<p id="test4">http://www.<span>mozilla.</span>org</p> +<p id="test5">http://www.<span>mozilla.</span>org</p> +<p id="test6">http://www.<span>mozilla.</span>org</p> +<pre id="log"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug469304.html b/dom/base/test/test_bug469304.html new file mode 100644 index 0000000000..3dae9287f3 --- /dev/null +++ b/dom/base/test/test_bug469304.html @@ -0,0 +1,187 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=469304 +--> +<head> + <title>Test for Bug 469304</title> + <script type="application/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469304">Mozilla Bug 469304</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 469304 **/ +function testGetAttribute() { + var a1 = document.createAttributeNS("", "aa"); + a1.nodeValue = "lowercase"; + var a2 = document.createAttributeNS("", "AA"); + a2.nodeValue = "UPPERCASE"; + document.body.setAttributeNode(a1); + document.body.setAttributeNode(a2); + var log = document.getElementById("log"); + is(document.body.getAttribute('aa'), "lowercase", "First attribute should have localname aa (1)."); + is(document.body.getAttribute('AA'), "lowercase", "First attribute should have localname aa (2)."); + is(document.body.getAttributeNS("", "aa"), "lowercase", "First attribute should have localName aa (3)."); + is(document.body.getAttributeNS("", "AA"), "UPPERCASE", "Second attribute should have value UPPERCASE!"); + + var s = ""; + for (var i = 0; i < document.body.attributes.length; ++i) { + s += document.body.attributes[i].nodeName + "=" + + document.body.attributes[i].nodeValue; + } + is(s, "aa=lowercaseAA=UPPERCASE", "Wrong attribute!"); + + is(document.body.getAttributeNode("aa"), document.body.getAttributeNode("AA"), + "Wrong node!"); + + document.body.getAttributeNodeNS("", "AA").nodeValue = "FOO"; + is(document.body.getAttributeNS("", "AA"), "FOO", "Wrong value!"); + + document.body.removeAttributeNode(document.body.getAttributeNodeNS("", "aa")); + ok(!document.body.getAttributeNode("AA"), "Should not have attribute node! (1)"); + ok(!document.body.getAttributeNode("aa"), "Should not have attribute node! (2)"); + + is(a2.nodeValue, "FOO", "Wrong value!"); + a2.nodeValue = "UPPERCASE"; + is(a2.nodeValue, "UPPERCASE", "Wrong value!"); + + document.body.setAttributeNode(a2); + is(document.body.getAttributeNS("", "AA"), "UPPERCASE", "Wrong value!"); + ok(document.body.getAttributeNodeNS("", "AA"), "Should have attribute node!"); + is(document.body.getAttributeNS("", "aa"), null, "No attribute has the localName aa."); + ok(!document.body.getAttributeNodeNS("", "aa"), "Should not have attribute node!"); +} +testGetAttribute(); + +// A bit modified testcases from WebKit. +function testGetAttributeCaseInsensitive() { + var div = document.createElement('div'); + div.setAttribute("mixedCaseAttrib", "x"); + // Do original case lookup, and lowercase lookup. + return div.getAttribute("mixedcaseattrib"); +} +is(testGetAttributeCaseInsensitive(), "x", "(1)"); + +function testGetAttributeNodeMixedCase() { + var div = document.createElement('div'); + var a = div.ownerDocument.createAttributeNS("", "mixedCaseAttrib"); + a.nodeValue = "x"; + div.setAttributeNode(a); + return div.getAttributeNS("", "mixedCaseAttrib"); +} +is(testGetAttributeNodeMixedCase(), "x", "(2)"); + +function testGetAttributeNodeLowerCase(div) { + var div = document.createElement('div'); + var a = div.ownerDocument.createAttribute("lowercaseattrib"); + a.nodeValue = "x"; + div.setAttributeNode(a); + return div.getAttribute("lowerCaseAttrib"); +} +is(testGetAttributeNodeLowerCase(), "x", "(3)"); + +function testSetAttributeNodeKeepsRef(div) { + var div = document.createElement('div'); + var a = div.ownerDocument.createAttribute("attrib_name"); + a.nodeValue = "0"; + div.setAttributeNode(a); + // Mutate the attribute node. + a.nodeValue = "1"; + return div.getAttribute("attrib_name"); +} +is(testSetAttributeNodeKeepsRef(), "1", "(4)"); + +function testAttribNodeNameFoldsCase() { + var div = document.createElement('div'); + var a = div.ownerDocument.createAttribute("A"); + a.nodeValue = "x"; + div.setAttributeNode(a); + var result = [ a.name, a.nodeName ]; + return result.join(","); +} +is(testAttribNodeNameFoldsCase(), "a,a", "(5)"); + +function testAttribNodeNameFoldsCaseGetNode() { + var body = document.body; + var a = body.ownerDocument.createAttribute("A"); + a.nodeValue = "x"; + body.setAttributeNode(a); + a = document.body.getAttributeNodeNS("", "a"); + if (!a) + return "FAIL"; + var result = [ a.name, a.nodeName ]; + return result.join(","); +} +is(testAttribNodeNameFoldsCaseGetNode(), "a,a", "(6)"); + +function testAttribNodeNameFoldsCaseGetNode2() { + var body = document.body; + var a = body.ownerDocument.createAttribute("B"); + a.nodeValue = "x"; + body.setAttributeNode(a); + a = document.body.getAttributeNodeNS("", "b"); + if (!a) + return "FAIL"; + // Now create node second time + a = body.ownerDocument.createAttribute("B"); + a.nodeValue = "x"; + body.setAttributeNode(a); + a = document.body.getAttributeNodeNS("", "b"); + var result = [ a.name, a.nodeName ]; + return result.join(","); +} +is(testAttribNodeNameFoldsCaseGetNode2(), "b,b", "(7)"); + +function testAttribNodeNameGetMutate() { + var body = document.body; + var a = body.ownerDocument.createAttribute("c"); + a.nodeValue = "0"; + body.setAttributeNode(a); + a = document.body.getAttributeNode("c"); + a.value = "1"; + a = document.body.getAttributeNode("c"); + return a.nodeValue; +} +is(testAttribNodeNameGetMutate(), "1", "(8)"); + +var node = document.createElement("div"); +var attrib = document.createAttribute("myAttrib"); +attrib.nodeValue = "XXX"; +node.setAttributeNode(attrib); +// Note, this is different to what WebKit does +is((new XMLSerializer).serializeToString(node), + "<div xmlns=\"http://www.w3.org/1999/xhtml\" myattrib=\"XXX\"></div>", "(9)"); +is(node.getAttributeNode('myAttrib').name, "myattrib", "(10)"); +is(node.getAttributeNode('myattrib').name, "myattrib", "(11)"); +is(attrib.name, "myattrib", "(12)"); + +var o = document.createElement("div"); +o.setAttribute("myAttrib","htmlattr"); +o.setAttributeNS("","myAttrib","123"); +is(o.getAttributeNodeNS("","myAttrib").nodeName, "myAttrib", "nodeName should be case-sensitive."); +is(o.getAttributeNode("myAttrib").nodeName, "myattrib", "nodeName shouldn't be case-sensitive."); +is(o.getAttributeNodeNS("","myAttrib").value, "123", "Should have got the case-sensitive attribute."); +is(o.attributes.length, 2, "Should have two attributes."); +o.setAttribute("myAttrib2", "htmlattr"); +o.setAttributeNS("", "myAttrib2", "123"); +is(o.attributes.length, 4, "Should have four attributes."); +var an = o.attributes.removeNamedItem("myAttrib2"); +is(o.attributes.length, 3, "An attribute should have been removed."); +is(an.value, "htmlattr", "The removed attribute should have been the case-insensitive attribute."); +is(o.getAttribute("myAttrib2"), null, "Element shouldn't have case-insensitive attribute anymore."); +var an2 = o.attributes.removeNamedItemNS("", "myAttrib2"); +is(an2.localName, "myAttrib2", "The removed attribute should be case-sensitive."); +is(o.attributes.length, 2, "Element should have two attributes."); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug473162-1.html b/dom/base/test/test_bug473162-1.html new file mode 100644 index 0000000000..336c979e9a --- /dev/null +++ b/dom/base/test/test_bug473162-1.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=473162 +--> +<head> + <title>Test for Bug 473162</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=473162">Mozilla Bug 473162</a> +<p id="display"></p> +<div id="content" style="display: none"> +<span id="TEST" class="TEST"></span> +<span id="test" class="test"></span> +<span id="Test" class="Test"></span> +<span id="tesT" class="tesT"></span> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 473162 **/ +var nodes = document.getElementsByClassName("test"); +is(nodes.length, 1, "Unexpected length"); +is(nodes[0], $("test"), "Unexpected first node"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug473162-2.html b/dom/base/test/test_bug473162-2.html new file mode 100644 index 0000000000..a627496716 --- /dev/null +++ b/dom/base/test/test_bug473162-2.html @@ -0,0 +1,33 @@ +<!-- NOTE: THIS TEST MUST BE IN QUIRKS MODE --> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=473162 +--> +<head> + <title>Test for Bug 473162</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=473162">Mozilla Bug 473162</a> +<p id="display"></p> +<div id="content" style="display: none"> +<span id="TEST" class="TEST"></span> +<span id="test" class="test"></span> +<span id="Test" class="Test"></span> +<span id="tesT" class="tesT"></span> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 473162 **/ +var nodes = document.getElementsByClassName("test"); +is(nodes.length, 4, "Unexpected length"); +is(nodes[0], $("TEST"), "Unexpected first node"); +is(nodes[1], $("test"), "Unexpected second node"); +is(nodes[2], $("Test"), "Unexpected third node"); +is(nodes[3], $("tesT"), "Unexpected fourth node"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug475156.html b/dom/base/test/test_bug475156.html new file mode 100644 index 0000000000..a262d47d82 --- /dev/null +++ b/dom/base/test/test_bug475156.html @@ -0,0 +1,299 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=475156 +--> +<head> + <title>Test for Bug 475156</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="drive(tests.shift());"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var path = "http://mochi.test:8888/tests/dom/base/test/"; + +function fromCache(xhr) +{ + var ch = SpecialPowers.wrap(xhr).channel.QueryInterface(SpecialPowers.Ci.nsICacheInfoChannel); + return ch.isFromCache(); +} + +var tests = [ + // First just init the file with an ETag + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs?etag=a1"); + }, + + loading: function(xhr) + { + }, + + done: function(xhr) + { + }, + }, + + // Try to load the file the first time regularly, we have to get 200 OK + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), false, "Not coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We get a fresh version of the file"); + is(xhr.getResponseHeader("Etag"), "a1", "We got correct ETag"); + is(xhr.responseText, "a1", "We got the expected file body"); + }, + }, + + // Try to load the file the second time regularly, we have to get 304 Not Modified + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a1"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), true, "Coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We got cached version"); + is(xhr.getResponseHeader("Etag"), "a1", "We got correct ETag"); + is(xhr.responseText, "a1", "We got the expected file body"); + }, + }, + + // Try to load the file the third time regularly, we have to get 304 Not Modified + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a1"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), true, "Coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We got cached version"); + is(xhr.getResponseHeader("Etag"), "a1", "We got correct ETag"); + is(xhr.responseText, "a1", "We got the expected file body"); + }, + }, + + // Now modify the ETag + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs?etag=a2"); + }, + + loading: function(xhr) + { + }, + + done: function(xhr) + { + }, + }, + + // Try to load the file, we have to get 200 OK with the new content + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a2"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), false, "Not coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We get a fresh version of the file"); + is(xhr.getResponseHeader("Etag"), "a2", "We got correct ETag"); + is(xhr.responseText, "a2", "We got the expected file body"); + }, + }, + + // Try to load the file the second time regularly, we have to get 304 Not Modified + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a2"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), true, "Coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We got cached version"); + is(xhr.getResponseHeader("Etag"), "a2", "We got correct ETag"); + is(xhr.responseText, "a2", "We got the expected file body"); + }, + }, + + // Try to load the file the third time regularly, we have to get 304 Not Modified + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a2"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), true, "Coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We got cached version"); + is(xhr.getResponseHeader("Etag"), "a2", "We got correct ETag"); + is(xhr.responseText, "a2", "We got the expected file body"); + }, + }, + + // Now modify the ETag ones more + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs?etag=a3"); + }, + + loading: function(xhr) + { + }, + + done: function(xhr) + { + }, + }, + + // Try to load the file, we have to get 200 OK with the new content + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a3"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), false, "Not coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We get a fresh version of the file"); + is(xhr.getResponseHeader("Etag"), "a3", "We got correct ETag"); + is(xhr.responseText, "a3", "We got the expected file body"); + }, + }, + + // Try to load the file the second time regularly, we have to get 304 Not Modified + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a3"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), true, "Coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We got cached version"); + is(xhr.getResponseHeader("Etag"), "a3", "We got correct ETag"); + is(xhr.responseText, "a3", "We got the expected file body"); + }, + }, + + // Try to load the file the third time regularly, we have to get 304 Not Modified + { + init: function(xhr) + { + xhr.open("GET", path + "bug475156.sjs"); + xhr.setRequestHeader("If-Match", "a3"); + }, + + loading: function(xhr) + { + is(fromCache(xhr), true, "Coming from the cache"); + }, + + done: function(xhr) + { + is(xhr.status, 200, "We got cached version"); + is(xhr.getResponseHeader("Etag"), "a3", "We got correct ETag"); + is(xhr.responseText, "a3", "We got the expected file body"); + }, + }, + + // Load one last time to reset the state variable in the .sjs file + {
+ init: function (xhr) {
+ xhr.open("GET", path + "bug475156.sjs");
+ xhr.setRequestHeader("If-Match", "a1");
+ }, + + loading: function (xhr) {
+ }, + + done: function (xhr) {
+ },
+ }, +] + + +function drive(test) +{ + var xhr = new XMLHttpRequest(); + test.init(xhr); + xhr.onreadystatechange = function() { + if (this.readyState == 3) { + test.loading(this); + } + if (this.readyState == 4) { + test.done(this); + if (tests.length == 0) + SimpleTest.finish(); + else + drive(tests.shift()); + } + } + xhr.send(); +} + +</script> +</body> +</html> + diff --git a/dom/base/test/test_bug482935.html b/dom/base/test/test_bug482935.html new file mode 100644 index 0000000000..17f5bfdb3d --- /dev/null +++ b/dom/base/test/test_bug482935.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test bug 482935</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href=" /tests/SimpleTest/test.css" /> +</head> +<body onload="onWindowLoad()"> +<script class="testbody" type="text/javascript"> + +var url = "bug482935.sjs"; + +function clearCache() { + SpecialPowers.Cc["@mozilla.org/netwerk/cache-storage-service;1"]. + getService(SpecialPowers.Ci.nsICacheStorageService). + clear(); +} + +// Tests that the response is cached if the request is cancelled +// after it has reached state 4 +function testCancelInPhase4() { + + clearCache(); + + // First request - should be loaded from server + var xhr = new XMLHttpRequest(); + xhr.addEventListener("readystatechange", function(e) { + if (xhr.readyState < xhr.DONE) return; + is(xhr.readyState, xhr.DONE, "wrong readyState"); + xhr.abort(); + SimpleTest.executeSoon(function() { + // This request was cancelled, so the responseText should be empty string + is(xhr.responseText, "", "Expected empty response to cancelled request"); + + // Second request - should be found in cache + var xhr2 = new XMLHttpRequest(); + + xhr2.addEventListener("load", function() { + is(xhr2.responseText, "0", "Received fresh value for second request"); + SimpleTest.finish(); + }, false); + + xhr2.open("GET", url); + xhr2.setRequestHeader("X-Request", "1", false); + + try { xhr2.send(); } + catch(e) { + is(xhr2.status, "200", "Exception!"); + } + }); + }, false); + + xhr.open("GET", url, true); + xhr.setRequestHeader("X-Request", "0", false); + try { xhr.send(); } + catch(e) { + is("Nothing", "Exception", "Boom: " + e); + } +} + +function onWindowLoad() { + testCancelInPhase4(); +} + +SimpleTest.waitForExplicitFinish(); +</script> +</body> +</html> diff --git a/dom/base/test/test_bug484396.html b/dom/base/test/test_bug484396.html new file mode 100644 index 0000000000..3565f442d2 --- /dev/null +++ b/dom/base/test/test_bug484396.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=484396 +--> +<head> + <title>Test for Bug 484396</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=484396">Mozilla Bug 484396</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +var msg = 'xhr.open() succeeds with empty url'; +var xhr = new XMLHttpRequest(); + +try { + xhr.open('GET', ''); + ok(true, msg); +} catch (e) { + ok(false, msg); +} + +xhr.onerror = function () { + ok(false, 'xhr.send() succeeds with empty url'); +} + +xhr.onreadystatechange = function () { + if (4 == xhr.readyState) { + is(xhr.status, 200, 'xhr.status is 200 OK'); + ok(-1 < xhr.responseText.indexOf('Bug 484396'), 'xhr.responseText contains the calling page'); + + SimpleTest.finish(); + } +}; + +xhr.send(''); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug493881.html b/dom/base/test/test_bug493881.html new file mode 100644 index 0000000000..ebd020baa0 --- /dev/null +++ b/dom/base/test/test_bug493881.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=493881 +--> + +<head> + <title>Test for Bug 493881</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="test_bug493881.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style type="text/css"> + + </style> +</head> + +<body id="body"> + +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=493881" + target="_blank" >Mozilla Bug 493881</a> + +<p id="display"></p> + +<a id="nonvisitedlink" href="http://www.example.com/">Non-visited link</a> +<a id="visitedlink" href="">Visited link</a> +<p id="plaintext">some text</p> + +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug493881.js b/dom/base/test/test_bug493881.js new file mode 100644 index 0000000000..b982e3dc7d --- /dev/null +++ b/dom/base/test/test_bug493881.js @@ -0,0 +1,72 @@ +/** + * Test for Bug 493881: Changes to legacy HTML color properties before the BODY is loaded + * should be ignored. Additionally, after BODY loads, setting any of these properties to undefined + * should cause them to be returned as the string "undefined". + */ + +SimpleTest.waitForExplicitFinish(); + +var legacyProps = ["fgColor", "bgColor", "linkColor", "vlinkColor", "alinkColor"]; +var testColors = ["blue", "silver", "green", "orange", "red"]; +var rgbTestColors = ["rgb(255, 0, 0)", "rgb(192, 192, 192)", "rgb(0, 128, 0)", "rgb(255, 165, 0)", "rgb(255, 0, 0)"]; +var idPropList = [ {id: "plaintext", prop: "color"}, + {id: "body", prop: "background-color"}, + {id: "nonvisitedlink", prop: "color"}, + {id: "visitedlink", prop: "color"} ]; +var initialValues = []; + +function setAndTestProperty(prop, color) { + var initial = document[prop]; + document[prop] = color; + is(document[prop], initial, "document[" + prop + "] not ignored before body"); + return initial; +} + +/** + * Attempt to set legacy color properties before BODY exists, and verify that such + * attempts are ignored. + */ +for (var i = 0; i < legacyProps.length; i++) { + initialValues[i] = setAndTestProperty(legacyProps[i], testColors[i]); +} + +/** + * After BODY loads, run some more tests. + */ +addLoadEvent( function() { + // Verify that the legacy color properties still have their original values. + for (var i = 0; i < legacyProps.length; i++) { + is(document[legacyProps[i]], initialValues[i], "document[" + legacyProps[i] + "] altered after body load"); + } + + // Verify that legacy color properties applied before BODY are really ignored when rendering. + // Save current computed style colors for later use. + for (i = 0; i < idPropList.length; i++) { + var style = window.getComputedStyle(document.getElementById(idPropList[i].id), null); + var color = style.getPropertyValue(idPropList[i].prop); + idPropList[i].initialComputedColor = color; + isnot(color, rgbTestColors[i], "element rendered using before-body style"); + } + // XXX: Can't get links to visually activate via script events, so can't verify + // that the alinkColor property was not applied. + + // Verify that setting legacy color props to undefined after BODY loads will cause them + // to be read as the string "undefined". + for (var i = 0; i < legacyProps.length; i++) { + document[legacyProps[i]] = undefined; + is(document[legacyProps[i]], "undefined", + "Unexpected value of " + legacyProps[i] + " after setting to undefined"); + } + + // Verify that setting legacy color props to undefined led to result + // of parsing undefined as a color. + for (i = 0; i < idPropList.length; i++) { + var style = window.getComputedStyle(document.getElementById(idPropList[i].id), null); + var color = style.getPropertyValue(idPropList[i].prop); + is(color, "rgb(0, 239, 14)", + "element's style should get result of parsing undefined as a color"); + } + + // Mark the test as finished. + setTimeout(SimpleTest.finish, 0); +}); diff --git a/dom/base/test/test_bug498240.html b/dom/base/test/test_bug498240.html new file mode 100644 index 0000000000..373c644700 --- /dev/null +++ b/dom/base/test/test_bug498240.html @@ -0,0 +1,254 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=498240 +--> +<head> + <title>Test for Bug 498240</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +<style> + .container { border: 1px solid blue; display:block; } + b { color:blue; } + i { color:magenta; } +</style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=498240">Mozilla Bug 498240</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 498240 **/ + + +function create(s) { + var p = document.createElement('span'); + p.innerHTML = s; + p.setAttribute("class","container"); + document.body.appendChild(p); + return p; +} +function select(start, startOffset, end, endOffset) { + var sel = getSelection(); + sel.removeAllRanges(); + var range = document.createRange(); + range.setStart(start, startOffset); + range.setEnd(end, endOffset); + sel.addRange(range); +} + +function insertClone(node) { + var sel = getSelection(); + var range = sel.getRangeAt(0); + range.insertNode(node.cloneNode(true)); +} +function insertCloneAtEnd(node) { + var sel = getSelection(); + var range = sel.getRangeAt(0); + range.endContainer.insertBefore(node.cloneNode(true),range.endContainer.childNodes[range.endOffset]); +} + +function check(start, startOffset, end, endOffset, s) { + var sel = getSelection(); + var range = sel.getRangeAt(0); + is(range.startContainer, start, "wrong start node for range: '"+range.toString()+"'"); + is(range.startOffset, startOffset, "wrong start offset for range: '"+range.toString()+"'"); + is(range.endContainer, end, "wrong end node for range: '"+range.toString()+"'"); + is(range.endOffset, endOffset, "wrong end offset for range: '"+range.toString()+"'"); +} + +function testInsertNode(node) { + var p; + + p = create('a<b>bc</b>'); + select(p.childNodes[0],0,p.childNodes[1],0); + insertClone(node); + check(p.childNodes[0],0,p.childNodes[3],0); + + p = create('d<b>ef</b>'); + select(p.childNodes[0],0,p.childNodes[1],1); + insertClone(node); + check(p.childNodes[0],0,p.childNodes[3],1); + + p = create('g<b>h</b>'); + select(p.childNodes[0],0,p.childNodes[0],0); + insertClone(node); + check(p.childNodes[0],0,p,2); + + p = create('i<b>j</b>'); + select(p.childNodes[0],1,p.childNodes[0],1); + insertClone(node); + check(p.childNodes[0],1,p,2); + + p = create('k<b>l</b>'); + select(p.childNodes[0],0,p.childNodes[1].childNodes[0],0); + insertClone(node); + check(p.childNodes[0],0,p.childNodes[3].childNodes[0],0); + + p = create('m<b>no</b>'); + select(p.childNodes[0],1,p.childNodes[1].childNodes[0],0); + insertClone(node); + check(p.childNodes[0],1,p.childNodes[3].childNodes[0],0); + + p = create('p<b>qr</b>'); + select(p.childNodes[0],1,p.childNodes[1].childNodes[0],1); + insertClone(node); + check(p.childNodes[0],1,p.childNodes[3].childNodes[0],1); + + p = create('s<b>tu</b>'); + select(p.childNodes[0],1,p.childNodes[1],0); + insertClone(node); + check(p.childNodes[0],1,p.childNodes[3],0); + + p = create('<i>A</i><b>BC</b>'); + select(p.childNodes[0],0,p.childNodes[1],0); + insertClone(node); + check(p.childNodes[0],0,p.childNodes[1],0); + + p = create('<i>D</i><b>EF</b>'); + select(p.childNodes[0],1,p.childNodes[1],1); + insertClone(node); + check(p.childNodes[0],1,p.childNodes[1],1); + + p = create('<i></i><b>GH</b>'); + select(p.childNodes[0],0,p.childNodes[1],0); + insertClone(node); + check(p.childNodes[0],0,p.childNodes[1],0); + + p = create('<i>I</i><b>J</b>'); + select(p,0,p.childNodes[1],0); + insertClone(node); + check(p,0,p.childNodes[2],0); + + p = create('<i>K</i><b>L</b>'); + select(p,0,p,2); + insertClone(node); + check(p,0,p,3); + + p = create('<i>M</i><b>N</b>'); + select(p,1,p,2); + insertClone(node); + check(p,1,p,3); + + p = create('<i>O</i><b>P</b>'); + select(p,1,p,1); + insertClone(node); + check(p,1,p,2); + + p = create('<i>Q</i><b>R</b>'); + select(p,2,p,2); + insertClone(node); + check(p,2,p,3); + + p = create('<i>S</i><b>T</b>'); + select(p,1,p,1); + insertCloneAtEnd(node); + check(p,1,p,1); + + p = create('<i>U</i><b>V</b>'); + select(p,2,p,2); + insertCloneAtEnd(node); + check(p,2,p,2); + + p = create('<i>X</i><b>Y</b>'); + select(p,0,p,1); + insertCloneAtEnd(node); + check(p,0,p,1); + + p = create('<i>X</i><b><s>Y</s></b>'); + select(p,0,p.childNodes[1],1); + insertCloneAtEnd(node); + check(p,0,p.childNodes[1],1); + + p = create('<i>Z</i><b></b>'); + select(p,0,p.childNodes[1],0); + insertCloneAtEnd(node); + check(p,0,p.childNodes[1],0); + + p = create('<i>ZA</i><b><s>ZB</s><u>ZC</u></b>'); + select(p,0,p.childNodes[1],1); + insertCloneAtEnd(node); + check(p,0,p.childNodes[1],1); +} +function testInvalidNodeType(node) { + try { + testInsertNode(node); + ok(false,"Expected an InvalidNodeTypeError"); + } catch(e) { + is(e.name, "InvalidNodeTypeError", "Wrong exception, expected InvalidNodeTypeError"); + ok(e instanceof DOMException, "Wrong type of exception: " + e); + is(e.code, DOMException.INVALID_NODE_TYPE_ERR, "Wrong exception code, expected INVALID_NODE_TYPE_ERR"); + } +} + +function runTest() { + testInsertNode(document.createTextNode('123')); + + var i = document.createElement('SPAN') + i.innerHTML='456' + testInsertNode(i); + + i = document.createDocumentFragment(); + i.appendChild(document.createTextNode('789')); + testInsertNode(i); + + /// DOM2 Traversal and Range Specification 2.13 "insertNode": + /// RangeException INVALID_NODE_TYPE_ERR: Raised if newNode is an Attr, Entity, Notation, or Document node. + // BUG: testInvalidNodeType(document.createAttribute('a')); + todo(false, "Test insertion of Entity node into range"); + // TODO: testInvalidNodeType(document.createEntity()); + todo(false, "Test insertion of Notation node into range"); + // TODO: testInvalidNodeType(document.createNotation()); + // BUG: testInvalidNodeType(document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null)); + + // Intentionally fails because of bug 418755. + todo(false, "test that Range::insertNode() throws WrongDocumentError when it should"); + i = document.implementation.createDocument('http://www.w3.org/1999/xhtml', 'html', null).createElement('html'); + try { + testInsertNode(i); + todo(false,"Expected a WrongDocumentError"); + } catch(e) { + is(e.name, "WrongDocumentError", "Wrong exception, expected WrongDocumentError"); + ok(e instanceof DOMException, "Wrong type of exception: " + e); + is(e.code, DOMException.WRONG_DOCUMENT_ERR, "Wrong exception code, expected WRONG_DOCUMENT_ERR"); + } + + // Inserting an ancestor of the start container should throw HierarchyRequestError + todo(false, "test that Range::insertNode() throws HierarchyRequestError when it should"); + var p = create('<b>IJK</b>'); + select(p.childNodes[0],0,p.childNodes[0],1); + var sel = getSelection(); + var range = sel.getRangeAt(0); + try { + range.insertNode(p); + ok(false,"Expected a HierarchyRequestError"); + } catch(e) { + is(e.name, "HierarchyRequestError", "Wrong exception, expected HierarchyRequestError"); + ok(e instanceof DOMException, "Wrong type of exception: " + e); + is(e.code, DOMException.HIERARCHY_REQUEST_ERR, "Wrong exception code, expected HIERARCHY_REQUEST_ERR"); + } + + // TODO: we should also have a test for: + /// "HierarchyRequestError: Raised if the container of the start of the Range is of a type + /// that does not allow children of the type of newNode" + + todo(false, "InvalidStateError test goes here..."); + + var sel = getSelection(); + sel.removeAllRanges(); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug498433.html b/dom/base/test/test_bug498433.html new file mode 100644 index 0000000000..5bafcd2ea6 --- /dev/null +++ b/dom/base/test/test_bug498433.html @@ -0,0 +1,104 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for HTML serializer</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=498433">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="testframe" src="file_htmlserializer_ipv6.html"> + </iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + + +function loadFileContent(aFile, aCharset) { + if (aCharset == undefined) + aCharset = 'UTF-8'; + + var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1'] + .createInstance(SpecialPowers.Ci.nsIURI); + baseUri.spec = window.location.href; + + var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1'] + .getService(SpecialPowers.Ci.nsIIOService); + var chann = ios.newChannel2(aFile, + aCharset, + baseUri, + null, // aLoadingNode + SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(), + null, // aTriggeringPrincipal + SpecialPowers.Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, + SpecialPowers.Ci.nsIContentPolicy.TYPE_OTHER); + + var cis = SpecialPowers.Ci.nsIConverterInputStream; + + var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"] + .createInstance(cis); + inputStream.init(chann.open2(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER); + var str = {}, content = ''; + while (inputStream.readString(4096, str) != 0) { + content += str.value; + } + return content; +} + +function isRoughly(actual, expected, message) { + return is(actual.replace("<!DOCTYPE HTML", "<!DOCTYPE html"), + expected, + message); +} + +function testHtmlSerializer_1 () { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + + var doc = $("testframe").contentDocument; + var out, expected; + + // in the following tests, we must use the OutputLFLineBreak flag, to avoid + // to have the default line break of the platform in the result, so the test + // can pass on all platform + + //------------ no flags + encoder.init(doc, "text/html", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_ipv6_out.html"); + isRoughly(out, expected, "test no flags"); + //------------ OutputAbsoluteLinks + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputAbsoluteLinks); + encoder.setCharset("UTF-8"); + out = encoder.encodeToString(); + expected = loadFileContent("file_htmlserializer_ipv6_out.html"); + isRoughly(out, expected, "test OutputAbsoluteLinks"); + //------------ serializing a selection + encoder.init(doc, "text/html", de.OutputLFLineBreak | de.OutputAbsoluteLinks); + encoder.setNode(doc.links[0]); + out = encoder.encodeToString(); + expected = "<a href=\"http://[2001:4860:a003::68]/\">Test</a>"; + isRoughly(out, expected, "test selection"); + + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlSerializer_1); + +</script> +</pre> + +</body> +</html> + + diff --git a/dom/base/test/test_bug498897.html b/dom/base/test/test_bug498897.html new file mode 100644 index 0000000000..c45c0421ea --- /dev/null +++ b/dom/base/test/test_bug498897.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=498897 +--> +<head> + <title>Test for Bug 498897</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=498897">Mozilla Bug 498897</a> +<p id="display"><iframe id="testframe"></iframe></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 498897 **/ + +var checkedLoad = false; + +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +// Content policy / factory implementation for the test +var policyID = SpecialPowers.wrap(SpecialPowers.Components).ID("{65944d64-2390-422e-bea3-80d0af7f69ef}"); +var policyName = "@mozilla.org/498897_testpolicy;1"; +var policy = { + // nsISupports implementation + QueryInterface: function(iid) { + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIFactory) || + iid.equals(Ci.nsIContentPolicy)) + return this; + + throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE; + }, + + // nsIFactory implementation + createInstance: function(outer, iid) { + return this.QueryInterface(iid); + }, + + // nsIContentPolicy implementation + shouldLoad: function(contentType, contentLocation, requestOrigin, context, + mimeTypeGuess, extra) { + var url = window.location.href.substr(0, window.location.href.indexOf('test_bug498897')); + if (contentLocation.spec == url + "file_bug498897.css" && + requestOrigin.spec == url + "file_bug498897.html") { + checkedLoad = true; + } + + return Ci.nsIContentPolicy.ACCEPT; + }, + + shouldProcess: function(contentType, contentLocation, requestOrigin, context, + mimeTypeGuess, extra) { + return Ci.nsIContentPolicy.ACCEPT; + } +} +policy = SpecialPowers.wrapCallbackObject(policy); + +var componentManager = SpecialPowers.wrap(SpecialPowers.Components).manager + .QueryInterface(Ci.nsIComponentRegistrar); +componentManager.registerFactory(policyID, "Test content policy for bug 498897", + policyName, policy); + +var categoryManager = + Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager); +categoryManager.addCategoryEntry("content-policy", policyName, policyName, + false, true); + +function testFinished() +{ + ok(checkedLoad, "Content policy didn't get called!"); + + categoryManager.deleteCategoryEntry("content-policy", policyName, false); + + setTimeout(function() { + componentManager.unregisterFactory(policyID, policy); + + SimpleTest.finish(); + }, 0); +} + +SimpleTest.waitForExplicitFinish(); + +document.getElementById("testframe").src = "file_bug498897.html"; + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug499656.html b/dom/base/test/test_bug499656.html new file mode 100644 index 0000000000..8fd71091a2 --- /dev/null +++ b/dom/base/test/test_bug499656.html @@ -0,0 +1,57 @@ +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=499656 +--> +<head> + <title>Test for Bug 499656</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=499656">Mozilla Bug 499655</a> +<p id="display"></p> +<div id="content"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 499655 **/ + +div1 = document.createElementNS("http://www.w3.org/1999/xhtml","test"); +div2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst"); +div3 = document.createElementNS("test","test"); +div4 = document.createElementNS("test","TEst"); +div5 = document.createElement("test"); +div6 = document.createElement("TEst"); + +content = document.getElementById("content"); + +content.appendChild(div1); +content.appendChild(div2); +content.appendChild(div3); +content.appendChild(div4); +content.appendChild(div5); +content.appendChild(div6); + +list = document.getElementsByTagName('test'); +is(list.length, 4, "Number of elements found"); +ok(list[0] == div1, "First element didn't match"); +ok(list[1] == div3, "Third element didn't match"); +ok(list[2] == div5, "Fifth element didn't match"); +ok(list[3] == div6, "Sixth element didn't match"); + +list = document.getElementsByTagName('TEst'); +is(list.length, 4, "Wrong number of elements found"); +ok(list[0] == div1, "First element didn't match"); +ok(list[1] == div4, "Fourth element didn't match"); +ok(list[2] == div5, "Fifth element didn't match"); +ok(list[3] == div6, "Sixth element didn't match"); + +list = document.getElementsByTagNameNS('test', 'test'); +is(list.length, 1, "Wrong number of elements found"); +ok(list[0] == div3, "Third element didn't match"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug499656.xhtml b/dom/base/test/test_bug499656.xhtml new file mode 100644 index 0000000000..3da53fe5ad --- /dev/null +++ b/dom/base/test/test_bug499656.xhtml @@ -0,0 +1,57 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=499655 +--> +<head> + <title>Test for Bug 499655</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=499655">Mozilla Bug 499655</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +<![CDATA[ + +div1 = document.createElementNS("http://www.w3.org/1999/xhtml","test"); +div2 = document.createElementNS("http://www.w3.org/1999/xhtml","TEst"); +div3 = document.createElementNS("test","test"); +div4 = document.createElementNS("test","TEst"); +div5 = document.createElement("test"); +div6 = document.createElement("TEst"); + +content = document.getElementById("content"); + +content.appendChild(div1); +content.appendChild(div2); +content.appendChild(div3); +content.appendChild(div4); +content.appendChild(div5); +content.appendChild(div6); + + +list = document.getElementsByTagName('test'); +is(list.length, 3, "Number of elements found"); +ok(list[0] == div1, "First element didn't match"); +ok(list[1] == div3, "Third element didn't match"); +ok(list[2] == div5, "Fifth element didn't match"); + +list = document.getElementsByTagName('TEst'); +is(list.length, 3, "Number of elements found"); +ok(list[0] == div2, "Second element didn't match"); +ok(list[1] == div4, "Fourth element didn't match"); +ok(list[2] == div6, "Sixth element didn't match"); + +list = document.getElementsByTagNameNS('test', 'test'); +is(list.length, 1, "Wrong number of elements found"); +ok(list[0] == div3, "Third element didn't match"); + +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug500937.html b/dom/base/test/test_bug500937.html new file mode 100644 index 0000000000..c342adc860 --- /dev/null +++ b/dom/base/test/test_bug500937.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=500937 +--> +<head> + <title>Test for Bug 500937</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=500937">Mozilla Bug 500937</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id=iframe src="about:blank"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 500937 **/ + +var d = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", null); +var h = d.documentElement; +h.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "head")); +var b = d.createElementNS("http://www.w3.org/1999/xhtml", "body"); +h.appendChild(b); + +b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "div")); +b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "script")); +b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "br")); +b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "source")); +b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "param")); +b.appendChild(d.createTextNode("\u00A0")); + +is(new XMLSerializer().serializeToString(d), + '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><div></div><script><\/script><br /><source /><param />\u00A0</body></html>', + "XML DOM input to XMLSerializer"); + +d = document.getElementById('iframe').contentWindow.document; + +while(d.documentElement.previousSibling) { + d.removeChild(d.documentElement.previousSibling); +} + +d.replaceChild(h, d.documentElement); + +is(new XMLSerializer().serializeToString(d), + '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><div></div><script><\/script><br /><source /><param />\u00A0</body></html>', + "HTML DOM input to XMLSerializer"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug503473.html b/dom/base/test/test_bug503473.html new file mode 100644 index 0000000000..fe563aa57d --- /dev/null +++ b/dom/base/test/test_bug503473.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=503473 +--> +<head> + <title>Test for Bug 503473</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=503473">Mozilla Bug 503473</a> +<p id="display"></p> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 503473 **/ + +SimpleTest.waitForExplicitFinish(); + +function done() { + var iframe = document.getElementById("iframe"); + var divs = iframe.contentWindow.document.getElementsByTagName("div").length; + is(divs, 0, "Div wasn't blown away.") + + SimpleTest.finish(); +} + +</script> +</pre> +<div id="content" style="display: none"> + <iframe id='iframe' src="file_bug503473-frame.sjs"> + </iframe> +</div> +</body> +</html> diff --git a/dom/base/test/test_bug503481.html b/dom/base/test/test_bug503481.html new file mode 100644 index 0000000000..98db4893e2 --- /dev/null +++ b/dom/base/test/test_bug503481.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=503481 +--> +<head> + <title>Test for Bug 503481</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="done();"> + +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503481" + target="_blank" >Mozilla Bug 503481</a> + +<p id="display"></p> + +<script> +SimpleTest.waitForExplicitFinish(); +function done() { + is(firstRan, true, "first has run"); + is(secondRan, true, "second has run"); + is(thirdRan, true, "third has run"); + SimpleTest.finish(); +} +var reqs = []; +function unblock(s) { + xhr = new XMLHttpRequest(); + xhr.open("GET", "file_bug503481.sjs?unblock=" + s); + xhr.send(); + reqs.push(xhr); +} +var firstRan = false, secondRan = false, thirdRan = false; +function runFirst() { firstRan = true; } +function runSecond() { + is(thirdRan, true, "should have run third already"); + secondRan = true; +} +function runThird() { + is(secondRan, false, "shouldn't have unblocked second yet"); + thirdRan = true; + unblock("B"); +} +</script> +<script id=firstScript async src="file_bug503481.sjs?blockOn=A&body=runFirst();"></script> +<script id=firstScriptHelper> +is(document.getElementById("firstScript").async, true, + "async set"); +is(document.getElementById("firstScriptHelper").async, false, + "async not set"); +document.getElementById("firstScript").async = false; +is(document.getElementById("firstScript").async, false, + "async no longer set"); +is(document.getElementById("firstScript").hasAttribute("async"), false, + "async attribute no longer set"); +is(firstRan, false, "First async script shouldn't have run"); +unblock("A"); +</script> + +<script async src="file_bug503481.sjs?blockOn=B&body=runSecond();"></script> +<script async src="file_bug503481.sjs?blockOn=C&body=runThird();"></script> +<script> +is(secondRan, false, "Second async script shouldn't have run"); +is(thirdRan, false, "Third async script shouldn't have run"); +unblock("C"); +</script> + +</body> +</html> diff --git a/dom/base/test/test_bug503481b.html b/dom/base/test/test_bug503481b.html new file mode 100644 index 0000000000..e11fe36116 --- /dev/null +++ b/dom/base/test/test_bug503481b.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=503481 +--> +<head> + <title>Test for Bug 503481</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=503481" + target="_blank" >Mozilla Bug 503481</a> + +<iframe src="file_bug503481b_inner.html"></iframe> +<script> +SimpleTest.waitForExplicitFinish(); +// script in the iframe will call SimpleTest.finish() +</script> +</body> +</html> diff --git a/dom/base/test/test_bug505783.html b/dom/base/test/test_bug505783.html new file mode 100644 index 0000000000..a1c9789ed3 --- /dev/null +++ b/dom/base/test/test_bug505783.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=505783 +--> +<head> + <title>Test for Bug 505783</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=505783">Mozilla Bug 505783</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 505783 **/ + +var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a"); +a.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:base", "http://example.org/"); +a.href = "page"; +is(a.href, "http://example.org/page", "xml:base not used when not in doc"); +document.getElementById("content").appendChild(a); +is(a.href, "http://example.org/page", "xml:base not used when in doc"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug51034.html b/dom/base/test/test_bug51034.html new file mode 100644 index 0000000000..b6eac76ba2 --- /dev/null +++ b/dom/base/test/test_bug51034.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=51034 +--> +<head> + <title>Test for Bug 51034</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=51034">Mozilla Bug 51034</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="divElement"> + <span>Subelement1</span> + <span>Subelement2</span> + <span>Subelement3</span> + </div> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 51034 **/ +var x = document.getElementById('divElement'); + +isOK = false; +try { +x.getElementsByTagName('span'); +isOK = true; +} catch (ex) { + isOK = false; +} + +ok(isOK, "getElementsByTagName() doesn't cause exception"); + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug513194.html b/dom/base/test/test_bug513194.html new file mode 100644 index 0000000000..ac2cb74bad --- /dev/null +++ b/dom/base/test/test_bug513194.html @@ -0,0 +1,28 @@ +<!doctype html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=513194 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 513194</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=631615" + >Mozilla Bug 513194</a> +<script> +// The use of document.write is deliberate. We are testing for the +// HTML parser to call the CSS parser once and only once when it +// encounters a new <style> element. + +SimpleTest.runTestExpectingConsoleMessages( + function () { document.write("<style>qux { foo : bar; }<\/style>") }, + [{ errorMessage: /Unknown property/ }] +); +</script> +</body> +</html> + diff --git a/dom/base/test/test_bug5141.html b/dom/base/test/test_bug5141.html new file mode 100644 index 0000000000..87acc5d0ee --- /dev/null +++ b/dom/base/test/test_bug5141.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=5141 +--> +<head> + <title>Test for Bug 5141</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=5141">Mozilla Bug 5141</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 5141 **/ +var baz = document.createElement('img'); +ok(baz.parentNode === null, "Node.parentNode should be null for standalone nodes"); + + + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug514487.html b/dom/base/test/test_bug514487.html new file mode 100644 index 0000000000..7b64d8fcbb --- /dev/null +++ b/dom/base/test/test_bug514487.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html id="root"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=514487 +--> +<head id="child"> + <title>Test for Bug 514487</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTests()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=514487">Mozilla Bug 514487</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 514487 **/ + + SimpleTest.waitForExplicitFinish(); + + function runTests() { + // Test XML document cloning. + var d = (new DOMParser()).parseFromString( + "<html xmlns='http://www.w3.org/1999/xhtml' id='root'><foo id='child'/></html>", + "text/xml"); + var cloneDoc = d.cloneNode(true); + ok(cloneDoc.getElementById("root"), + "XML document should have an element with ID 'root'"); + ok(cloneDoc.getElementById("child"), + "XML document should have an element with ID 'child'"); + + // Test HTML cloning. + cloneDoc = document.cloneNode(true); + ok(cloneDoc.getElementById("root"), + "HTML document should have an element with ID 'root'"); + ok(cloneDoc.getElementById("child"), + "HTML document should have an element with ID 'child'"); + SimpleTest.finish(); + } + + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug515401.html b/dom/base/test/test_bug515401.html new file mode 100644 index 0000000000..d3e1884d7c --- /dev/null +++ b/dom/base/test/test_bug515401.html @@ -0,0 +1,141 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=515401 +--> +<head> + <title>Test for Bug 515401</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <base id=basehref href="base/"> + <base id=basehref2> + <base id=basetarget target="def_target"> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=515401">Mozilla Bug 515401</a> +<a id=a href="dest.html">Simple link</a> +<a id=awtarget target="a_target">Link with target</a> + +<p id="display"></p> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var a = $('a'); +var awtarget = $('awtarget'); +var head = document.documentElement.firstElementChild; + +// Test targets +is(a.target, "def_target", "using default target"); +is(awtarget.target, "a_target", "specified target"); +$('basetarget').setAttribute("target", "new_def_target"); +is(a.target, "new_def_target", "using new default target"); +is(awtarget.target, "a_target", "still specified target"); +$('basetarget').removeAttribute("target"); +is(a.target, "", "no target"); +is(awtarget.target, "a_target", "yet still specified target"); +newbasetarget = document.createElement('base'); +newbasetarget.target = "new_target_elem"; +head.appendChild(newbasetarget); +is(a.target, "new_target_elem", "new target element"); +is(awtarget.target, "a_target", "yet still specified target"); +newbasetarget.target = "new_target_elem_value"; +is(a.target, "new_target_elem_value", "new target element attribute"); +is(awtarget.target, "a_target", "yet still specified target"); +newbasetarget.target = ""; +is(a.target, "", "new target element no attribute"); +is(awtarget.target, "a_target", "yet still specified target"); + + +// link hrefs +var basehref = $('basehref'); +var basehref2 = $('basehref2'); +var pre = "http://mochi.test:8888/tests/dom/base/test/"; +function verifyBase(base, test) { + if (base == "") { + is(document.baseURI, document.URL, "document base when " + test); + is(a.href, pre + "dest.html", "link href when " + test); + } + else { + is(document.baseURI, pre + base, "document base when " + test); + is(a.href, pre + base + "dest.html", "link href when " + test); + } +} + + +// In document base +verifyBase("base/", "from markup"); + +// Modify existing <base> +basehref.href = "base2/"; +verifyBase("base2/", "modify existing"); +is(basehref.href, pre + "base2/", "HTMLBaseElement.href resolves correctly"); + +// Modify existing <base> to absolute url +basehref.href = "http://www.example.com/foo/bar.html"; +is(document.baseURI, "http://www.example.com/foo/bar.html", "document base when setting absolute url"); +is(a.href, "http://www.example.com/foo/dest.html", "link href when setting absolute url"); +is(basehref.href, "http://www.example.com/foo/bar.html", + "HTMLBaseElement.href resolves correctly when setting absolute url"); + +// Remove href on existing element +basehref.removeAttribute("href"); +verifyBase("", "remove href on existing element"); + +// Create href on existing element +basehref.href = "base3/"; +verifyBase("base3/", "create href on existing element"); + +// Fall back to second after remove attr +basehref2.href = "base4/"; +verifyBase("base3/", "add href on second base"); +basehref.removeAttribute("href"); +verifyBase("base4/", "fall back to second after remove attr"); + +// Set href on existing again +basehref.href = "base5/"; +verifyBase("base5/", "set href on existing again"); + +// Unset href on second +basehref2.removeAttribute("href"); +verifyBase("base5/", "unset href on second"); + +// Insert base with href before existing +var basehref0 = document.createElement("base"); +basehref0.href = "base6/"; +verifyBase("base5/", "nothing modified"); +head.insertBefore(basehref0, head.firstChild); +verifyBase("base6/", "insert base with href before existing"); + +// Insert base as grandchild of head +var basehref3 = document.createElement("base"); +basehref3.href = "base7/"; +var tmp = document.createElement("head"); +tmp.appendChild(basehref3); +head.insertBefore(tmp, head.firstChild); +verifyBase("base7/", "inserted base as grandchild of head at the beginning of head"); +is(basehref3.parentNode.parentNode, head, "base got inserted correctly"); + +// Remove secondary bases +var tmp, tmp2; +for (tmp = head.firstChild; tmp = tmp.nextSibling; tmp) { + if (tmp.localName == "base" && tmp != basehref0) { + tmp2 = tmp.previousSibling; + head.removeChild(tmp); + tmp = tmp2; + } + verifyBase("base7/", "remove unneeded base"); +} + +// Remove head +document.documentElement.removeChild(head); +verifyBase("", "removed head"); + +// Insert base in body +document.body.insertBefore(basehref3, document.body.firstChild); +verifyBase("base7/", "inserted base in body"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug518104.html b/dom/base/test/test_bug518104.html new file mode 100644 index 0000000000..d60d2ac9f8 --- /dev/null +++ b/dom/base/test/test_bug518104.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=518104 +--> +<head> + <title>Test for Bug 518104</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=518104">Mozilla Bug 518104</a> +<p id="display"></p> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 518104 **/ +SimpleTest.waitForExplicitFinish(); + +function done() { + var iframe = document.getElementById("iframe"); + var divs = iframe.contentWindow.document.getElementsByTagName("p").length; + is(divs, 0, "<p> got written.") + SimpleTest.finish(); +} + +</script> +<div id="content" style="display: none"> + <iframe id='iframe' src="data:text/html, + <div></div><div></div> + <script defer src='data:application/javascript,document.write(%2522<p></p>%2522);parent.done();document.close();'></script>"> + </iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug527896.html b/dom/base/test/test_bug527896.html new file mode 100644 index 0000000000..666338d044 --- /dev/null +++ b/dom/base/test/test_bug527896.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=527896 +--> +<head> + <title>Test for Bug 527896</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload='done();'> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=527896">Mozilla Bug 527896</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 527896 **/ + +SimpleTest.waitForExplicitFinish(); + +var docWrittenSrcExecuted = false; +var scriptInsertedSrcExecuted = false; + +// the iframe test runs with the HTML5 parser + +var iframe = document.getElementsByTagName('iframe')[0]; +iframe.contentWindow.document.open(); +iframe.contentWindow.document.write("<!DOCTYPE html>"); +iframe.contentWindow.document.write("<body><script id =\"thescript\" src=\"data:text/javascript,parent.docWrittenSrcExecuted = true;\">"); + +// now remove the src attribute before the end tag is parsed +iframe.contentWindow.document.getElementById('thescript').removeAttribute('src'); + +iframe.contentWindow.document.write("parent.ok(false, \"Content executed.\");"); +iframe.contentWindow.document.write("<\/script>"); +iframe.contentWindow.document.close(); + +// the insertion test runs with the default HTML parser since it's in this document itself! + +var div = document.getElementById('content'); +var script = document.createElement('script'); +div.appendChild(script); // this shouldn't yet freeze the script node nor run it +script.setAttribute("src", "data:text/javascript,scriptInsertedSrcExecuted = true;"); + +todo(false, "Add SVG tests after bug 528442."); + +function done() { + ok(docWrittenSrcExecuted, "document.written src didn't execute"); + ok(scriptInsertedSrcExecuted, "script-inserted src didn't execute"); + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug540854.html b/dom/base/test/test_bug540854.html new file mode 100644 index 0000000000..f4d12621f8 --- /dev/null +++ b/dom/base/test/test_bug540854.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=540854 +--> +<head> + <title>Test for Bug 540854</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=540854">Mozilla Bug 540854</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 540854 **/ + + + var x; + + function getUTF8() { + return unescape(encodeURIComponent('\0foo')); + } + + function xload() { + is(this.responseText, getUTF8(), "Unexpected responseText!"); + SimpleTest.finish(); + } + + function runTest() { + x = new XMLHttpRequest(); + x.open("POST", "bug540854.sjs") + x.onload = xload; + x.send(getUTF8()); + } + + SimpleTest.waitForExplicitFinish(); + addLoadEvent(runTest); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug541937.html b/dom/base/test/test_bug541937.html new file mode 100644 index 0000000000..c311b16157 --- /dev/null +++ b/dom/base/test/test_bug541937.html @@ -0,0 +1,119 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for XHTML serializer, bug 541937</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=541937">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="testframe" src="file_bug541937.html"> + </iframe> + <iframe id="testframe2" src="file_bug541937.xhtml"> + </iframe> +</div> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function testSerializer () { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + + var parser = new DOMParser(); + var serializer = new XMLSerializer(); + + // with content + var str = '<?xml version="1.0"?><doc>\n<link xmlns="http://www.w3.org/1999/xhtml"><!-- child nodes --> \n<content xmlns=""/></link>\n</doc>'; + var expected = '<?xml version="1.0" encoding="UTF-8"?>\n<doc>\n<link xmlns="http://www.w3.org/1999/xhtml"><!-- child nodes --> \n<content xmlns=""/></link>\n</doc>'; + + var doc = parser.parseFromString(str,"application/xml"); + var result = serializer.serializeToString(doc); + result = result.replace(/\r\n/mg, "\n"); + is(result, expected, "serialization of a link element inside an xml document with children"); + + // with only whitespaces + str = '<?xml version="1.0"?><doc>\n<link xmlns="http://www.w3.org/1999/xhtml"> \n </link>\n</doc>'; + expected = '<?xml version="1.0" encoding="UTF-8"?>\n<doc>\n<link xmlns="http://www.w3.org/1999/xhtml"> \n </link>\n</doc>'; + + doc = parser.parseFromString(str,"application/xml"); + result = serializer.serializeToString(doc); + result = result.replace(/\r\n/mg, "\n"); + is(result, expected, "serialization of a link element with only whitespaces as content, inside an xml document"); + + // with only one space as content + str = '<?xml version="1.0"?><doc>\n<link xmlns="http://www.w3.org/1999/xhtml"> </link>\n</doc>'; + expected = '<?xml version="1.0" encoding="UTF-8"?>\n<doc>\n<link xmlns="http://www.w3.org/1999/xhtml"> </link>\n</doc>'; + + doc = parser.parseFromString(str,"application/xml"); + result = serializer.serializeToString(doc); + result = result.replace(/\r\n/mg, "\n"); + is(result, expected, "serialization of a link element with only one space as content, inside an xml document"); + + // let's remove the content + str = '<?xml version="1.0"?><doc>\n<link xmlns="http://www.w3.org/1999/xhtml"> <!-- child nodes --> \ndeleted content<content xmlns=""/> </link>\n</doc>'; + expected = '<?xml version="1.0" encoding="UTF-8"?>\n<doc>\n<link xmlns="http://www.w3.org/1999/xhtml" />\n</doc>'; + + doc = parser.parseFromString(str,"application/xml"); + doc.documentElement.firstElementChild.textContent = ''; + result = serializer.serializeToString(doc); + result = result.replace(/\r\n/mg, "\n"); + is(result, expected, "serialization of a link element on which we removed dynamically the content, inside an xml document"); + + // with no content but an ended tag + str = '<?xml version="1.0"?><doc>\n<link xmlns="http://www.w3.org/1999/xhtml"></link>\n</doc>'; + expected = '<?xml version="1.0" encoding="UTF-8"?>\n<doc>\n<link xmlns="http://www.w3.org/1999/xhtml" />\n</doc>'; + + doc = parser.parseFromString(str,"application/xml"); + result = serializer.serializeToString(doc); + result = result.replace(/\r\n/mg, "\n"); + is(result, expected, "serialization of a link element with no content but with an ended tag, inside an xml document"); + + // with no content + str = '<?xml version="1.0"?><doc>\n<link xmlns="http://www.w3.org/1999/xhtml"/>\n</doc>'; + expected = '<?xml version="1.0" encoding="UTF-8"?>\n<doc>\n<link xmlns="http://www.w3.org/1999/xhtml" />\n</doc>'; + + doc = parser.parseFromString(str,"application/xml"); + result = serializer.serializeToString(doc); + result = result.replace(/\r\n/mg, "\n"); + is(result, expected, "serialization of a link element with no content, inside an xml document"); + + + doc = $("testframe").contentDocument; + encoder.init(doc, "text/html", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + result = encoder.encodeToString(); + expected = '<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n <title>Test</title>\n'; + expected += ' <link rel=\"Top\" href=\"\"> '; + expected += ' </head><body>foo \n\n\n <p>Hello world</p>\n</body></html>'; + is(result, expected, "serialization of a link element with content, inside an html document"); + + doc = $("testframe2").contentDocument; + encoder.init(doc, "application/xhtml+xml", de.OutputLFLineBreak); + encoder.setCharset("UTF-8"); + result = encoder.encodeToString(); + expected = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'; + expected += '<html xmlns="http://www.w3.org/1999/xhtml">\n<head>\n <meta http-equiv="content-type" content="text/html; charset=UTF-8" />\n <title>Test</title>\n'; + expected += ' <link rel="Top" href=""> foo </link>\n'; + expected += '\n</head>\n<body>\n <p>Hello world</p>\n</body>\n</html>'; + is(result, expected, "serialization of a link element with content, inside an xhtml document"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testSerializer); + +</script> +</pre> +</body> +</html> + + diff --git a/dom/base/test/test_bug544642.html b/dom/base/test/test_bug544642.html new file mode 100644 index 0000000000..350360f41c --- /dev/null +++ b/dom/base/test/test_bug544642.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for bug 544642</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=544642" + target="_blank" >Mozilla Bug 544642</a> +<p id="display"></p> +<iframe id=iframe></iframe> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> +SimpleTest.waitForExplicitFinish(); +var gen = runTest(); + +addLoadEvent(function() { gen.next(); }); + +function runTest() { + var iframe = $('iframe'); + iframe.onerror = function() { gen.send("error"); }; + iframe.onload = function() { gen.send("load"); }; + + iframe.src = "data:text/plain,hello"; + is((yield), "load", "plaintext data"); + + iframe.src = "file://foo/bar"; + is((yield), "error", "file"); + + // We should do this test too, however it brings up a modal dialog which + // we can't dismiss. + //iframe.src = "http:////"; + //is((yield), "error", "invalid http"); + + SimpleTest.finish(); + + yield undefined; +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug545644.html b/dom/base/test/test_bug545644.html new file mode 100644 index 0000000000..d3e169ec4f --- /dev/null +++ b/dom/base/test/test_bug545644.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for HTML serializer + innerHtml, bug 545644</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=545644">Mozilla Bug </a> +<p id="display"></p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function testInner () { + var div = document.getElementById("test_inner"); + + try { + div.innerHTML = "some \u00A0 text"; + div.innerHTML += "!"; + ok (true, "innerHTML in html", "test ok"); + } catch (e) { + ok(false, "innerHTML in html", "test failed, unwanted exception "+e); + } + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testInner); + +</script> +</pre> +<div id="test_inner"></div> +</body> +</html> + + diff --git a/dom/base/test/test_bug545644.xhtml b/dom/base/test/test_bug545644.xhtml new file mode 100644 index 0000000000..c45fd1621b --- /dev/null +++ b/dom/base/test/test_bug545644.xhtml @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +--> +<head> + <title>Test for XHTML serializer + innerHtml, bug 545644</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=545644">Mozilla Bug </a> +<p id="display"></p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function testInner () { + var div = document.getElementById("test_inner"); + + try { + div.innerHTML = "some \u00A0 &nbsp; text"; + ok(false, "innerHTML in xhtml", "test failed, no exception by the parser when giving an unexpected entity"+e); + } catch (e) { + ok (true, "innerHTML in xhtml", "test ok"); + } + + try { + div.innerHTML = "some \u00A0 text"; + div.innerHTML += "!"; + ok (true, "innerHTML in xhtml", "test ok"); + } catch (e) { + ok(false, "innerHTML in xhtml", "test failed, unexpected exception "+e); + } + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testInner); + +</script> +</pre> +<div id="test_inner"></div> +</body> +</html> + + diff --git a/dom/base/test/test_bug548463.html b/dom/base/test/test_bug548463.html new file mode 100644 index 0000000000..922c0e9d1c --- /dev/null +++ b/dom/base/test/test_bug548463.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=548463 +--> +<head> + <title>Test for Bug 548463</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=548463">Mozilla Bug 548463</a> +<p id="display"></p> +<iframe id="otherDoc"></iframe> +<div id="content" style="display: none"> + <p id="elem1"></p> + <p id="elem2"></p> +</div> +<div id="otherContent" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 548463 **/ + +var otherDoc = document.getElementById("otherDoc").contentDocument; +var content = document.getElementById("content"); +var elem1 = document.getElementById("elem1"); +var elem2 = document.getElementById("elem2"); + +function testAdoptFromDOMNodeRemoved(nodeToAppend, nodeRemoved, nodeToAdopt) +{ + function reparent(event) + { + if (event.target == nodeRemoved) { + nodeRemoved.removeEventListener("DOMNodeRemoved", arguments.callee, false); + otherDoc.adoptNode(nodeToAdopt); + } + } + nodeRemoved.addEventListener("DOMNodeRemoved", reparent, false); + + var thrown = false; + try { + document.getElementById("otherContent").appendChild(nodeToAppend); + } + catch (e) { + thrown = true; + } + + ok(!thrown, "adoptNode while appending should not throw"); +} + +var frag = document.createDocumentFragment(); +frag.appendChild(elem1); +frag.appendChild(elem2); +testAdoptFromDOMNodeRemoved(frag, elem1, elem2); + +content.appendChild(elem1); +testAdoptFromDOMNodeRemoved(elem1, elem1, content); + +content.appendChild(elem1); + +var thrown = false; + +function changeOwnerDocument() +{ + SpecialPowers.wrap(elem1).setUserData("foo", null, null); + otherDoc.adoptNode(elem1); +} +SpecialPowers.wrap(elem1).setUserData("foo", "bar", changeOwnerDocument); +try { + document.adoptNode(elem1); +} +catch (e) { + thrown = true; +} + +ok(!thrown, "adoptNode while adopting should not throw"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug553896.xhtml b/dom/base/test/test_bug553896.xhtml new file mode 100644 index 0000000000..ae43642cb7 --- /dev/null +++ b/dom/base/test/test_bug553896.xhtml @@ -0,0 +1,69 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=553896 +--> +<head> + <title>Test for Bug 553896</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=553896">Mozilla Bug 553896</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +<![CDATA[ +/** Test for Bug 553896 **/ +try { + ok(!document.createElement("foo").isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.createAttribute("foo").isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.createTextNode("foo").isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.createCDATASection("foo").isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.createProcessingInstruction("foo", "bar").isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.createComment("foo").isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.implementation.createDocumentType("html", "", "").isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +try { + ok(!document.createDocumentFragment().isEqualNode(null), "Node is equal to null?"); +} catch (e) { + ok(false, "Exception was raised."); +} +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug557892.html b/dom/base/test/test_bug557892.html new file mode 100644 index 0000000000..4a5ec5549a --- /dev/null +++ b/dom/base/test/test_bug557892.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=557892 +--> +<head> + <title>Test for Bug 557892</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=557892">Mozilla Bug 557892</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 557892 **/ + +SimpleTest.waitForExplicitFinish(); + +window.open("file_bug557892.html", "", "width=100,height=100"); + +function done() { + ok(true, "Should not crash"); + setTimeout("SimpleTest.finish();", 0); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug558726.html b/dom/base/test/test_bug558726.html new file mode 100644 index 0000000000..759ee20955 --- /dev/null +++ b/dom/base/test/test_bug558726.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=558726 +--> +<head> + <title>Test for Bug 558726</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=558726">Mozilla Bug 558726</a> +<div> +<div id="test_558726_1"><select name="selecttest"><option value="0">item 1</option></select>x<input type="button" name="test" value="test"></div> +<div id="test_558726_2">y<input><i style="-moz-user-select: none;">z</i></div> +</div> + +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 558726 **/ + +function runTest() { + is(document.getElementById('test_558726_1').innerHTML, '<select name="selecttest"><option value="0">item 1</option></select>x<input name="test" value="test" type="button">','test_558726_1.innerHTML') + is(document.getElementById('test_558726_2').innerHTML, 'y<input><i style="-moz-user-select: none;">z</i>','test_558726_2.innerHTML') + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug559526.html b/dom/base/test/test_bug559526.html new file mode 100644 index 0000000000..dbbb490321 --- /dev/null +++ b/dom/base/test/test_bug559526.html @@ -0,0 +1,93 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=559526 +--> +<head> + <title>Test for Bug 559526</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=559526">Mozilla Bug 559526</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<div id="nodes" style="display:none"> + <div id="child1"></div> + <div id="child2"></div> + + <div id="child3"></div> + <div id="child4"></div> + <div id="child5"></div> + <div id="child6"></div> + <div id="child7"></div> + <div id="child8"></div> +</div> +<script type="application/javascript"> + +/** Test for Bug 559526 **/ + +var it; +var recurse = false; +var testCount = 0; +function filter(node) { + if (node.id == "child3" && ! recurse) { + recurse = true; + var ex = null; + try { + var foo = it.nextNode(); + } catch(e) { + ex = e; + } + ++testCount; + is(ex.name, "InvalidStateError", "Should have thrown an exception!"); + is(ex.code, DOMException.INVALID_STATE_ERR, "Should have thrown an exception!"); + recurse = false; + } + return NodeFilter.FILTER_ACCEPT; +} + +(function testNodeIterator() { + + it = document.createNodeIterator( + document.getElementById("nodes"), + NodeFilter.SHOW_ELEMENT, + filter + ); + while (it.nextNode()); +})(); + +(function testTreeWalker() { + it = document.createTreeWalker( + document.getElementById("nodes"), + NodeFilter.SHOW_ELEMENT, + filter + ); + while(it.nextNode()); + + it = document.createTreeWalker( + document.getElementById("nodes"), + NodeFilter.SHOW_ELEMENT, + filter + ); + it.firstChild(); + while(it.nextSibling()); + + it = document.createTreeWalker( + document.getElementById("nodes"), + NodeFilter.SHOW_ELEMENT, + filter + ); + it.lastChild(); + while(it.previousSibling()); +})(); + +is(testCount, 4, "Should have tests 3 filter calls!"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug560780.html b/dom/base/test/test_bug560780.html new file mode 100644 index 0000000000..d8a8fd8e7a --- /dev/null +++ b/dom/base/test/test_bug560780.html @@ -0,0 +1,99 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=560780 +--> +<head> + <title>Test for Bug 560780</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script type="text/javascript"> +function init() { + var elem = document.getElementById('body'); + elem.addEventListener('mousedown', mousedown, true); +} +var seen_mousedown = 0; +function mousedown(event) { + var doc = event.target.ownerDocument; + var win = doc.defaultView; + var elem = doc.getElementById('body'); + var selection = win.getSelection(); + if (selection.rangeCount>0) { + var ragne = selection.getRangeAt(0); + var rect = ragne.getBoundingClientRect(); + var p = elem.parentNode.appendChild(doc.createElement('p')); + p.textContent = "width: " + (rect.right -rect.left); + } + ++seen_mousedown; +} +</script> + +</head> +<body id="body"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=560780">Mozilla Bug 560780</a> +<p id="display" style="margin:0;padding:0;border:0"><a id="testlink" href="#aaaaaaaaaaaaaaaaaaaaaa">abcdefghijklmnabcdefghijklmn</a></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + 1.Start Minefield with New Profile. + 2.Select texts by alt + mouse dragging horizontaly from 'd' in the link above to far right of window. + 3.Click on the selected text + 4.Click empty area of page + 5.Repeat STEP 2 to 4 till browser crashes. (at least 5 times) + +<script type="application/javascript"> + +/** Test for Bug 560780 **/ + +function selectByMouseThenClick(elm,startx,starty) { + // select some text + var ctrl = navigator.platform.indexOf("Linux") ? true : false; + var alt = true; + var x = startx; + synthesizeMouse(elm, x, starty, { type:"mousedown", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x += 100, starty, { type:"mousemove", ctrlKey:ctrl, altKey:alt }); + synthesizeMouse(elm, x, starty, { type:"mouseup", ctrlKey:ctrl, altKey:alt }); + + // click on the selection + synthesizeMouse(elm, startx + 10, starty + 1, {}); + + // click empty area of the page + synthesizeMouse(document.getElementById('body'), 800, 800, {}); +} + +function runTest() { + var e = document.getElementById('testlink'); + selectByMouseThenClick(e,110,5); + selectByMouseThenClick(e,90,5); + selectByMouseThenClick(e,70,5); + selectByMouseThenClick(e,50,5); + selectByMouseThenClick(e,30,5); + selectByMouseThenClick(e,10,5); + is(seen_mousedown, 12, "got the mousedown events"); + SimpleTest.finish(); +} + +function doTest() { + init(); + runTest(); +} + +SimpleTest.waitForFocus(doTest, window); +SimpleTest.waitForExplicitFinish(); + + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug562137.html b/dom/base/test/test_bug562137.html new file mode 100644 index 0000000000..76bb09b620 --- /dev/null +++ b/dom/base/test/test_bug562137.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=562137 +--> +<head> + <title>Test for Bug 562137</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562137">Mozilla Bug 562137</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 562137 **/ +var myStr = "I\ufffdhave\ufffdnbsp\n"; + +var xhr = new XMLHttpRequest(); +xhr.open("GET", "file_bug562137.txt", false); +xhr.send(); +is(xhr.responseText, myStr); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug562169-1.html b/dom/base/test/test_bug562169-1.html new file mode 100644 index 0000000000..e2e9e9da28 --- /dev/null +++ b/dom/base/test/test_bug562169-1.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=562169 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 562169</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562169">Mozilla Bug 562169</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div dir="rtl" id="z"></div> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 562169 **/ +/** Test that adding an child to an element with dir="rtl" makes the + child have rtl directionality, and removing the child makes it + go back to ltr directionality **/ + +function checkSelector(element, expectedDir, expectedChild) +{ + ok(element.querySelector(":dir("+expectedDir+")") == expectedChild, + "direction should be " + expectedDir); +} + +var x = document.createElement("div"); +var y = document.createElement("div"); +x.appendChild(y); +checkSelector(x, "ltr", y); +$(z).appendChild(x); +checkSelector(x, "rtl", y); +$(z).removeChild(x); +checkSelector(x, "ltr", y); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug562169-2.html b/dom/base/test/test_bug562169-2.html new file mode 100644 index 0000000000..c421f3708c --- /dev/null +++ b/dom/base/test/test_bug562169-2.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=562169 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 562169</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562169">Mozilla Bug 562169</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 562169 **/ +/** Test that a newly created element has ltr directionality **/ + +ok(document.createElement("div").matches(":dir(ltr)"), + "Element should be ltr on creation"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug562652.html b/dom/base/test/test_bug562652.html new file mode 100644 index 0000000000..5da9867fdb --- /dev/null +++ b/dom/base/test/test_bug562652.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=562652 +--> +<head> + <title>Test for Bug 562652</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=562652">Mozilla Bug 562652</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="testtarget">_</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 562652 **/ + + +var testCount = 0; +function createHTMLDoc() { + var dtd = document.implementation.createDocumentType("HTML", "-//W3C//DTD HTML 4.01//EN", null); + var d = document.implementation.createDocument(null, null, dtd); + d.appendChild(d.createElement("html")); + d.documentElement.appendChild(d.createElement("body")); + d.body.setAttribute("id", "testtarget"); + return d; +} + +function test(d) { + var t = d.getElementById("testtarget"); + d.addEventListener("DOMNodeInserted", function(e) { ++testCount; }, false); + t.innerHTML = "_"; +} + +function runTests() { + test(document); + test(createHTMLDoc()); + is(testCount, 2, "DOMNodeInserted should have fired 2 times!"); + SimpleTest.finish(); +} + +addLoadEvent(runTests); + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug564047.html b/dom/base/test/test_bug564047.html new file mode 100644 index 0000000000..5f215232a5 --- /dev/null +++ b/dom/base/test/test_bug564047.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=564047 +--> +<head> + <title>Test for Bug 564047</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=564047">Mozilla Bug 564047</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 564047 **/ +try { + document.doctype.appendChild(document.createTextNode("test")); + ok(false, "Should have thrown an exception"); +} catch (e) { + is(e.name, "HierarchyRequestError"); + ok(e instanceof DOMException, "Should be a DOMException"); + is(e.code, DOMException.HIERARCHY_REQUEST_ERR); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug564863.xhtml b/dom/base/test/test_bug564863.xhtml new file mode 100644 index 0000000000..df6d2de3ca --- /dev/null +++ b/dom/base/test/test_bug564863.xhtml @@ -0,0 +1,359 @@ +<!DOCTYPE html [ +<!ATTLIST ns:x id ID #REQUIRED> +<!ATTLIST ns2:x id_2 ID #REQUIRED> +]> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:ns="urn:namespace" + xmlns:ns2="urn:namespace"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=564863 +--> +<head> + <title>Test for Bug 564863</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +<style> +* { + color: rgb(0, 0, 0); +} +#div_id { + color: rgb(10, 10, 10); +} +#a_id { + color: rgb(20, 20, 20); +} +#xul_id { + color: rgb(30, 30, 30); +} +#svg_id { + color: rgb(40, 40, 40); +} +#ns_id { + color: rgb(50, 50, 50); +} +#ns2_id { + color: rgb(60, 60, 60); +} +</style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=564863">Mozilla Bug 564863</a> +<!-- Elements to ensure we have nodeinfos with id-attribute set --> +<div><ns:x id="ns-holder"/><ns2:x id_2="ns2-holder"/></div> + +<!-- DOM to muck around with for tests --> +<p id="root"> +<div id="div_id" /> +<a id="a_id" /> +<xul:button id="xul_id" /> +<svg:svg><svg:g id="svg_id" /></svg:svg> +<ns:x id="ns_id" /> +</p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ + +root = $('root'); +div = root.children[0]; +a = root.children[1]; +xul = root.children[2]; +svg = root.children[3].firstChild; +nsx = root.children[4]; + +var div_cs = getComputedStyle(div, ""); +var a_cs = getComputedStyle(a, ""); +var xul_cs = getComputedStyle(xul, ""); +var svg_cs = getComputedStyle(svg, ""); +var nsx_cs = getComputedStyle(nsx, ""); + +function checkHasId(test) { + // Check computed style first to avoid flushes from hiding problems + checkHasIdNoGEBI(test); + + is($("div_id"), div, "div getElementById " + test); + is($("a_id"), a, "a getElementById " + test); + is($("xul_id"), xul, "xul getElementById " + test); + is($("svg_id"), svg, "svg getElementById " + test); + is($("ns_id"), nsx, "ns getElementById " + test); +} + +function checkHasIdNoGEBI(test) { + is(div_cs.color, "rgb(10, 10, 10)", "div color " + test); + is(a_cs.color, "rgb(20, 20, 20)", "a color " + test); + is(xul_cs.color, "rgb(30, 30, 30)", "xul color " + test); + is(svg_cs.color, "rgb(40, 40, 40)", "svg color " + test); + is(nsx_cs.color, "rgb(50, 50, 50)", "nsx color " + test); + + is(div.id, "div_id", "div id " + test); + is(a.id, "a_id", "a id " + test); + is(xul.id, "xul_id", "xul id " + test); + is(svg.id, "svg_id", "svg id " + test); + is (nsx.getAttribute("id"), "ns_id", "ns id " + test); +} + +function checkHasNoId(removed, test) { + is(div_cs.color, "rgb(0, 0, 0)", "div color " + test); + is(a_cs.color, "rgb(0, 0, 0)", "a color " + test); + is(xul_cs.color, "rgb(0, 0, 0)", "xul color " + test); + is(svg_cs.color, "rgb(0, 0, 0)", "svg color " + test); + is(nsx_cs.color, "rgb(0, 0, 0)", "nsx color " + test); + + attrValue = removed ? null : ""; + + is(div.id, "", "div id " + test); + is(a.id, "", "a id " + test); + is(xul.id, "", "xul id " + test); + is(svg.id, "", "svg id " + test); + + is(div.getAttribute("id"), attrValue, "div getAttribute " + test); + is(a.getAttribute("id"), attrValue, "a getAttribute " + test); + is(xul.getAttribute("id"), "", "xul getAttribute " + test); + is(svg.getAttribute("id"), attrValue, "svg getAttribute " + test); + is(nsx.getAttribute("id"), attrValue, "ns getAttribute " + test); + + is($("div_id"), null, "div getElementById " + test); + is($("a_id"), null, "a getElementById " + test); + is($("xul_id"), null, "xul getElementById " + test); + is($("svg_id"), null, "svg getElementById " + test); + is($("ns_id"), null, "ns getElementById " + test); +} + +// Check that dynamic modifications of attribute work + +checkHasId("in markup"); + +div.id = ""; +a.id = ""; +xul.id = ""; +svg.id = ""; +nsx.setAttribute("id", ""); + +checkHasNoId(false, "set to empty"); + +div.id = "div_id"; +a.id = "a_id"; +xul.id = "xul_id"; +svg.id = "svg_id"; +nsx.setAttribute("id", "ns_id"); + +checkHasId("set using .id"); + +div.setAttribute("id", ""); +a.setAttribute("id", ""); +xul.setAttribute("id", ""); +svg.setAttribute("id", ""); +nsx.setAttribute("id", ""); + +checkHasNoId(false, "setAttribute to empty"); + +div.id = "div_id"; +a.id = "a_id"; +xul.id = "xul_id"; +svg.id = "svg_id"; +nsx.setAttribute("id", "ns_id"); + +checkHasId("set again using .id"); + +div.removeAttribute("id"); +a.removeAttribute("id"); +xul.removeAttribute("id"); +svg.removeAttribute("id"); +nsx.removeAttribute("id"); + +checkHasNoId(true, "removed attribute"); + +div.setAttribute("id", "div_id"); +a.setAttribute("id", "a_id"); +xul.setAttribute("id", "xul_id"); +svg.setAttribute("id", "svg_id"); +nsx.setAttribute("id", "ns_id"); + +checkHasId("set using setAttribute"); + +t1 = document.createElement("div"); +t1.id = "div_id"; +t2 = document.createElement("a"); +t2.id = "a_id"; +t3 = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "button"); +t3.id = "xul_id"; +t4 = document.createElementNS("http://www.w3.org/2000/svg", "g"); +t4.id = "svg_id"; +t5 = document.createElementNS("urn:namespace", "ns:x"); +t5.setAttribute("id", "ns_id"); + +// Check that inserting elements before/after existing work + +function insertAfter(newChild, existing) { + existing.parentNode.insertBefore(newChild, existing.nextSibling); +} +function insertBefore(newChild, existing) { + existing.parentNode.insertBefore(newChild, existing); +} +function removeNode(child) { + child.parentNode.removeChild(child); +} + +insertAfter(t1, div); +insertAfter(t2, a); +insertAfter(t3, xul); +insertAfter(t4, svg); +insertAfter(t5, nsx); + +checkHasId("inserted after"); + +insertBefore(t1, div); +insertBefore(t2, a); +insertBefore(t3, xul); +insertBefore(t4, svg); +insertBefore(t5, nsx); + +checkHasIdNoGEBI("inserted before"); +is($("div_id"), t1, "div getElementById inserted before"); +is($("a_id"), t2, "a getElementById inserted before"); +is($("xul_id"), t3, "xul getElementById inserted before"); +is($("svg_id"), t4, "svg getElementById inserted before"); +is($("ns_id"), t5, "ns getElementById inserted before"); + +t1.removeAttribute("id"); +t2.removeAttribute("id"); +t3.removeAttribute("id"); +t4.removeAttribute("id"); +t5.removeAttribute("id"); + +checkHasId("removed tx attribute"); + +t1.setAttribute("id", "div_id"); +t2.setAttribute("id", "a_id"); +t3.setAttribute("id", "xul_id"); +t4.setAttribute("id", "svg_id"); +t5.setAttribute("id", "ns_id"); + +checkHasIdNoGEBI("setAttribute before"); +is($("div_id"), t1, "div getElementById setAttribute before"); +is($("a_id"), t2, "a getElementById setAttribute before"); +is($("xul_id"), t3, "xul getElementById setAttribute before"); +is($("svg_id"), t4, "svg getElementById setAttribute before"); +is($("ns_id"), t5, "ns getElementById setAttribute before"); + +removeNode(t1); +removeNode(t2); +removeNode(t3); +removeNode(t4); +removeNode(t5); + +checkHasId("removed temporaries"); + +removeNode(div); +removeNode(a); +removeNode(xul); +removeNode(svg); +removeNode(nsx); + +checkHasIdNoGEBI("removed node"); + +// Check that removing an element during UnsetAttr works +is(div.id, "div_id", "div still has id set"); +var mutateFired = false; +root.appendChild(div); +div.addEventListener("DOMAttrModified", function(e) { + div.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, div, "target is div"); + is(div.id, "", "div no longer has id"); + is(div.getAttribute("id"), null, "div no longer has id attr"); + removeNode(div); + is(div.parentNode, null, "div was removed"); + mutateFired = true; +}, false); +div.removeAttribute("id"); +ok(mutateFired, "mutation event fired"); + +// Check same for XML elements +is(nsx.getAttribute("id"), "ns_id", "nsx still has id set"); +mutateFired = false; +root.appendChild(nsx); +nsx.addEventListener("DOMAttrModified", function(e) { + nsx.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, nsx, "target is nsx"); + is(nsx.getAttribute("id"), null, "nsx no longer has id attr"); + removeNode(nsx); + is(nsx.parentNode, null, "nsx was removed"); + mutateFired = true; +}, false); +nsx.removeAttribute("id"); +ok(mutateFired, "mutation event fired"); + + +// Re-add the id inside a mutation event on a XML element +is($("ns_id"), null, "no nsx"); +is($("ns2_id"), null, "no nsx"); +nsx = document.createElementNS("urn:namespace", "ns:x"); +nsx.setAttribute("id", "ns_id"); +root.appendChild(nsx); +is($("ns_id"), nsx, "new nsx is set up"); +mutateFired = false; +nsx.addEventListener("DOMAttrModified", function(e) { + nsx.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, nsx, "target is nsx"); + is(nsx.getAttribute("id"), null, "nsx no longer has id attr"); + nsx.setAttribute("id", "other_id"); + mutateFired = true; +}, false); +nsx.removeAttribute("id"); +ok(mutateFired, "mutation event fired"); +is($("ns_id"), null, "ns_id was removed from table"); +is($("other_id"), nsx, "other_id was added"); +removeNode(nsx); +is($("other_id"), null, "other_id was removed"); + +// Re-add the id inside a mutation event on a HTML element +is($("div_id"), null, "no div"); +div = document.createElement("div"); +div.id = "div_id"; +root.appendChild(div); +is($("div_id"), div, "new div is set up"); +mutateFired = false; +div.addEventListener("DOMAttrModified", function(e) { + div.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, div, "target is div"); + is(div.getAttribute("id"), null, "div no longer has id attr"); + is(div.id, "", "div no longer has id"); + div.id = "other_div_id"; + mutateFired = true; +}, false); +div.removeAttribute("id"); +ok(mutateFired, "mutation event fired"); +is($("div_id"), null, "div_id was removed from table"); +is($("other_div_id"), div, "other_div_id was added"); +removeNode(div); +is($("other_div_id"), null, "other_div_id was removed"); + +// Re-add the id inside a mutation event on a XUL element +is($("xul_id"), null, "no xul"); +xul = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "button"); +xul.id = "xul_id"; +root.appendChild(xul); +is($("xul_id"), xul, "new xul is set up"); +mutateFired = false; +xul.addEventListener("DOMAttrModified", function(e) { + xul.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, xul, "target is xul"); + is(xul.getAttribute("id"), "", "xul no longer has id attr"); + is(xul.id, "", "xul no longer has id"); + xul.id = "other_xul_id"; + mutateFired = true; +}, false); +xul.removeAttribute("id"); +ok(mutateFired, "mutation event fired"); +is($("xul_id"), null, "xul_id was removed from table"); +is($("other_xul_id"), xul, "other_xul_id was added"); +removeNode(xul); +is($("other_xul_id"), null, "other_xul_id was removed"); + +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug567350.html b/dom/base/test/test_bug567350.html new file mode 100644 index 0000000000..14a8687af9 --- /dev/null +++ b/dom/base/test/test_bug567350.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=567350 +--> +<head> + <title>Test for Bug 567350</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=567350">Mozilla Bug 567350</a> +<p id="display"><span style="color: blue;"></span></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 567350 **/ +is(getComputedStyle(document.getElementById("display").firstChild).color, + "rgb(0, 0, 255)"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug574596.html b/dom/base/test/test_bug574596.html new file mode 100644 index 0000000000..0978f4333d --- /dev/null +++ b/dom/base/test/test_bug574596.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=574596 +--> +<head> + <title>Test for Bug 574596</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=574596">Mozilla Bug 574596</a> +<style type="text/css"> +#link1 a { -moz-user-select:none; } +</style> +<div id="link1"><a href="http://www.mozilla.org/">link1</a></div> +<div id="link2"><a href="http://www.mozilla.org/">link2</a></div> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 574596 **/ + +function ignoreFunc(actualData, expectedData) { + return true; +} + +var dragLinkText = [[ + { type:"text/x-moz-url", data:"", eqTest:ignoreFunc }, + { type:"text/x-moz-url-data", data:"http://www.mozilla.org/" }, + { type:"text/x-moz-url-desc", data:"link1" }, + { type:"text/uri-list", data:"http://www.mozilla.org/" }, + { type:"text/_moz_htmlcontext", data:"", eqTest:ignoreFunc }, + { type:"text/_moz_htmlinfo", data:"", eqTest:ignoreFunc }, + { type:"text/html", data:'<div id="link1"><a href="http://www.mozilla.org/">link1</a></div>' }, + { type:"text/plain", data:"http://www.mozilla.org/" } +]]; + + +function dumpTransfer(dataTransfer,expect) { + dtData = dataTransfer.mozItemCount + "items:\n"; + for (var i = 0; i < dataTransfer.mozItemCount; i++) { + var dtTypes = dataTransfer.mozTypesAt(i); + for (var j = 0; j < dtTypes.length; j++) { + var actualData = dataTransfer.mozGetDataAt(dtTypes[j],i) + if (expect && expect[i] && expect[i][j]) { + if (expect[i][j].eqTest) + dtData += expect[i][j].eqTest(actualData,expect[i][j].data) ? "ok" : "fail"; + else + dtData += (actualData == expect[i][j].data) ? "ok" : "fail"; + } + dtData += "["+i+"]" + "["+j+"]: " + '"' + dtTypes[j] + '" "' + actualData + '"\n'; + } + } + alert(dtData); +} + +function runTest() { + var result = synthesizeDragStart($('link1'), dragLinkText, window); + is(result, null, "Drag -moz-user-select:none link (#link1)"); + // if (result) dumpTransfer(result,dragLinkText); + + dragLinkText[0][2].data = "link2"; + dragLinkText[0][6].data = '<div id="link2"><a href="http://www.mozilla.org/">link2</a></div>' + var result = synthesizeDragStart($('link2'), dragLinkText, window); + is(result, null, "Drag link (#link2)"); + // if (result) dumpTransfer(result,dragLinkText); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(runTest); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug578096.html b/dom/base/test/test_bug578096.html new file mode 100644 index 0000000000..dd6c7fed12 --- /dev/null +++ b/dom/base/test/test_bug578096.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=578096 +--> +<head> + <title>Test for Bug 578096</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=578096">Mozilla Bug 578096</a> +<p id="display"></p> +<div id="content"> + <input type="file" id="file" onchange="fireXHR()"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var url = SimpleTest.getTestFileURL("bug578096LoadChromeScript.js"); +var script = SpecialPowers.loadChromeScript(url); + +script.addMessageListener("file.created", function (message) { + SpecialPowers.wrap(document.getElementById('file')).mozSetFileArray([message]); + + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function(event) { + if (xhr.readyState == 4) { + script.sendAsyncMessage("file.remove", {}); + } + } + + xhr.open('POST', window.location, true); + xhr.send(document.getElementById('file').files[0]); +}); + +script.addMessageListener("file.removed", function (message) { + ok(true, "We didn't throw! Yay!"); + script.destroy(); + SimpleTest.finish(); +}); + +script.sendAsyncMessage("file.create", {}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug585978.html b/dom/base/test/test_bug585978.html new file mode 100644 index 0000000000..5c63c0811f --- /dev/null +++ b/dom/base/test/test_bug585978.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=585978 +--> +<head> + <title>Test for Bug 585978</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=585978">Mozilla Bug 585978</a> + +<script type="application/javascript;version=1.7"> + +/* Test that if we have a unicode character in the middle of an ascii string, + the unicode character survives translation into and out of a text node. */ + +for (let i = 0; i < 128; i++) { + let node = document.createTextNode(''); + let str = ''; + for (let j = 0; j < i; j++) { + str += 'a'; + } + str += '\uA0A9' + node.data = str; + + for (let j = 0; j < 32; j++) { + is(node.data, str); + + str += 'b'; + node.appendData('b'); + } +} + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug587931.html b/dom/base/test/test_bug587931.html new file mode 100644 index 0000000000..7cef6938f5 --- /dev/null +++ b/dom/base/test/test_bug587931.html @@ -0,0 +1,102 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=587931 +--> +<head> + <title>Test for Bug 587931</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=587931">Mozilla Bug 587931</a> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 587931 **/ +SimpleTest.waitForExplicitFinish(); +var afterCount = 0; +var lastBeforeExecute = null; +var expectedCurrentScriptInAfterScriptExecute = null; +function verifyScript(n) { + var curr = document.currentScript; + is(curr, document.getElementById(n), "correct script (" + n + ")"); + is(lastBeforeExecute, curr, "correct beforescript (" + n + ")"); + document.addEventListener("afterscriptexecute", function(event) { + afterCount++; + lastBeforeExecute = null; + is(event.target, curr, "correct afterscript (" + n + ")"); + is(document.currentScript, expectedCurrentScriptInAfterScriptExecute, + "document.currentScript in afterscriptexecute(" + n + ")"); + document.removeEventListener("afterscriptexecute", arguments.callee, false); + }, false); +} +document.onbeforescriptexecute = function(event) { + lastBeforeExecute = event.target; +}; + +window.addEventListener("load", function() { + is(afterCount, 4, "correct number of afterscriptexecute"); + SimpleTest.finish(); +}, false); +</script> +</pre> +<!-- Test parser inserted scripts --> +<script id="parse-inline"> +verifyScript("parse-inline"); +</script> +<script id="parse-ext" src="data:text/plain,verifyScript('parse-ext');"></script> + +<!-- Test DOM inserted scripts --> +<script> +var s = document.createElement("script"); +s.textContent = "verifyScript('dom-inline');"; +s.id = "dom-inline"; +expectedCurrentScriptInAfterScriptExecute = document.currentScript; +document.body.appendChild(s); +expectedCurrentScriptInAfterScriptExecute = null; + +s = document.createElement("script"); +s.src = "data:text/plain,verifyScript('dom-ext');"; +s.id = "dom-ext"; +document.body.appendChild(s); +</script> + +<!-- Test cancel using beforescriptexecute --> +<script onbeforescriptexecute="return false;" + onafterescriptexecute="window.firedAfterScriptExecuteForCancel = true;"> +ok(false, "should have been canceled"); +</script> +<script> +isnot(window.firedAfterScriptExecuteForCancel, true, "onafterscriptexecute executed"); +</script> + +<!-- Test cancel using beforescriptexecute for external --> +<script onbeforescriptexecute="return false;" + onafterescriptexecute="window.extFiredAfterScriptExecuteForCancel = true;" + onload="window.extFiredLoadForCancel = true;" + src="data:text/plain,ok(false, 'should have been canceled');"> +</script> +<script> +isnot(window.extFiredAfterScriptExecuteForCancel, true, "onafterscriptexecute executed"); +is(extFiredLoadForCancel, true, "onload executed"); +</script> + +<!-- Test that all events fire --> +<script onbeforescriptexecute="window.beforeDidExecute = true;" + onafterscriptexecute="window.afterDidExecute = true;" + onload="window.loadDidExecute = true" + onerror="window.errorDidExecute = true" + src="data:text/plain, +is(window.beforeDidExecute, true, 'onbeforescriptexecute executed'); +isnot(window.afterDidExecute, true, 'onafterscriptexecute executed'); +isnot(window.loadDidExecute, true, 'onload executed'); +isnot(window.errorDidExecute, true, 'onerror executed'); +"> +</script> +<script> +is(afterDidExecute, true, "onafterscriptexecute executed"); +is(loadDidExecute, true, "onload executed"); +isnot(window.errorDidExecute, true, "onerror executed"); +</script> +</body> +</html> diff --git a/dom/base/test/test_bug588990.html b/dom/base/test/test_bug588990.html new file mode 100644 index 0000000000..087741a4de --- /dev/null +++ b/dom/base/test/test_bug588990.html @@ -0,0 +1,336 @@ +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=588990 +--> +<head> + <title>Test for Bug 588990</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=588990">Mozilla Bug 588990</a> +<!-- DOM to muck around with for tests --> +<p id="root"> +<img name="n1"> +<img name="n2"> +<img name="n2"> +<img name="n3"> +<img name="n3"> +<img name="n3"> +</p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +root = $('root'); +i1_1 = root.children[0]; +i2_1 = root.children[1]; +i2_2 = root.children[2]; +i3_1 = root.children[3]; +i3_2 = root.children[4]; +i3_3 = root.children[5]; + +function checkHasName(test) { + // Check name first to avoid flushes from hiding problems + checkHasNameNoDocProp(test); + + is(document.n1, i1_1, "i1_1 doc.name " + test); + is(document.n2[0], i2_1, "i2_1 doc.name " + test); + is(document.n2[1], i2_2, "i2_2 doc.name " + test); + is(document.n2.length, 2, "doc.name.length " + test); + is(document.n3[0], i3_1, "i3_1 doc.name " + test); + is(document.n3[1], i3_2, "i3_2 doc.name " + test); + is(document.n3[2], i3_3, "i3_3 doc.name " + test); + is(document.n3.length, 3, "doc.name.length " + test); +} + +function checkHasNameNoDocProp(test) { + is(i1_1.name, "n1", "i1_1 name " + test); + is(i2_1.name, "n2", "i2_1 name " + test); + is(i2_2.name, "n2", "i2_2 name " + test); + is(i3_1.name, "n3", "i3_1 name " + test); + is(i3_2.name, "n3", "i3_2 name " + test); + is(i3_3.name, "n3", "i3_3 name " + test); +} + +function checkHasNoName(removed, test) { + is(i1_1.name, "", "i1_1 name " + test); + is(i2_1.name, "", "i2_1 name " + test); + is(i2_2.name, "", "i2_2 name " + test); + is(i3_1.name, "", "i3_1 name " + test); + is(i3_2.name, "", "i3_2 name " + test); + is(i3_3.name, "", "i3_3 name " + test); + + var attrValue = removed ? null : ""; + is(i1_1.getAttribute("name"), attrValue, "i1_1 getAttribute " + test); + is(i2_1.getAttribute("name"), attrValue, "i2_1 getAttribute " + test); + is(i2_2.getAttribute("name"), attrValue, "i2_2 getAttribute " + test); + is(i3_1.getAttribute("name"), attrValue, "i3_1 getAttribute " + test); + is(i3_2.getAttribute("name"), attrValue, "i3_2 getAttribute " + test); + is(i3_3.getAttribute("name"), attrValue, "i3_3 getAttribute " + test); + + is(document.n1, undefined, "doc.n1 " + test); + is(document.n2, undefined, "doc.n2 " + test); + is(document.n3, undefined, "doc.n3 " + test); +} + +// Check that dynamic modifications of attribute work + +checkHasName("in markup"); + +i1_1.name = ""; +i2_1.name = ""; +i2_2.name = ""; +i3_1.name = ""; +i3_2.name = ""; +i3_3.name = ""; + +checkHasNoName(false, "set to empty"); + +i1_1.name = "n1"; +i2_1.name = "n2"; +i2_2.name = "n2"; +i3_1.name = "n3"; +i3_2.name = "n3"; +i3_3.name = "n3"; + +checkHasName("set using .name"); + +i1_1.setAttribute("name", ""); +i2_1.setAttribute("name", ""); +i2_2.setAttribute("name", ""); +i3_1.setAttribute("name", ""); +i3_2.setAttribute("name", ""); +i3_3.setAttribute("name", ""); + +checkHasNoName(false, "setAttribute to empty"); + +i1_1.name = "n1"; +i2_1.name = "n2"; +i2_2.name = "n2"; +i3_1.name = "n3"; +i3_2.name = "n3"; +i3_3.name = "n3"; + +checkHasName("set again using .name"); + +i1_1.removeAttribute("name"); +i2_1.removeAttribute("name"); +i2_2.removeAttribute("name"); +i3_1.removeAttribute("name"); +i3_2.removeAttribute("name"); +i3_3.removeAttribute("name"); + +checkHasNoName(true, "removed attribute"); + +i1_1.setAttribute("name", "n1"); +i2_1.setAttribute("name", "n2"); +i2_2.setAttribute("name", "n2"); +i3_1.setAttribute("name", "n3"); +i3_2.setAttribute("name", "n3"); +i3_3.setAttribute("name", "n3"); + +checkHasName("set using setAttribute"); + +t1 = document.createElement("img"); +t1.name = "n1"; +t2 = document.createElement("img"); +t2.name = "n2"; +t3 = document.createElement("img"); +t3.name = "n2"; +t4 = document.createElement("img"); +t4.name = "n3"; +t5 = document.createElement("img"); +t5.name = "n3"; +t6 = document.createElement("img"); +t6.name = "n3"; + +// Check that inserting elements before/after existing work + +function insertAfter(newChild, existing) { + existing.parentNode.insertBefore(newChild, existing.nextSibling); +} +function insertBefore(newChild, existing) { + existing.parentNode.insertBefore(newChild, existing); +} +function removeNode(child) { + child.parentNode.removeChild(child); +} + +insertAfter(t1, i1_1); +insertAfter(t2, i2_1); +insertAfter(t3, i2_2); +insertAfter(t4, i3_1); +insertAfter(t5, i3_2); +insertAfter(t6, i3_3); + +checkHasNameNoDocProp("inserted after"); +is(document.n1[0], i1_1, "i1_1 doc.name inserted after"); +is(document.n1[1], t1, "t1 doc.name inserted after"); +is(document.n1.length, 2, "doc.name1.length inserted after"); +is(document.n2[0], i2_1, "i2_1 doc.name inserted after"); +todo_is(document.n2[1], t2, "This is where t2 should show up. The elements in here should be in order-in-document rather than order-of-insertion"); +is(document.n2[1], i2_2, "i2_2 doc.name inserted after"); +is(document.n2[2], t2, "t2 doc.name inserted after"); +is(document.n2[3], t3, "t3 doc.name inserted after"); +is(document.n2.length, 4, "doc.name2.length inserted after"); +is(document.n3[0], i3_1, "i3_1 doc.name inserted after"); +is(document.n3[1], i3_2, "i3_3 doc.name inserted after"); +is(document.n3[2], i3_3, "i3_2 doc.name inserted after"); +is(document.n3[3], t4, "t4 doc.name inserted after"); +is(document.n3[4], t5, "t5 doc.name inserted after"); +is(document.n3[5], t6, "t6 doc.name inserted after"); +is(document.n3.length, 6, "doc.name3.length inserted after"); + + +insertBefore(t1, i1_1); +insertBefore(t2, i2_1); +insertBefore(t3, i2_2); +insertBefore(t4, i3_1); +insertBefore(t5, i3_2); +insertBefore(t6, i3_3); + +checkHasNameNoDocProp("inserted before"); +is(document.n1[0], i1_1, "i1_1 doc.name inserted before"); +is(document.n1[1], t1, "t1 doc.name inserted before"); +is(document.n1.length, 2, "doc.name1.length inserted before"); +is(document.n2[0], i2_1, "i2_1 doc.name inserted before"); +is(document.n2[1], i2_2, "i2_2 doc.name inserted before"); +is(document.n2[2], t2, "t2 doc.name inserted before"); +is(document.n2[3], t3, "t3 doc.name inserted before"); +is(document.n2.length, 4, "doc.name2.length inserted before"); +is(document.n3[0], i3_1, "i3_1 doc.name inserted before"); +is(document.n3[1], i3_2, "i3_3 doc.name inserted before"); +is(document.n3[2], i3_3, "i3_2 doc.name inserted before"); +is(document.n3[3], t4, "t4 doc.name inserted before"); +is(document.n3[4], t5, "t5 doc.name inserted before"); +is(document.n3[5], t6, "t6 doc.name inserted before"); +is(document.n3.length, 6, "doc.name3.length inserted before"); + +t1.removeAttribute("name"); +t2.removeAttribute("name"); +t3.removeAttribute("name"); +t4.removeAttribute("name"); +t5.removeAttribute("name"); +t6.removeAttribute("name"); + +checkHasName("removed tx attribute"); + +t1.setAttribute("name", "n1"); +t2.setAttribute("name", "n2"); +t3.setAttribute("name", "n2"); +t4.setAttribute("name", "n3"); +t5.setAttribute("name", "n3"); +t6.setAttribute("name", "n3"); + +checkHasNameNoDocProp("inserted before"); +is(document.n1[0], i1_1, "i1_1 doc.name inserted before"); +is(document.n1[1], t1, "t1 doc.name inserted before"); +is(document.n1.length, 2, "doc.name1.length inserted before"); +is(document.n2[0], i2_1, "i2_1 doc.name inserted before"); +is(document.n2[1], i2_2, "i2_2 doc.name inserted before"); +is(document.n2[2], t2, "t2 doc.name inserted before"); +is(document.n2[3], t3, "t3 doc.name inserted before"); +is(document.n2.length, 4, "doc.name2.length inserted before"); +is(document.n3[0], i3_1, "i3_1 doc.name inserted before"); +is(document.n3[1], i3_2, "i3_3 doc.name inserted before"); +is(document.n3[2], i3_3, "i3_2 doc.name inserted before"); +is(document.n3[3], t4, "t4 doc.name inserted before"); +is(document.n3[4], t5, "t5 doc.name inserted before"); +is(document.n3[5], t6, "t6 doc.name inserted before"); +is(document.n3.length, 6, "doc.name3.length inserted before"); + +removeNode(t1); +removeNode(t2); +removeNode(t3); +removeNode(t4); +removeNode(t5); +removeNode(t6); + +checkHasName("removed temporaries"); + +removeNode(i1_1); +removeNode(i2_1); +removeNode(i2_2); +removeNode(i3_1); +removeNode(i3_2); +removeNode(i3_3); + +checkHasNameNoDocProp("removed node"); + +// Check that removing an element during UnsetAttr works +is(i1_1.name, "n1", "i1_1 has name set"); +var mutateFired = false; +root.appendChild(i1_1); +i1_1.addEventListener("DOMAttrModified", function(e) { + i1_1.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, i1_1, "target is i1_1"); + is(i1_1.name, "", "i1_1 no longer has name"); + is(i1_1.getAttribute("name"), null, "i1_1 no longer has name attr"); + removeNode(i1_1); + is(i1_1.parentNode, null, "i1_1 was removed"); + mutateFired = true; +}, false); +i1_1.removeAttribute("name"); +ok(mutateFired, "mutation event fired"); +SpecialPowers.gc(); + +// Check that removing an element during SetAttr works +i2_1.name = ""; +mutateFired = false; +root.appendChild(i2_1); +i2_1.addEventListener("DOMAttrModified", function(e) { + i2_1.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, i2_1, "target is i2_1"); + is(i2_1.name, "n2", "i2_1 no longer has name"); + is(i2_1.getAttribute("name"), "n2", "i2_1 no longer has name attr"); + removeNode(i2_1); + is(i2_1.parentNode, null, "i2_1 was removed"); + mutateFired = true; +}, false); +i2_1.name = "n2"; +ok(mutateFired, "mutation event fired"); +SpecialPowers.gc(); + +// Re-add the name inside a mutation event on a HTML element +is(i2_2.name, "n2", "i2_2 has name set"); +root.appendChild(i2_2); +mutateFired = false; +root.appendChild(i2_2); +i2_2.addEventListener("DOMAttrModified", function(e) { + i2_2.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, i2_2, "target is i2_2"); + is(i2_2.name, "", "i2_2 no longer has name"); + is(i2_2.getAttribute("name"), "", "i2_2 has empty name attr"); + i2_2.name = "n2"; + mutateFired = true; +}, false); +i2_2.name = ""; +ok(mutateFired, "mutation event fired"); +is(document.n2, i2_2, "named was readded during mutation"); +removeNode(i2_2); +SpecialPowers.gc(); + +// Re-remove the name inside a mutation event on a HTML element +i3_1.name = ""; +root.appendChild(i3_1); +mutateFired = false; +root.appendChild(i3_1); +i3_1.addEventListener("DOMAttrModified", function(e) { + i3_1.removeEventListener("DOMAttrModified", arguments.callee, false); + is(e.target, i3_1, "target is i3_1"); + is(i3_1.name, "n3", "i3_1 no longer has name"); + is(i3_1.getAttribute("name"), "n3", "i3_1 has empty name attr"); + i3_1.removeAttribute("name"); + mutateFired = true; +}, false); +i3_1.name = "n3"; +ok(mutateFired, "mutation event fired"); +is(document.n3, undefined, "named was readded during mutation"); +removeNode(i3_1); +SpecialPowers.gc(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug590812.html b/dom/base/test/test_bug590812.html new file mode 100644 index 0000000000..834fa38f85 --- /dev/null +++ b/dom/base/test/test_bug590812.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for XML pretty printing, bug 590812</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=590812">Mozilla Bug 590812</a> +<p id="display"></p> +<iframe src="http://noxul.example.com/tests/dom/base/test/file_bug590812.xml"></iframe> +<iframe src="file_bug590812.xml"></iframe> +<iframe src="file_bug590812-ref.xhtml"></iframe> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +SimpleTest.waitForExplicitFinish(); + +function runTest() { + sNoXUL = snapshotWindow(window.frames[0], false); + sWithXUL = snapshotWindow(window.frames[1], false); + sRef = snapshotWindow(window.frames[2], false); + let res; + ok(compareSnapshots(sNoXUL, sRef, true)[0], + "noxul domain same as ref"); + ok(compareSnapshots(sWithXUL, sRef, true)[0], + "xul supporting domain same as ref"); + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug590870.html b/dom/base/test/test_bug590870.html new file mode 100644 index 0000000000..0faa2f4b60 --- /dev/null +++ b/dom/base/test/test_bug590870.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for creating XUL elements, bug 590870</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="gen.next()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=590870">Mozilla Bug 590870</a> +<p id="display"></p> +<iframe id=iframe></iframe> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +SimpleTest.waitForExplicitFinish(); +window.addEventListener("message", function(e) { gen.send(e.data) }, false); + +var gen = runTest(); + +function runTest() { + var iframe = $('iframe'); + iframe.src = "http://noxul.example.com/tests/dom/base/test/file_bug590870.html"; + is((yield), true, "shouldn't be able to create XUL elements"); + + iframe.src = "file_bug590870.html"; + is((yield), false, "should be able to create XUL elements"); + + SimpleTest.finish(); + yield undefined; +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug592366.html b/dom/base/test/test_bug592366.html new file mode 100644 index 0000000000..1269c4250b --- /dev/null +++ b/dom/base/test/test_bug592366.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=592366 +--> +<head> + <title>Test for Bug 592366</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=592366">Mozilla Bug 592366</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe></iframe> +<iframe></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 592366 **/ + +var gExecuted = false; + +function hitEventLoop(times, next) +{ + if (times == 0) { + next(); + return; + } + + SimpleTest.executeSoon(function() { + hitEventLoop(times - 1, next); + }); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + var s = document.createElement("script"); + s.src = "data:text/javascript,parent.gExecuted=true;"; + + var iframes = document.getElementsByTagName("iframe"); + + iframes[0].contentDocument.body.appendChild(s); + iframes[1].contentDocument.body.appendChild(s); + + // It seems to work with 1 event loop hit locally but using 2 given that it + // was hsivonen advice. + hitEventLoop(2, function() { + ok(!gExecuted, "The scripts should not have been executed"); + SimpleTest.finish(); + }); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug592829.html b/dom/base/test/test_bug592829.html new file mode 100644 index 0000000000..8163058491 --- /dev/null +++ b/dom/base/test/test_bug592829.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=592829 +--> +<head> + <title>Test for Bug 592829</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=592829">Mozilla Bug 592829</a> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 592829 **/ + +// NOTE! It's imperative that we don't call .init() here. Otherwise we're not +// testing what happens if parsing fails. +// If we ever change how DOMParser initilization works, just update this code +// to create a DOMParser which is not allowed to parse XUL. + +var isXUL = true; +try { + var x = + SpecialPowers.Cc + .getService(Components.interfaces.nsIDOMParser) + .parseFromString('<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>', "text/xml"); + isXUL = x.documentElement.namespaceURI == + "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; +} +catch (ex) { + isXUL = false; +} + +is(isXUL, false, "We didn't create XUL and we didn't crash!"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug597345.html b/dom/base/test/test_bug597345.html new file mode 100644 index 0000000000..1eb0bb6a2c --- /dev/null +++ b/dom/base/test/test_bug597345.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=597345 +--> +<head> + <title>Test for Bug 597345</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=597345">Mozilla Bug 597345</a> +<pre id="test"> + <!-- We want no spaces inside span id="target". The 'stray' close comment at + the end of that span needs to be there! --> + <span id="target"><script + src="script-1_bug597345.sjs"></script><script + charset="ISO-5559-1" src="script-2_bug597345.js"></script>--></span> +<script type="application/javascript"> + +/** Test for Bug 597345 **/ +is($("target").textContent, "R\u00e4ksm\u00f6rg\u00e5s", + "script-2 should be decoded as UTF-8"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug599295.html b/dom/base/test/test_bug599295.html new file mode 100644 index 0000000000..4cfb0d0679 --- /dev/null +++ b/dom/base/test/test_bug599295.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=599295 +--> +<head> + <title>Test for Bug 599295</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=599295">Mozilla Bug 599295</a> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 599295 **/ + +/* Do not allow a response to a CONNECT method, used to establish an + SSL tunnel over an HTTP proxy, to contain a redirect */ + +function runTest() { + /* Previously, necko would allow a 302 as part of a CONNECT response + if the LOAD_DOCUMENT_URI flag was set and the original document + URI had not yet been changed. */ + + SpecialPowers.loadChannelAndReturnStatus("https://redirproxy.example.com/test", + true) + .then(function({status, httpStatus}) { + /* testing here that the redirect was not followed. If it was followed + we would see a http status of 200 and status of NS_OK */ + + is(httpStatus, 302, "http status 302"); + is(status, SpecialPowers.Cr.NS_ERROR_CONNECTION_REFUSED, + "raised refused"); + SimpleTest.finish(); + }); +} + +SimpleTest.waitForExplicitFinish(); +SimpleTest.waitForFocus(runTest); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug599588.html b/dom/base/test/test_bug599588.html new file mode 100644 index 0000000000..a94490e7a2 --- /dev/null +++ b/dom/base/test/test_bug599588.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=599588 +--> +<head> + <title>Test for Bug 599588</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=599588">Mozilla Bug 599588</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Test for Bug 599588 **/ + +var div = document.createElement("div"); +div.innerHTML = "\u003Cscript>ok(false, 'Scripts created by innerHTML should not run.');\u003C/script>"; +document.body.appendChild(div); + +var contextualFragmentRan = false; + +var range = document.createRange(); +range.selectNode(document.body); +var fragment = range.createContextualFragment("\u003Cscript>contextualFragmentRan = true;\u003C/script>"); +document.body.appendChild(fragment); + +ok(contextualFragmentRan, "Script from createContextualFragment should have run."); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug601803.html b/dom/base/test/test_bug601803.html new file mode 100644 index 0000000000..cbc15a22c3 --- /dev/null +++ b/dom/base/test/test_bug601803.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=601803 +--> +<head> + <title>Test for Bug 601803</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=601803">Mozilla Bug 601803</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe id="frame"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 601803 **/ +SimpleTest.waitForExplicitFinish(); + +window.onmessage = function (event) { + is(event.data, false, "Shouldn't throw when adopting a node cross-compartment"); + SimpleTest.finish(); +} + +document.getElementById("frame").src = "http://example.org/tests/dom/base/test/file_bug601803a.html"; + + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug602838.html b/dom/base/test/test_bug602838.html new file mode 100644 index 0000000000..611d81136a --- /dev/null +++ b/dom/base/test/test_bug602838.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=602838 +--> +<head> + <title>Test for Bug 602838</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=602838">Mozilla Bug 602838</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script id=withasync async></script> +<script id=withoutasync></script> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 602838 **/ +SimpleTest.waitForExplicitFinish(); +var firstRan = false; +var asyncRan = false; + +var withoutasync = document.getElementById("withoutasync"); +ok(withoutasync.async, "When a script loses parser-insertedness, it should become async."); + +var withasync = document.getElementById("withasync"); +ok(withasync.async, "A script with the async content attribute should have the DOM attribute reporting true."); +withasync.removeAttribute("async"); +ok(!withasync.async, "Should be able to remove asyncness from a script that had the async content attribute when losing parser-insertedness by removing the content attribute."); + +var s = document.createElement("script"); +ok(s.async, "Script-created scripts should default to .async=true"); +ok(!s.hasAttribute("async"), "Script-created scripts should not have the async content attribute by default."); +s.removeAttribute("async"); +ok(s.async, "Removing a non-existing content-attribute should not have an effect on the forced async DOM property."); +s.setAttribute("async", ""); +ok(s.async, "The async DOM property should still be true."); +s.removeAttribute("async"); +ok(!s.async, "When a previously present async content attribute is removed, the DOM property should become false."); +s.src = "script_bug602838.sjs"; +document.body.appendChild(s); + +s = document.createElement("script"); +s.src = "data:text/javascript,ok(firstRan, 'The first script should have run'); SimpleTest.finish();"; +s.async = false; +ok(!s.async, "Setting the async DOM property to false should turned of forcing async to true."); +document.body.appendChild(s); + +function unblock() { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "script_bug602838.sjs?unblock"); + xhr.send(); +} + +s = document.createElement("script"); +s.src = "data:text/javascript,ok(!firstRan, 'Non-async should not have run yet.'); asyncRan = true; unblock();"; +document.body.appendChild(s); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug604592.html b/dom/base/test/test_bug604592.html new file mode 100644 index 0000000000..0441f7f148 --- /dev/null +++ b/dom/base/test/test_bug604592.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=604592 +--> +<head> + <title>Test for Bug 604592</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=604592">Mozilla Bug 604592</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 604592 **/ +function testInStrictMode() { + "use strict"; + try { + document.body.prefix = "foo"; + ok(false, "Should not have reached this point"); + } catch (e) { + ok(e instanceof TypeError, "Expected a TypeError"); + } +} + +testInStrictMode(); +document.body.prefix = "foo"; +ok(document.body.prefix === null, + "Expected strictly equal to null, got " + document.body.prefix); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug604660.html b/dom/base/test/test_bug604660.html new file mode 100644 index 0000000000..0008c2dd56 --- /dev/null +++ b/dom/base/test/test_bug604660.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=604660 +--> +<head> + <title>Test for Bug 604660</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=604660">Mozilla Bug 604660</a> +<script> +SimpleTest.waitForExplicitFinish(); +var asyncState = false; +var scriptState = 0; + +function scriptRan(num) { + ++scriptState; + is(scriptState, num, "Scripts ran in the wrong sequence."); +} + +function asyncRan() { + asyncState = true; +} + +</script> +<p id="display"><iframe src="file_bug604660-1.xml" onload="iframeloaded()";></iframe></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var xlstProcessorState = false; + +function xsltProcessorCreatedScriptRan() { + xlstProcessorState = true; +} + +function iframeloaded() { + ok(asyncState, "Async script should have run."); + is(scriptState, 5, "Five scripts should have run."); + + var processor = new XSLTProcessor(); + + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + processor.importStylesheet(this.responseXML); + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + var doc = processor.transformToDocument(this.responseXML); + var target = document.getElementById("display"); + target.appendChild(doc.documentElement.firstChild); + ok(!xlstProcessorState, "Scripts created by transformToDocument should not run."); + + var fragment = processor.transformToFragment(this.responseXML, document); + target.appendChild(fragment.firstChild.firstChild); + ok(xlstProcessorState, "Scripts created by transformToFragment should run."); + + SimpleTest.finish(); + } + } + xhr.open("GET", "file_bug604660-5.xml"); + xhr.send(); + } + } + xhr.open("GET", "file_bug604660-6.xsl"); + xhr.send(); +} +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug605982.html b/dom/base/test/test_bug605982.html new file mode 100644 index 0000000000..ad1f95fe10 --- /dev/null +++ b/dom/base/test/test_bug605982.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=605982 +--> +<head> + <title>Test for Bug 605982</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=605982">Mozilla Bug 605982</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 605982 **/ + +var elmt = document.createElement("div"); + +var caught = false; +try { + elmt.matches("!!"); +} catch(e) { + ok(e.name == "SyntaxError", "Error should be SyntaxError"); + ok(e.code == DOMException.SYNTAX_ERR, "Error code should be SYNTAX_ERR"); + caught = true; +} +ok(caught, "An exception should have been thrown"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug606729.html b/dom/base/test/test_bug606729.html new file mode 100644 index 0000000000..46fa4443e5 --- /dev/null +++ b/dom/base/test/test_bug606729.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=606729 +--> +<head> + <title>Test for Bug 606729</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=606729">Mozilla Bug 606729</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script> + SimpleTest.waitForExplicitFinish(); + var events = 0; + var expectedEvents = 2; + function eventFired() { + ++events; + if (events == expectedEvents) { + SimpleTest.finish(); + } + } +</script> +<script + src="data:" + onerror="ok(true, 'Script with src=data: should fire onerror.'); + eventFired();" + onload="ok(false, 'Script with src=data: should not fire onload.'); + eventFired();" +> +ok(false, "Script with src=data: should not run textContent."); +</script> +<script + src="bogus:" + onerror="ok(true, 'Script with src=bogus: should fire onerror.'); + eventFired();" + onload="ok(false, 'Script with src=bogus: should not fire onload.'); + eventFired();" +> +ok(false, "Script with src=bogus: should not run textContent."); +</script> +</pre> +</body> +</html> + + diff --git a/dom/base/test/test_bug614058.html b/dom/base/test/test_bug614058.html new file mode 100644 index 0000000000..3ae136d7f3 --- /dev/null +++ b/dom/base/test/test_bug614058.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=614058 +--> +<head> + <title>Test for Bug 614058</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=614058">Mozilla Bug 614058</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 614058 **/ +var f1 = document.createDocumentFragment(); +f2 = f1.cloneNode(true); +f1.appendChild(document.createElement("foo")); +is(f1.isEqualNode(f2), false, "Fragments have different kids!"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug614583.html b/dom/base/test/test_bug614583.html new file mode 100644 index 0000000000..866aa17521 --- /dev/null +++ b/dom/base/test/test_bug614583.html @@ -0,0 +1,261 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=614583 +--> +<head> + <title>Test for Bug 614583</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=614583">Mozilla Bug 614583</a> +<span id="crash1" +attr0 attr1 attr2 attr3 attr4 attr5 attr6 attr7 attr8 attr9 +attr10 attr11 attr12 attr13 attr14 attr15 attr16 attr17 attr18 attr19 +attr20 attr21 attr22 attr23 attr24 attr25 attr26 attr27 attr28 attr29 +attr30 attr31 attr32 attr33 attr34 attr35 attr36 attr37 attr38 attr39 +attr40 attr41 attr42 attr43 attr44 attr45 attr46 attr47 attr48 attr49 +attr50 attr51 attr52 attr53 attr54 attr55 attr56 attr57 attr58 attr59 +attr60 attr61 attr62 attr63 attr64 attr65 attr66 attr67 attr68 attr69 +attr70 attr71 attr72 attr73 attr74 attr75 attr76 attr77 attr78 attr79 +attr80 attr81 attr82 attr83 attr84 attr85 attr86 attr87 attr88 attr89 +attr90 attr91 attr92 attr93 attr94 attr95 attr96 attr97 attr98 attr99 +attr100 attr101 attr102 attr103 attr104 attr105 attr106 attr107 attr108 attr109 +attr110 attr111 attr112 attr113 attr114 attr115 attr116 attr117 attr118 attr119 +attr120 attr121 attr122 attr123 attr124 attr125 attr126 attr127 attr128 attr129 +attr130 attr131 attr132 attr133 attr134 attr135 attr136 attr137 attr138 attr139 +attr140 attr141 attr142 attr143 attr144 attr145 attr146 attr147 attr148 attr149 +attr150 attr151 attr152 attr153 attr154 attr155 attr156 attr157 attr158 attr159 +attr160 attr161 attr162 attr163 attr164 attr165 attr166 attr167 attr168 attr169 +attr170 attr171 attr172 attr173 attr174 attr175 attr176 attr177 attr178 attr179 +attr180 attr181 attr182 attr183 attr184 attr185 attr186 attr187 attr188 attr189 +attr190 attr191 attr192 attr193 attr194 attr195 attr196 attr197 attr198 attr199 +attr200 attr201 attr202 attr203 attr204 attr205 attr206 attr207 attr208 attr209 +attr210 attr211 attr212 attr213 attr214 attr215 attr216 attr217 attr218 attr219 +attr220 attr221 attr222 attr223 attr224 attr225 attr226 attr227 attr228 attr229 +attr230 attr231 attr232 attr233 attr234 attr235 attr236 attr237 attr238 attr239 +attr240 attr241 attr242 attr243 attr244 attr245 attr246 attr247 attr248 attr249 +attr250 attr251 attr252 attr253 attr254 attr255 attr256 attr257 attr258 attr259 +attr260 attr261 attr262 attr263 attr264 attr265 attr266 attr267 attr268 attr269 +attr270 attr271 attr272 attr273 attr274 attr275 attr276 attr277 attr278 attr279 +attr280 attr281 attr282 attr283 attr284 attr285 attr286 attr287 attr288 attr289 +attr290 attr291 attr292 attr293 attr294 attr295 attr296 attr297 attr298 attr299 +attr300 attr301 attr302 attr303 attr304 attr305 attr306 attr307 attr308 attr309 +attr310 attr311 attr312 attr313 attr314 attr315 attr316 attr317 attr318 attr319 +attr320 attr321 attr322 attr323 attr324 attr325 attr326 attr327 attr328 attr329 +attr330 attr331 attr332 attr333 attr334 attr335 attr336 attr337 attr338 attr339 +attr340 attr341 attr342 attr343 attr344 attr345 attr346 attr347 attr348 attr349 +attr350 attr351 attr352 attr353 attr354 attr355 attr356 attr357 attr358 attr359 +attr360 attr361 attr362 attr363 attr364 attr365 attr366 attr367 attr368 attr369 +attr370 attr371 attr372 attr373 attr374 attr375 attr376 attr377 attr378 attr379 +attr380 attr381 attr382 attr383 attr384 attr385 attr386 attr387 attr388 attr389 +attr390 attr391 attr392 attr393 attr394 attr395 attr396 attr397 attr398 attr399 +attr400 attr401 attr402 attr403 attr404 attr405 attr406 attr407 attr408 attr409 +attr410 attr411 attr412 attr413 attr414 attr415 attr416 attr417 attr418 attr419 +attr420 attr421 attr422 attr423 attr424 attr425 attr426 attr427 attr428 attr429 +attr430 attr431 attr432 attr433 attr434 attr435 attr436 attr437 attr438 attr439 +attr440 attr441 attr442 attr443 attr444 attr445 attr446 attr447 attr448 attr449 +attr450 attr451 attr452 attr453 attr454 attr455 attr456 attr457 attr458 attr459 +attr460 attr461 attr462 attr463 attr464 attr465 attr466 attr467 attr468 attr469 +attr470 attr471 attr472 attr473 attr474 attr475 attr476 attr477 attr478 attr479 +attr480 attr481 attr482 attr483 attr484 attr485 attr486 attr487 attr488 attr489 +attr490 attr491 attr492 attr493 attr494 attr495 attr496 attr497 attr498 attr499 +attr500 attr501 attr502 attr503 attr504 attr505 attr506 attr507 attr508 attr509 +attr510 attr511 attr512 attr513 attr514 attr515 attr516 attr517 attr518 attr519 +attr520 attr521 attr522 attr523 attr524 attr525 attr526 attr527 attr528 attr529 +attr530 attr531 attr532 attr533 attr534 attr535 attr536 attr537 attr538 attr539 +attr540 attr541 attr542 attr543 attr544 attr545 attr546 attr547 attr548 attr549 +attr550 attr551 attr552 attr553 attr554 attr555 attr556 attr557 attr558 attr559 +attr560 attr561 attr562 attr563 attr564 attr565 attr566 attr567 attr568 attr569 +attr570 attr571 attr572 attr573 attr574 attr575 attr576 attr577 attr578 attr579 +attr580 attr581 attr582 attr583 attr584 attr585 attr586 attr587 attr588 attr589 +attr590 attr591 attr592 attr593 attr594 attr595 attr596 attr597 attr598 attr599 +attr600 attr601 attr602 attr603 attr604 attr605 attr606 attr607 attr608 attr609 +attr610 attr611 attr612 attr613 attr614 attr615 attr616 attr617 attr618 attr619 +attr620 attr621 attr622 attr623 attr624 attr625 attr626 attr627 attr628 attr629 +attr630 attr631 attr632 attr633 attr634 attr635 attr636 attr637 attr638 attr639 +attr640 attr641 attr642 attr643 attr644 attr645 attr646 attr647 attr648 attr649 +attr650 attr651 attr652 attr653 attr654 attr655 attr656 attr657 attr658 attr659 +attr660 attr661 attr662 attr663 attr664 attr665 attr666 attr667 attr668 attr669 +attr670 attr671 attr672 attr673 attr674 attr675 attr676 attr677 attr678 attr679 +attr680 attr681 attr682 attr683 attr684 attr685 attr686 attr687 attr688 attr689 +attr690 attr691 attr692 attr693 attr694 attr695 attr696 attr697 attr698 attr699 +attr700 attr701 attr702 attr703 attr704 attr705 attr706 attr707 attr708 attr709 +attr710 attr711 attr712 attr713 attr714 attr715 attr716 attr717 attr718 attr719 +attr720 attr721 attr722 attr723 attr724 attr725 attr726 attr727 attr728 attr729 +attr730 attr731 attr732 attr733 attr734 attr735 attr736 attr737 attr738 attr739 +attr740 attr741 attr742 attr743 attr744 attr745 attr746 attr747 attr748 attr749 +attr750 attr751 attr752 attr753 attr754 attr755 attr756 attr757 attr758 attr759 +attr760 attr761 attr762 attr763 attr764 attr765 attr766 attr767 attr768 attr769 +attr770 attr771 attr772 attr773 attr774 attr775 attr776 attr777 attr778 attr779 +attr780 attr781 attr782 attr783 attr784 attr785 attr786 attr787 attr788 attr789 +attr790 attr791 attr792 attr793 attr794 attr795 attr796 attr797 attr798 attr799 +attr800 attr801 attr802 attr803 attr804 attr805 attr806 attr807 attr808 attr809 +attr810 attr811 attr812 attr813 attr814 attr815 attr816 attr817 attr818 attr819 +attr820 attr821 attr822 attr823 attr824 attr825 attr826 attr827 attr828 attr829 +attr830 attr831 attr832 attr833 attr834 attr835 attr836 attr837 attr838 attr839 +attr840 attr841 attr842 attr843 attr844 attr845 attr846 attr847 attr848 attr849 +attr850 attr851 attr852 attr853 attr854 attr855 attr856 attr857 attr858 attr859 +attr860 attr861 attr862 attr863 attr864 attr865 attr866 attr867 attr868 attr869 +attr870 attr871 attr872 attr873 attr874 attr875 attr876 attr877 attr878 attr879 +attr880 attr881 attr882 attr883 attr884 attr885 attr886 attr887 attr888 attr889 +attr890 attr891 attr892 attr893 attr894 attr895 attr896 attr897 attr898 attr899 +attr900 attr901 attr902 attr903 attr904 attr905 attr906 attr907 attr908 attr909 +attr910 attr911 attr912 attr913 attr914 attr915 attr916 attr917 attr918 attr919 +attr920 attr921 attr922 attr923 attr924 attr925 attr926 attr927 attr928 attr929 +attr930 attr931 attr932 attr933 attr934 attr935 attr936 attr937 attr938 attr939 +attr940 attr941 attr942 attr943 attr944 attr945 attr946 attr947 attr948 attr949 +attr950 attr951 attr952 attr953 attr954 attr955 attr956 attr957 attr958 attr959 +attr960 attr961 attr962 attr963 attr964 attr965 attr966 attr967 attr968 attr969 +attr970 attr971 attr972 attr973 attr974 attr975 attr976 attr977 attr978 attr979 +attr980 attr981 attr982 attr983 attr984 attr985 attr986 attr987 attr988 attr989 +attr990 attr991 attr992 attr993 attr994 attr995 attr996 attr997 attr998 attr999 +attr1000 attr1001 attr1002 attr1003 attr1004 attr1005 attr1006 attr1007 attr1008 attr1009 +attr1010 attr1011 attr1012 attr1013 attr1014 attr1015 attr1016 attr1017 attr1018 attr1019 +attr1020 attr1021 attr1022 attr1023 attr1024 attr1025 attr1026 attr1027 attr1028 attr1029 +attr1030 attr1031 attr1032 attr1033 attr1034 attr1035 attr1036 attr1037 attr1038 attr1039 +attr1040 attr1041 attr1042 attr1043 attr1044 attr1045 attr1046 attr1047 attr1048 attr1049 +attr1050 attr1051 attr1052 attr1053 attr1054 attr1055 attr1056 attr1057 attr1058 attr1059 +attr1060 attr1061 attr1062 attr1063 attr1064 attr1065 attr1066 attr1067 attr1068 attr1069 +attr1070 attr1071 attr1072 attr1073 attr1074 attr1075 attr1076 attr1077 attr1078 attr1079 +attr1080 attr1081 attr1082 attr1083 attr1084 attr1085 attr1086 attr1087 attr1088 attr1089 +attr1090 attr1091 attr1092 attr1093 attr1094 attr1095 attr1096 attr1097 attr1098 attr1099 +>I'm on a boat</span> +<span +attr0 attr1 attr2 attr3 attr4 attr5 attr6 attr7 attr8 attr9 +attr10 attr11 attr12 attr13 attr14 attr15 attr16 attr17 attr18 attr19 +attr20 attr21 attr22 attr23 attr24 attr25 attr26 attr27 attr28 attr29 +attr30 attr31 attr32 attr33 attr34 attr35 attr36 attr37 attr38 attr39 +attr40 attr41 attr42 attr43 attr44 attr45 attr46 attr47 attr48 attr49 +attr50 attr51 attr52 attr53 attr54 attr55 attr56 attr57 attr58 attr59 +attr60 attr61 attr62 attr63 attr64 attr65 attr66 attr67 attr68 attr69 +attr70 attr71 attr72 attr73 attr74 attr75 attr76 attr77 attr78 attr79 +attr80 attr81 attr82 attr83 attr84 attr85 attr86 attr87 attr88 attr89 +attr90 attr91 attr92 attr93 attr94 attr95 attr96 attr97 attr98 attr99 +attr100 attr101 attr102 attr103 attr104 attr105 attr106 attr107 attr108 attr109 +attr110 attr111 attr112 attr113 attr114 attr115 attr116 attr117 attr118 attr119 +attr120 attr121 attr122 attr123 attr124 attr125 attr126 attr127 attr128 attr129 +attr130 attr131 attr132 attr133 attr134 attr135 attr136 attr137 attr138 attr139 +attr140 attr141 attr142 attr143 attr144 attr145 attr146 attr147 attr148 attr149 +attr150 attr151 attr152 attr153 attr154 attr155 attr156 attr157 attr158 attr159 +attr160 attr161 attr162 attr163 attr164 attr165 attr166 attr167 attr168 attr169 +attr170 attr171 attr172 attr173 attr174 attr175 attr176 attr177 attr178 attr179 +attr180 attr181 attr182 attr183 attr184 attr185 attr186 attr187 attr188 attr189 +attr190 attr191 attr192 attr193 attr194 attr195 attr196 attr197 attr198 attr199 +attr200 attr201 attr202 attr203 attr204 attr205 attr206 attr207 attr208 attr209 +attr210 attr211 attr212 attr213 attr214 attr215 attr216 attr217 attr218 attr219 +attr220 attr221 attr222 attr223 attr224 attr225 attr226 attr227 attr228 attr229 +attr230 attr231 attr232 attr233 attr234 attr235 attr236 attr237 attr238 attr239 +attr240 attr241 attr242 attr243 attr244 attr245 attr246 attr247 attr248 attr249 +attr250 attr251 attr252 attr253 attr254 attr255 attr256 attr257 attr258 attr259 +attr260 attr261 attr262 attr263 attr264 attr265 attr266 attr267 attr268 attr269 +attr270 attr271 attr272 attr273 attr274 attr275 attr276 attr277 attr278 attr279 +attr280 attr281 attr282 attr283 attr284 attr285 attr286 attr287 attr288 attr289 +attr290 attr291 attr292 attr293 attr294 attr295 attr296 attr297 attr298 attr299 +attr300 attr301 attr302 attr303 attr304 attr305 attr306 attr307 attr308 attr309 +attr310 attr311 attr312 attr313 attr314 attr315 attr316 attr317 attr318 attr319 +attr320 attr321 attr322 attr323 attr324 attr325 attr326 attr327 attr328 attr329 +attr330 attr331 attr332 attr333 attr334 attr335 attr336 attr337 attr338 attr339 +attr340 attr341 attr342 attr343 attr344 attr345 attr346 attr347 attr348 attr349 +attr350 attr351 attr352 attr353 attr354 attr355 attr356 attr357 attr358 attr359 +attr360 attr361 attr362 attr363 attr364 attr365 attr366 attr367 attr368 attr369 +attr370 attr371 attr372 attr373 attr374 attr375 attr376 attr377 attr378 attr379 +attr380 attr381 attr382 attr383 attr384 attr385 attr386 attr387 attr388 attr389 +attr390 attr391 attr392 attr393 attr394 attr395 attr396 attr397 attr398 attr399 +attr400 attr401 attr402 attr403 attr404 attr405 attr406 attr407 attr408 attr409 +attr410 attr411 attr412 attr413 attr414 attr415 attr416 attr417 attr418 attr419 +attr420 attr421 attr422 attr423 attr424 attr425 attr426 attr427 attr428 attr429 +attr430 attr431 attr432 attr433 attr434 attr435 attr436 attr437 attr438 attr439 +attr440 attr441 attr442 attr443 attr444 attr445 attr446 attr447 attr448 attr449 +attr450 attr451 attr452 attr453 attr454 attr455 attr456 attr457 attr458 attr459 +attr460 attr461 attr462 attr463 attr464 attr465 attr466 attr467 attr468 attr469 +attr470 attr471 attr472 attr473 attr474 attr475 attr476 attr477 attr478 attr479 +attr480 attr481 attr482 attr483 attr484 attr485 attr486 attr487 attr488 attr489 +attr490 attr491 attr492 attr493 attr494 attr495 attr496 attr497 attr498 attr499 +attr500 attr501 attr502 attr503 attr504 attr505 attr506 attr507 attr508 attr509 +attr510 attr511 attr512 attr513 attr514 attr515 attr516 attr517 attr518 attr519 +attr520 attr521 attr522 attr523 attr524 attr525 attr526 attr527 attr528 attr529 +attr530 attr531 attr532 attr533 attr534 attr535 attr536 attr537 attr538 attr539 +attr540 attr541 attr542 attr543 attr544 attr545 attr546 attr547 attr548 attr549 +attr550 attr551 attr552 attr553 attr554 attr555 attr556 attr557 attr558 attr559 +attr560 attr561 attr562 attr563 attr564 attr565 attr566 attr567 attr568 attr569 +attr570 attr571 attr572 attr573 attr574 attr575 attr576 attr577 attr578 attr579 +attr580 attr581 attr582 attr583 attr584 attr585 attr586 attr587 attr588 attr589 +attr590 attr591 attr592 attr593 attr594 attr595 attr596 attr597 attr598 attr599 +attr600 attr601 attr602 attr603 attr604 attr605 attr606 attr607 attr608 attr609 +attr610 attr611 attr612 attr613 attr614 attr615 attr616 attr617 attr618 attr619 +attr620 attr621 attr622 attr623 attr624 attr625 attr626 attr627 attr628 attr629 +attr630 attr631 attr632 attr633 attr634 attr635 attr636 attr637 attr638 attr639 +attr640 attr641 attr642 attr643 attr644 attr645 attr646 attr647 attr648 attr649 +attr650 attr651 attr652 attr653 attr654 attr655 attr656 attr657 attr658 attr659 +attr660 attr661 attr662 attr663 attr664 attr665 attr666 attr667 attr668 attr669 +attr670 attr671 attr672 attr673 attr674 attr675 attr676 attr677 attr678 attr679 +attr680 attr681 attr682 attr683 attr684 attr685 attr686 attr687 attr688 attr689 +attr690 attr691 attr692 attr693 attr694 attr695 attr696 attr697 attr698 attr699 +attr700 attr701 attr702 attr703 attr704 attr705 attr706 attr707 attr708 attr709 +attr710 attr711 attr712 attr713 attr714 attr715 attr716 attr717 attr718 attr719 +attr720 attr721 attr722 attr723 attr724 attr725 attr726 attr727 attr728 attr729 +attr730 attr731 attr732 attr733 attr734 attr735 attr736 attr737 attr738 attr739 +attr740 attr741 attr742 attr743 attr744 attr745 attr746 attr747 attr748 attr749 +attr750 attr751 attr752 attr753 attr754 attr755 attr756 attr757 attr758 attr759 +attr760 attr761 attr762 attr763 attr764 attr765 attr766 attr767 attr768 attr769 +attr770 attr771 attr772 attr773 attr774 attr775 attr776 attr777 attr778 attr779 +attr780 attr781 attr782 attr783 attr784 attr785 attr786 attr787 attr788 attr789 +attr790 attr791 attr792 attr793 attr794 attr795 attr796 attr797 attr798 attr799 +attr800 attr801 attr802 attr803 attr804 attr805 attr806 attr807 attr808 attr809 +attr810 attr811 attr812 attr813 attr814 attr815 attr816 attr817 attr818 attr819 +attr820 attr821 attr822 attr823 attr824 attr825 attr826 attr827 attr828 attr829 +attr830 attr831 attr832 attr833 attr834 attr835 attr836 attr837 attr838 attr839 +attr840 attr841 attr842 attr843 attr844 attr845 attr846 attr847 attr848 attr849 +attr850 attr851 attr852 attr853 attr854 attr855 attr856 attr857 attr858 attr859 +attr860 attr861 attr862 attr863 attr864 attr865 attr866 attr867 attr868 attr869 +attr870 attr871 attr872 attr873 attr874 attr875 attr876 attr877 attr878 attr879 +attr880 attr881 attr882 attr883 attr884 attr885 attr886 attr887 attr888 attr889 +attr890 attr891 attr892 attr893 attr894 attr895 attr896 attr897 attr898 attr899 +attr900 attr901 attr902 attr903 attr904 attr905 attr906 attr907 attr908 attr909 +attr910 attr911 attr912 attr913 attr914 attr915 attr916 attr917 attr918 attr919 +attr920 attr921 attr922 attr923 attr924 attr925 attr926 attr927 attr928 attr929 +attr930 attr931 attr932 attr933 attr934 attr935 attr936 attr937 attr938 attr939 +attr940 attr941 attr942 attr943 attr944 attr945 attr946 attr947 attr948 attr949 +attr950 attr951 attr952 attr953 attr954 attr955 attr956 attr957 attr958 attr959 +attr960 attr961 attr962 attr963 attr964 attr965 attr966 attr967 attr968 attr969 +attr970 attr971 attr972 attr973 attr974 attr975 attr976 attr977 attr978 attr979 +attr980 attr981 attr982 attr983 attr984 attr985 attr986 attr987 attr988 attr989 +attr990 attr991 attr992 attr993 attr994 attr995 attr996 attr997 attr998 attr999 +attr1000 attr1001 attr1002 attr1003 attr1004 attr1005 attr1006 attr1007 attr1008 attr1009 +attr1010 attr1011 attr1012 attr1013 attr1014 attr1015 attr1016 attr1017 attr1018 attr1019 +attr1020 attr1021 attr1022 attr1023 attr1024 attr1025 attr1026 attr1027 attr1028 attr1029 +attr1030 attr1031 attr1032 attr1033 attr1034 attr1035 attr1036 attr1037 attr1038 attr1039 +attr1040 attr1041 attr1042 attr1043 attr1044 attr1045 attr1046 attr1047 attr1048 attr1049 +attr1050 attr1051 attr1052 attr1053 attr1054 attr1055 attr1056 attr1057 attr1058 attr1059 +attr1060 attr1061 attr1062 attr1063 attr1064 attr1065 attr1066 attr1067 attr1068 attr1069 +attr1070 attr1071 attr1072 attr1073 attr1074 attr1075 attr1076 attr1077 attr1078 attr1079 +attr1080 attr1081 attr1082 attr1083 attr1084 attr1085 attr1086 attr1087 attr1088 attr1089 +attr1090 attr1091 attr1092 attr1093 attr1094 attr1095 attr1096 attr1097 attr1098 attr1099 +id="crash2" +>I'm on a boat</span> +<pre id="test"> +<script> +span = document.createElement("span"); +try { + var i = 0; + while(1) { + span.setAttribute("attr" + (++i), "foo"); + } +} +catch (ex) {} +span.id = "crash3"; +document.body.appendChild(span); +var attrCount = span.attributes.length; +var spans = document.getElementsByTagName("span"); +for (i = 0; i < spans.length; ++i) { + is(spans[i].attributes.length, attrCount, "didn't have maxed out attrs"); +} +while (spans.length) { + spans[0].parentNode.removeChild(spans[0]); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug622088.html b/dom/base/test/test_bug622088.html new file mode 100644 index 0000000000..134bb898d3 --- /dev/null +++ b/dom/base/test/test_bug622088.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 622088 - Test that XHR gives the referrer corresponding to the dynamic script context.</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622088">Mozilla Bug 622088</a> +<pre id="test"> + +<iframe id='iframe' src='file_bug622088_inner.html'></iframe> + +<iframe id='dataWindow' src="data:text/html,<html><head> +<script>function getXHRObject() { return new XMLHttpRequest(); }</script> +</head><body onload='parent.dataWindowLoaded()'>Hello!!</body></html>"></iframe> + +<script class="testbody" type="application/javascript;version=1.8"> + +// Bug 622088 - Test that XHR gives the referrer corresponding to the +// dynamic script context. + +const kOriginalLocation = location.href; + +SimpleTest.waitForExplicitFinish(); + +var innerFinishedLoading = false; +function innerLoaded(inner) { + // Here, we're being called through inner's onload handler, so our referrer + // should be inner's URL. + var referrer = inner.doXHR(); + is (referrer, String(inner.document.location), 'Expected inner frame location'); + + // Now change the location of the inner frame. This should be reflected in + // the XHR's referrer. + inner.history.pushState('', '', Math.random()); + referrer = inner.doXHR(); + is (referrer, String(inner.document.location), 'Expected inner frame location after pushstate'); + + innerFinishedLoading = true; +} + +var dataWindowFinishedLoading = false; +function dataWindowLoaded() { + dataWindowFinishedLoading = true; +} + +function callXHR() { + if (innerFinishedLoading && dataWindowFinishedLoading) { + var inner = document.getElementById('iframe').contentWindow; + var referrer = inner.doXHR(); + is (referrer, String(inner.document.location), + 'Expected inner frame location when called from outer frame.'); + + var referrer = inner.doXHR(new XMLHttpRequest()); + is (referrer, String(document.location), + "Expected outer frame location when called with outer's XHR object."); + + // Now do a request within the inner window using an XMLHttpRequest + // retrieved from a data: URI. The referrer should be this window, not the + // data: URI. + var dataWindow = document.getElementById('dataWindow').contentWindow; + var referrer = inner.doXHR(dataWindow.getXHRObject()); + is (referrer, String(document.location), + "Expected outer frame location when called with data's XHR object."); + + // Now do that test again, but after having changed the outer window's URI. + // This currently fails, due to basically bug 631949. It's not even clear + // what the right behavior is. So marking as a todo for now. + history.replaceState('', '', Math.random()); + + var referrer = inner.doXHR(dataWindow.getXHRObject()); + todo_is (referrer, String(document.location), + "Expected outer frame location when called with data's XHR object " + + "after replaceState."); + + // In case you're temped, you probably don't want to do history.pushState + // here and test again with the outer frame. Calling pushState on the + // outer frame messes up Mochitest in subtle ways. + + history.replaceState('', '', kOriginalLocation); + SimpleTest.finish(); + } + else { + // ugh. + setTimeout(callXHR, 0); + } +} + +callXHR(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug622117.html b/dom/base/test/test_bug622117.html new file mode 100644 index 0000000000..e712fd4e7e --- /dev/null +++ b/dom/base/test/test_bug622117.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=622117 +--> +<head> + <title>Test for Bug 622117</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622117">Mozilla Bug 622117</a> +<p id="display"> + <iframe id="testframe" + src="data:text/html,<a href='data:text/plain,PASS' onclick='throw 1'>Click me</a>"> + </iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 622117 **/ +SimpleTest.waitForExplicitFinish(); + +const PASSURL = "data:text/plain,PASS"; + +SimpleTest.waitForFocus(function() { + $("testframe").onload = function() { + is(this.contentDocument.documentElement.textContent, "PASS", "Should have loaded link"); + SimpleTest.finish(); + }; + + var win = $("testframe").contentWindow; + var a = win.document.getElementsByTagName("a")[0]; + synthesizeMouseAtCenter(a, {}, win); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug622246.html b/dom/base/test/test_bug622246.html new file mode 100644 index 0000000000..684a8f2b38 --- /dev/null +++ b/dom/base/test/test_bug622246.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=622246 +--> +<head> + <title>Test for Bug 622246</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622246">Mozilla Bug 622246</a> +<p id="display"> + <iframe id="testframe" + src="data:text/html,<span onclick='this.parentNode.removeChild(this)'><a href='data:text/plain,PASS'>Click me</a></span>"> + </iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 622246 **/ +SimpleTest.waitForExplicitFinish(); + +const PASSURL = "data:text/plain,PASS"; + +SimpleTest.waitForFocus(function() { + $("testframe").onload = function() { + is(this.contentDocument.documentElement.textContent, "PASS", "Should have loaded link"); + SimpleTest.finish(); + }; + + var win = $("testframe").contentWindow; + var a = win.document.getElementsByTagName("a")[0]; + synthesizeMouseAtCenter(a, {}, win); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug625722.html b/dom/base/test/test_bug625722.html new file mode 100644 index 0000000000..92d1443232 --- /dev/null +++ b/dom/base/test/test_bug625722.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=625722 +--> +<head> + <title>Test for Bug 625722</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=625722">Mozilla Bug 625722</a> +<p id="display"></p> +<div id="content" style="display: none"> + <span id=root><span id=A><span id=A1></span></span><span id=B></span></span> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 625722 **/ + +function testNodeFilter(n) { + if (n.id == 'A' || n.id == 'A1') + return NodeFilter.FILTER_SKIP; + return NodeFilter.FILTER_ACCEPT; +} + +tw = document.createTreeWalker(document.getElementById("root"), + NodeFilter.SHOW_ELEMENT, + testNodeFilter); + +node = tw.firstChild(); +is(node.id, 'B', "First accepted child of root not B"); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug626262.html b/dom/base/test/test_bug626262.html new file mode 100644 index 0000000000..70ee12febf --- /dev/null +++ b/dom/base/test/test_bug626262.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=626262 +--> +<head> + <title>Test for Bug 626262</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=626262">Mozilla Bug 626262</a> +<p id="display"><iframe id="f" src="data:text/html,1"></iframe></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 626262 **/ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + var iframe = document.getElementById("f"); + var frameDoc = iframe.contentDocument; + var parent = frameDoc.createElementNS("http://www.w3.org/1999/xhtml", "div"); + + function a() + { + window.removeEventListener("DOMNodeRemoved", arguments.callee, false); + document.adoptNode(parent); + } + + var text = document.createTextNode(" "); + document.documentElement.appendChild(text); + + var thrown = false; + try { + window.addEventListener("DOMNodeRemoved", a, false); + parent.appendChild(text); + } + catch (e) { + thrown = true; + } + + ok(!thrown, "changing ownerDocument during adoptNode should not throw"); + + SimpleTest.finish(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug628938.html b/dom/base/test/test_bug628938.html new file mode 100644 index 0000000000..d29b86a999 --- /dev/null +++ b/dom/base/test/test_bug628938.html @@ -0,0 +1,239 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=628938 +--> +<head> + <title>Test for Bug 628938</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=628938">Mozilla Bug 628938</a> +<p id="display"></p> +<foo id="content" style="display: none"> + <div><div>foo</div></div> + <span> bar </span> + <div>tulip<span>bar</span></div> + <span></span> + <div>foo</div> + <span></span> + <div>bar</div> + <span></span> + <div>foobar</div> +</foo> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 628938 **/ + +var gResults = []; +var gIdx = 0; + +function walkTree(walker) +{ + if(walker.firstChild()) { + do { + if (walker.currentNode.nodeType == Node.ELEMENT_NODE) { + ok(gResults[gIdx][0], "current node should be an element"); + is(walker.currentNode.nodeName, gResults[gIdx][1], + "current node name should be " + gResults[gIdx][1]); + } else { + ok(!gResults[gIdx][0], "current node shouldn't be an element"); + is(walker.currentNode.nodeValue, gResults[gIdx][1], + "current node value should be " + gResults[gIdx][1]); + } + gIdx++; + // Recursively walk the rest of the sub-tree. + walkTree(walker); + } while(walker.nextSibling()); + + // don't forget to return the treewalker to it's previous state + // before exiting the function + walker.parentNode(); + } +} + +function regularWalk() +{ + gResults = [ + [ false, "\n " ], + [ true, "DIV" ], + [ true, "DIV" ], + [ false, "foo" ], + [ false, "\n " ], + [ true, "SPAN" ], + [ false, " bar " ], + [ false, "\n " ], + [ true, "DIV" ], + [ false, "tulip" ], + [ true, "SPAN" ], + [ false, "bar" ], + [ false, "\n " ], + [ true, "SPAN" ], + [ false, "\n " ], + [ true, "DIV" ], + [ false, "foo" ], + [ false, "\n " ], + [ true, "SPAN" ], + [ false, "\n " ], + [ true, "DIV" ], + [ false, "bar" ], + [ false, "\n " ], + [ true, "SPAN" ], + [ false, "\n " ], + [ true, "DIV" ], + [ false, "foobar" ], + [ false, "\n" ], + ]; + var walker = document.createTreeWalker(document.getElementById('content'), + NodeFilter.SHOW_ALL, null); + + walkTree(walker); + + gIdx = 0; +} + +function noWhiteSpaceWalk() +{ + gResults = [ + [ true, "DIV" ], + [ true, "DIV" ], + [ false, "foo" ], + [ true, "SPAN" ], + [ false, " bar " ], + [ true, "DIV" ], + [ false, "tulip" ], + [ true, "SPAN" ], + [ false, "bar" ], + [ true, "SPAN" ], + [ true, "DIV" ], + [ false, "foo" ], + [ true, "SPAN" ], + [ true, "DIV" ], + [ false, "bar" ], + [ true, "SPAN" ], + [ true, "DIV" ], + [ false, "foobar" ], + ]; + var walker = document.createTreeWalker(document.getElementById('content'), + NodeFilter.SHOW_ALL, + { + acceptNode : function(node) { + if (node.nodeType == Node.TEXT_NODE && + !(/[^\t\n\r ]/.test(node.nodeValue))) + return NodeFilter.FILTER_REJECT; + return NodeFilter.FILTER_ACCEPT; + } + }); + + walkTree(walker); + + gIdx = 0; +} + +function onlyElementsWalk() +{ + gResults = [ + [ true, "DIV" ], + [ true, "DIV" ], + [ true, "SPAN" ], + [ true, "DIV" ], + [ true, "SPAN" ], + [ true, "SPAN" ], + [ true, "DIV" ], + [ true, "SPAN" ], + [ true, "DIV" ], + [ true, "SPAN" ], + [ true, "DIV" ], + ]; + var walker = document.createTreeWalker(document.getElementById('content'), + NodeFilter.SHOW_ELEMENT, null); + + walkTree(walker); + + gIdx = 0; +} + +function onlyDivSubTreeWalk() +{ + gResults = [ + [ true, "DIV" ], + [ true, "DIV" ], + [ false, "foo" ], + [ true, "DIV" ], + [ false, "tulip" ], + [ true, "SPAN" ], + [ false, "bar" ], + [ true, "DIV" ], + [ false, "foo" ], + [ true, "DIV" ], + [ false, "bar" ], + [ true, "DIV" ], + [ false, "foobar" ], + ]; + var walker = document.createTreeWalker(document.getElementById('content'), + NodeFilter.SHOW_ALL, + { + acceptNode : function(node) { + if (node.nodeType == Node.TEXT_NODE && + !(/[^\t\n\r ]/.test(node.nodeValue))) + return NodeFilter.FILTER_REJECT; + + while (node) { + if (node.nodeName == "DIV") + return NodeFilter.FILTER_ACCEPT; + node = node.parentNode; + } + return NodeFilter.FILTER_SKIP; + } + }); + + walkTree(walker); + + gIdx = 0; +} + +function onlyDivDataWalk() +{ + gResults = [ + [ true, "DIV" ], + [ true, "DIV" ], + [ false, "foo" ], + [ true, "DIV" ], + [ false, "tulip" ], + [ true, "SPAN" ], + [ true, "DIV" ], + [ false, "foo" ], + [ true, "DIV" ], + [ false, "bar" ], + [ true, "DIV" ], + [ false, "foobar" ], + ]; + var walker = document.createTreeWalker(document.getElementById('content'), + NodeFilter.SHOW_ALL, + { + acceptNode : function(node) { + if (node.nodeName == "DIV" || + (node.parentNode && + node.parentNode.nodeName == "DIV")) + return NodeFilter.FILTER_ACCEPT; + return NodeFilter.FILTER_SKIP; + } + }); + + walkTree(walker); + + gIdx = 0; +} + +regularWalk(); +noWhiteSpaceWalk(); +onlyElementsWalk(); +onlyDivSubTreeWalk(); +onlyDivDataWalk(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug631615.html b/dom/base/test/test_bug631615.html new file mode 100644 index 0000000000..b78295eb34 --- /dev/null +++ b/dom/base/test/test_bug631615.html @@ -0,0 +1,39 @@ +<!doctype html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=631615 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 631615</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=631615" + >Mozilla Bug 631615</a> +<pre id="monitor"></pre> +<script> +function doTest() { + var monitor = document.getElementById("monitor"); + var html = document.documentElement; + var results; + + try { + results = "return: " + html.matches("[test!='']:sizzle") + "\n"; + } catch (e) { + results = "throws: " + e + "\n"; + } + + monitor.appendChild(document.createTextNode(results)); + is(results.slice(0, 6), "throws", "looking for an exception"); +} + +SimpleTest.runTestExpectingConsoleMessages(doTest, [{ + forbid: true, + message: /An invalid or illegal string was specified/ +}]); +</script> +</body> +</html> diff --git a/dom/base/test/test_bug638112.html b/dom/base/test/test_bug638112.html new file mode 100644 index 0000000000..4f6741ed04 --- /dev/null +++ b/dom/base/test/test_bug638112.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=638112 +https://bugzilla.mozilla.org/show_bug.cgi?id=796850 +--> +<head> + <title>Test for Bug 638112</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=638112">Mozilla Bug 638112</a> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=796850">Mozilla Bug 796850</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="text/javascript"> + +/** Test for Bug 638112, revised for Bug 796850 **/ + +/* Bug 796850 changed the type of statusText to ByteString. As a result it is + * now considered to be raw 8 bit encoded rather than UTF8. + */ + +function run_test() { + var req = new XMLHttpRequest(); + req.open("GET", "bug638112.sjs", false); + req.send(null); + var statusText = req.statusText; + + is(statusText, "Information Sans-Autorit\u00E9", ""); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(run_test); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug647518.html b/dom/base/test/test_bug647518.html new file mode 100644 index 0000000000..bb5a6a02a2 --- /dev/null +++ b/dom/base/test/test_bug647518.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=647518 +--> +<head> + <title>Test for Bug 647518</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=647518">Mozilla Bug 647518</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 647518 **/ +SimpleTest.waitForExplicitFinish(); +var counter = 3; + +var called = false; +var handle1 = window.requestAnimationFrame(function() { + called = true; +}); +ok(handle1 > 0, "Should get back a nonzero handle"); + +function checker() { + --counter; + if (counter == 0) { + is(called, false, "Canceled callback should not have been called"); + SimpleTest.finish(); + } else { + window.requestAnimationFrame(checker); + } +} +window.requestAnimationFrame(checker); +window.cancelAnimationFrame(handle1); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug650001.html b/dom/base/test/test_bug650001.html new file mode 100644 index 0000000000..8c2bb71953 --- /dev/null +++ b/dom/base/test/test_bug650001.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=650001 +--> +<head> + <title>Test for Bug 650001</title> + <script type="application/javascript" src="/MochiKit/packed.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650001">Mozilla Bug 650001</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 650001 **/ + +var svg = '<svg><style xml:lang="en" xlink:href="foo" xmlns="bar" xmlns:link="qux"><></style><script><><\/script></svg>'; +var div = document.getElementById("content"); +div.innerHTML = svg; +is(div.innerHTML, svg, "Unexpected serialization."); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug650776.html b/dom/base/test/test_bug650776.html new file mode 100644 index 0000000000..fbc6f8c035 --- /dev/null +++ b/dom/base/test/test_bug650776.html @@ -0,0 +1,105 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=650776 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 650776</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650776">Mozilla Bug 650776</a> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 650776 **/ + +var u = SpecialPowers.Ci.nsIParserUtils; +var s = SpecialPowers.ParserUtils; + +// Basic sanity +is(s.sanitize("foo", 0), "<html><head></head><body>foo</body></html>", "Wrong sanitizer result 1"); +// Scripts get removed +is(s.sanitize("<script>\u003c/script>", 0), "<html><head></head><body></body></html>", "Wrong sanitizer result 2"); +// Event handlers get removed +is(s.sanitize("<a onclick='boom()'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 3"); +// By default, styles are removed +is(s.sanitize("<style>p { color: red; }</style><p style='background-color: blue;'></p>", 0), "<html><head></head><body><p></p></body></html>", "Wrong sanitizer result 4"); +// Can allow styles +is(s.sanitize("<style>p { color: red; }</style><p style='background-color: blue;'></p>", u.SanitizerAllowStyle), '<html><head><style>p { color: red; }</style></head><body><p style="background-color: blue;"></p></body></html>', "Wrong sanitizer result 5"); +// -moz-binding gets dropped when styles allowed; however, reconstructing the p { ... } part seems broken! +todo_is(s.sanitize("<style>p { color: red; -moz-binding: url(foo); }</style><p style='background-color: blue; -moz-binding: url(foo);'></p>", u.SanitizerAllowStyle), '<html><head><style>p { color: red; }</style></head><body><p style="background-color: blue;"></p></body></html>', "Wrong sanitizer result 6"); +// Various cid: embeds only cases +is(s.sanitize("<img src='foo.html'>", u.SanitizerCidEmbedsOnly), '<html><head></head><body><img></body></html>', "Wrong sanitizer result 7"); +is(s.sanitize("<img src='cid:foo'>", u.SanitizerCidEmbedsOnly), '<html><head></head><body><img src="cid:foo"></body></html>', "Wrong sanitizer result 8"); +is(s.sanitize("<img src='data:image/png,'>", u.SanitizerCidEmbedsOnly), '<html><head></head><body><img></body></html>', "Wrong sanitizer result 9"); +is(s.sanitize("<img src='http://mochi.test/'>", u.SanitizerCidEmbedsOnly), '<html><head></head><body><img></body></html>', "Wrong sanitizer result 10"); +is(s.sanitize("<a href='http://mochi.test/'></a>", u.SanitizerCidEmbedsOnly), '<html><head></head><body><a href="http://mochi.test/"></a></body></html>', "Wrong sanitizer result 11"); +is(s.sanitize("<body background='http://mochi.test/'>", u.SanitizerCidEmbedsOnly), '<html><head></head><body></body></html>', "Wrong sanitizer result 12"); +is(s.sanitize("<body background='cid:foo'>", u.SanitizerCidEmbedsOnly), '<html><head></head><body background="cid:foo"></body></html>', "Wrong sanitizer result 13"); +is(s.sanitize("<svg></svg>", u.SanitizerCidEmbedsOnly), '<html><head></head><body></body></html>', "Wrong sanitizer result 14"); +is(s.sanitize("<math definitionURL='cid:foo' altimg='cid:foo'></math>", u.SanitizerCidEmbedsOnly), '<html><head></head><body><math></math></body></html>', "Wrong sanitizer result 14"); +is(s.sanitize("<video><source src='http://mochi.test/'></video>", u.SanitizerCidEmbedsOnly), '<html><head></head><body><video controls="controls"><source></video></body></html>', "Wrong sanitizer result 15"); +is(s.sanitize("<style></style>", u.SanitizerAllowStyle | u.SanitizerCidEmbedsOnly), '<html><head></head><body></body></html>', "Wrong sanitizer result 16"); +// Dangerous links +is(s.sanitize("<a href='javascript:boom()'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 17"); +is(s.sanitize("<a href='JavaScript:boom()'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 18"); +is(s.sanitize("<a href=' javascript:boom()'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 19"); +is(s.sanitize("<a href='\njavascript:boom()'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 20"); +is(s.sanitize("<a href='\fjavascript:boom()'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 21"); +is(s.sanitize("<a href='\u00A0javascript:boom()'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 22"); +is(s.sanitize("<a href='foo.html'></a>", 0), "<html><head></head><body><a></a></body></html>", "Wrong sanitizer result 23"); +// Comments +is(s.sanitize("<!-- foo -->", 0), "<html><head></head><body></body></html>", "Wrong sanitizer result 24"); +is(s.sanitize("<!-- foo -->", u.SanitizerAllowComments), "<!-- foo -->\n<html><head></head><body></body></html>", "Wrong sanitizer result 25"); +// noscript +is(s.sanitize("<body><noscript><p class=bar>foo</p></noscript>", 0), '<html><head></head><body><noscript><p class="bar">foo</p></noscript></body></html>', "Wrong sanitizer result 26"); +// dangerous elements +is(s.sanitize("<iframe></iframe>", 0), "<html><head></head><body></body></html>", "Wrong sanitizer result 27"); +is(s.sanitize("<object></object>", 0), "<html><head></head><body></body></html>", "Wrong sanitizer result 28"); +is(s.sanitize("<embed>", 0), "<html><head></head><body></body></html>", "Wrong sanitizer result 29"); +// presentationalism +is(s.sanitize("<font></font>", 0), "<html><head></head><body><font></font></body></html>", "Wrong sanitizer result 30"); +is(s.sanitize("<center></center>", 0), "<html><head></head><body><center></center></body></html>", "Wrong sanitizer result 31"); +is(s.sanitize("<div align=center></div>", 0), '<html><head></head><body><div align="center"></div></body></html>', "Wrong sanitizer result 32"); +is(s.sanitize("<table><tr><td bgcolor=#FFFFFF>", 0), '<html><head></head><body><table><tbody><tr><td bgcolor="#FFFFFF"></td></tr></tbody></table></body></html>', "Wrong sanitizer result 33"); +is(s.sanitize("<font></font>", u.SanitizerDropNonCSSPresentation), "<html><head></head><body></body></html>", "Wrong sanitizer result 34"); +is(s.sanitize("<center></center>", u.SanitizerDropNonCSSPresentation), "<html><head></head><body></body></html>", "Wrong sanitizer result 35"); +is(s.sanitize("<div align=center></div>", u.SanitizerDropNonCSSPresentation), '<html><head></head><body><div></div></body></html>', "Wrong sanitizer result 36"); +is(s.sanitize("<table><tr><td bgcolor=#FFFFFF>", u.SanitizerDropNonCSSPresentation), '<html><head></head><body><table><tbody><tr><td></td></tr></tbody></table></body></html>', "Wrong sanitizer result 37"); +// metadata +is(s.sanitize("<meta charset=utf-7>", 0), "<html><head></head><body></body></html>", "Wrong sanitizer result 38"); +is(s.sanitize("<meta http-equiv=content-type content='text/html; charset=utf-7'>", 0), "<html><head></head><body></body></html>", "Wrong sanitizer result 39"); +is(s.sanitize("<meta itemprop=foo content=bar>", 0), '<html><head><meta itemprop="foo" content="bar"></head><body></body></html>', "Wrong sanitizer result 40"); +is(s.sanitize("<link rel=whatever href=http://mochi.test/ >", 0), '<html><head></head><body></body></html>', "Wrong sanitizer result 41"); +is(s.sanitize("<link itemprop=foo href=http://mochi.test/ >", 0), '<html><head><link itemprop="foo" href="http://mochi.test/"></head><body></body></html>', "Wrong sanitizer result 42"); +is(s.sanitize("<link rel=stylesheet itemprop=foo href=http://mochi.test/ >", 0), '<html><head><link itemprop="foo" href="http://mochi.test/"></head><body></body></html>', "Wrong sanitizer result 43"); +is(s.sanitize("<meta name=foo content=bar>", 0), '<html><head><meta name="foo" content="bar"></head><body></body></html>', "Wrong sanitizer result 44"); +// forms +is(s.sanitize("<form></form>", 0), '<html><head></head><body><form></form></body></html>', "Wrong sanitizer result 45"); +is(s.sanitize("<fieldset><legend></legend></fieldset>", 0), '<html><head></head><body><fieldset><legend></legend></fieldset></body></html>', "Wrong sanitizer result 46"); +is(s.sanitize("<input>", 0), '<html><head></head><body><input></body></html>', "Wrong sanitizer result 47"); +is(s.sanitize("<button>foo</button>", 0), '<html><head></head><body><button>foo</button></body></html>', "Wrong sanitizer result 48"); +is(s.sanitize("<select><optgroup><option>foo</option></optgroup></select></button>", 0), '<html><head></head><body><select><optgroup><option>foo</option></optgroup></select></body></html>', "Wrong sanitizer result 49"); +is(s.sanitize("<form></form>", u.SanitizerDropForms), '<html><head></head><body></body></html>', "Wrong sanitizer result 50"); +is(s.sanitize("<fieldset><legend></legend></fieldset>", u.SanitizerDropForms), '<html><head></head><body><fieldset><legend></legend></fieldset></body></html>', "Wrong sanitizer result 51"); +is(s.sanitize("<input>", u.SanitizerDropForms), '<html><head></head><body></body></html>', "Wrong sanitizer result 52"); +is(s.sanitize("<button>foo</button>", u.SanitizerDropForms), '<html><head></head><body></body></html>', "Wrong sanitizer result 53"); +is(s.sanitize("<select><optgroup><option>foo</option></optgroup></select></button>", u.SanitizerDropForms), '<html><head></head><body></body></html>', "Wrong sanitizer result 54"); +// doctype +is(s.sanitize("<!DOCTYPE html>", 0), '<!DOCTYPE html>\n<html><head></head><body></body></html>', "Wrong sanitizer result 55"); +// title +is(s.sanitize("<title></title>", 0), '<html><head><title></title></head><body></body></html>', "Wrong sanitizer result 56"); +// Drop media +is(s.sanitize("<img>", u.SanitizerDropMedia), '<html><head></head><body></body></html>', "Wrong sanitizer result 57"); +is(s.sanitize("<svg>foo</svg>", u.SanitizerDropMedia), '<html><head></head><body>foo</body></html>', "Wrong sanitizer result 58"); +is(s.sanitize("<video><source></video>", u.SanitizerDropMedia), '<html><head></head><body></body></html>', "Wrong sanitizer result 59"); +is(s.sanitize("<audio><source></audio>", u.SanitizerDropMedia), '<html><head></head><body></body></html>', "Wrong sanitizer result 60"); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug650784.html b/dom/base/test/test_bug650784.html new file mode 100644 index 0000000000..c907c265a4 --- /dev/null +++ b/dom/base/test/test_bug650784.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=650776 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 650776</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650776">Mozilla Bug 650776</a> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 650776 **/ + +var c = SpecialPowers.Ci.nsIDocumentEncoder; +var s = SpecialPowers.ParserUtils; + +is(s.convertToPlainText("foo", c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 1"); +is(s.convertToPlainText("foo foo foo", c.OutputWrap | c.OutputLFLineBreak, 7), "foo foo\nfoo", "Wrong conversion result 2"); +is(s.convertToPlainText("<body><noscript>b<span>a</span>r</noscript>foo", c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 3"); +is(s.convertToPlainText("<body><noscript>b<span>a</span>r</noscript>foo", c.OutputNoScriptContent, 0), "barfoo", "Wrong conversion result 4"); +is(s.convertToPlainText("foo\u00A0bar", c.OutputPersistNBSP | c.OutputLFLineBreak, 0), "foo\u00A0bar", "Wrong conversion result 5"); +is(s.convertToPlainText("foo\u00A0bar", c.OutputLFLineBreak, 0), "foo bar", "Wrong conversion result 6"); +is(s.convertToPlainText("<body><noframes>bar</noframes>foo", c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 7"); +// OutputNoFramesContent doesn't actually work, because the flag gets overridden in all cases. +is(s.convertToPlainText("<body><noframes>bar</noframes>foo", c.OutputNoFramesContent | c.OutputLFLineBreak, 0), "foo", "Wrong conversion result 8"); +is(s.convertToPlainText("<i>foo</i> <b>bar</b>", c.OutputFormatted | c.OutputLFLineBreak, 0), "/foo/ *bar*\n", "Wrong conversion result 9"); +is(s.convertToPlainText("<p>foo</p> <p>bar</p>", c.OutputLFLineBreak, 0), "foo\n\nbar", "Wrong conversion result 10"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug656283.html b/dom/base/test/test_bug656283.html new file mode 100644 index 0000000000..47c05845dd --- /dev/null +++ b/dom/base/test/test_bug656283.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=656283 +--> +<head> + <title>Test for Bug 656283</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="test()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=656283">Mozilla Bug 656283</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 656283 **/ + +SimpleTest.waitForExplicitFinish(); + +var ifr; +function test() { + // First a test with data documents. + var d = document.implementation.createHTMLDocument(""); + is(d.activeElement, d.body, "Active element should be body by default! (1)"); + + + ifr = document.getElementById("ifr"); + ifr.onload = test2; + ifr.src = "data:text/html,1"; +} + +var firstDoc; +function test2() { + firstDoc = ifr.contentDocument; + is(firstDoc.activeElement, firstDoc.body, + "Active element should be body by default! (2)"); + ifr.onload = test3; + ifr.src = "data:text/html,<input>"; +} + +function test3() { + ifr.contentDocument.getElementsByTagName("input")[0].focus(); + is(firstDoc.activeElement, firstDoc.body, + "Active element should be body by default! (3)"); + ifr.parentNode.removeChild(ifr); + is(firstDoc.activeElement, firstDoc.body, + "Active element should be body by default! (4)"); + SimpleTest.finish(); +} + +</script> +</pre> +<iframe id="ifr"></irame> +</body> +</html> diff --git a/dom/base/test/test_bug664916.html b/dom/base/test/test_bug664916.html new file mode 100644 index 0000000000..fbfdde3eed --- /dev/null +++ b/dom/base/test/test_bug664916.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=664916 +--> +<head> + <title>Test for Bug 664916</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=664916">Mozilla Bug 664916</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + + +/** Test for Bug 664916 **/ +var div = document.createElement("div"); +var textNode = document.createTextNode("x") +var tagNameGetter = div.__lookupGetter__("tagName"); + +var tagName = ""; +try { + tagName = tagNameGetter.call(textNode); + ok(false, "Should throw when calling tagname getter on text node"); +} catch(e) { + ok(true, "Should throw when calling tagname getter on text node"); +} +is(tagName, "", "Should not have changed tagName yet"); +tagName = tagNameGetter.call(div); +is(tagName, "DIV", "Should get the right tag name"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug666604.html b/dom/base/test/test_bug666604.html new file mode 100644 index 0000000000..4f73c4075c --- /dev/null +++ b/dom/base/test/test_bug666604.html @@ -0,0 +1,142 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=666604 +--> +<head> + <title>Test for Bug 666604</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=666604">Mozilla Bug 666604</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<a href="javascript:activationListener()" id="testlink">test</a> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 666604 **/ + +SimpleTest.waitForExplicitFinish(); + +function hitEventLoop(times, next) +{ + if (times == 0) { + next(); + return; + } + + SimpleTest.executeSoon(function() { + hitEventLoop(times - 1, next); + }); +} + +var activationListener; + +function dispatchClick(target, ctrl) { + var e = document.createEvent("MouseEvent"); + e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, + ctrl, false, false, false, 0, null); + target.dispatchEvent(e); +} + +function dispatchReturn(target, ctrl) { + var e = document.createEvent("KeyboardEvent"); + e.initKeyEvent("keypress", true, true, window, ctrl, false, + false, false, 13, 0); + target.dispatchEvent(e); +} + +function dispatchDOMActivate(target) { + var e = document.createEvent("UIEvent"); + e.initUIEvent("DOMActivate", true, true, window, 0); + target.dispatchEvent(e); +} + +var testlink = document.getElementById("testlink"); +function test1() { + activationListener = + function() { + ok(true, "Untrusted click should activate a link"); + test2(); + } + dispatchClick(testlink, false); +} + +function test2() { + activationListener = + function() { + ok(true, "Untrusted return keypress should activate a link"); + test3(); + } + dispatchReturn(testlink, false); +} + +function test3() { + activationListener = + function() { + ok(false, "Untrusted click+ctrl should not activate a link"); + test4(); + } + dispatchClick(testlink, true); + hitEventLoop(10, test4); +} + +function test4() { + activationListener = + function() { + ok(false, "Untrusted return keypress+ctrl should not activate a link"); + test5(); + } + dispatchReturn(testlink, true); + hitEventLoop(10, test5); +} + +function test5() { + activationListener = + function() { + ok(true, "click() should activate a link"); + test6(); + } + testlink.click(); +} + +function test6() { + activationListener = + function() { + ok(true, "Untrusted DOMActivate should activate a link"); + SpecialPowers.pushPrefEnv({"set":[["dom.disable_open_during_load", false]]}, test7); + } + dispatchDOMActivate(testlink); +} + +function test7() { + testlink.href = "javascript:opener.activationListener(); window.close();"; + testlink.target = "_blank"; + activationListener = + function() { + ok(true, "Click() should activate a link"); + SpecialPowers.pushPrefEnv({"set":[["dom.disable_open_during_load", true]]}, test8); + } + testlink.click(); +} + +function test8() { + testlink.href = "javascript:opener.activationListener(); window.close();"; + testlink.target = "_blank"; + activationListener = + function() { + ok(false, "Click() should not activate a link"); + } + testlink.click(); + SimpleTest.executeSoon(SimpleTest.finish); +} +addLoadEvent(test1); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug675121.html b/dom/base/test/test_bug675121.html new file mode 100644 index 0000000000..a48fea935e --- /dev/null +++ b/dom/base/test/test_bug675121.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=675121 +--> +<head> + <title>Test for Bug 675121</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=675121">Mozilla Bug 675121</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 675121 **/ +var callbackFired = false; +var xhrInProgress = false; +function f() { + callbackFired = true; + if (!xhrInProgress) { + SimpleTest.finish(); + } +} + +window.requestAnimationFrame(f); +var xhr = new XMLHttpRequest(); +xhr.open("GET", "file_bug675121.sjs", false); +xhrInProgress = true; +xhr.send(); +xhrInProgress = false; +is(xhr.responseText, "Responded", "Should have a response by now"); +is(callbackFired, false, "Callback should not fire during sync XHR"); + +if (!callbackFired) { + SimpleTest.waitForExplicitFinish(); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug675166.html b/dom/base/test/test_bug675166.html new file mode 100644 index 0000000000..cef5ff5600 --- /dev/null +++ b/dom/base/test/test_bug675166.html @@ -0,0 +1,57 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=675166 +--> +<head> + <title>Test for Bug 675166</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=675166">Mozilla Bug 675166</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 675166 **/ + + +var dt = document.implementation.createDocumentType("html", null, null); +isnot(dt.ownerDocument, null, "DocumentType should have ownerDocument"); + +var d = document.implementation.createDocument(null, null, dt); +is(dt.ownerDocument, d, "DocumentType shouldn't have null ownerDocument"); + +try { + document.implementation.createDocument(null, null, dt); + ok(true, "Creating document using already bound document type shouldn't throw!"); +} catch(ex) { + ok(false, "Creating document using already bound document type shouldn't throw!"); +} + +var d2 = document.implementation.createDocument(null, null, null); +var dt2 = document.implementation.createDocumentType("html", null, null); +d2.appendChild(dt2); +is(dt2.ownerDocument, d2, "DocumentType shouldn't have null ownerDocument"); + +is(document.ownerDocument, null, "Document's ownerDocument should be null!"); +is(document.documentElement.ownerDocument, document, + "Element should have ownerDocument!") + +is(dt2.parentNode, d2, "parentNode should be document!"); +d2.removeChild(dt2); +is(dt2.parentNode, null, "parentNode should be null!"); + +d.adoptNode(dt2); +d2.adoptNode(dt2); +d2.appendChild(dt2); +is(dt2.parentNode, d2, "parentNode should be document!"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug682463.html b/dom/base/test/test_bug682463.html new file mode 100644 index 0000000000..7fc5097d0f --- /dev/null +++ b/dom/base/test/test_bug682463.html @@ -0,0 +1,156 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=682463 +--> +<head> + <title>Test for Bug 682463</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=682463">Mozilla Bug 682463</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 682463 **/ + + function text(s) { + return document.createTextNode(s); + } + function div(l,r) { + var div = document.createElement("DIV"); + if (l) div.appendChild(l); + if (r) div.appendChild(r); + return div; + } + function createRange(sn,so,en,eo) { + var r = document.createRange(); + r.setStart(sn,so); + r.setEnd(en,eo); + return r; + } + function verifyRange(msg,r,sn,so,en,eo) { + ok(r.startContainer == sn && r.startOffset == so && + r.endContainer == en && r.endOffset == eo, msg); + } + function showRange(r,msg) { + var s = "" + r.startContainer + ": " + r.startOffset; + s+= '\n'; + s += "" + r.endContainer + ": " + r.endOffset; + alert(msg + ':\n' + s) + } + + var tests = [ + function() { + var t = text("foobar"); + var r = createRange(t,2,t,t.length); + var t2 = t.splitText(1); + verifyRange("split before, no parent",r,t2,1,t2,5); + }, + function() { + var t = text("foobar"); + var r = createRange(t,0,t,t.length); + var t2 = t.splitText(3); + verifyRange("split middle, no parent",r,t,0,t,3); + }, + function() { + var t = text("foobar"); + var r = createRange(t,0,t,t.length); + var n = t.length; + var t2 = t.splitText(n); + verifyRange("split after, no parent",r,t,0,t,n); + }, + function() { + var t = text("foobar"); + var parent = div(t); + var r = createRange(t,0,t,t.length); + var t2 = t.splitText(3); + verifyRange("split middle, parent",r,t,0,t2,3); + parent.removeChild(t); + verifyRange("removed left, parent",r,parent,0,t2,3); + var t2b = t2.splitText(1); + verifyRange("split middle, parent, end",r,parent,0,t2b,2); + }, + function() { + var t0 = text("x"); + var t = text("foobar"); + var parent = div(t0,t); + var r = createRange(t,0,t,t.length); + var t2 = t.splitText(3); + parent.removeChild(t); + verifyRange("removed left, text sibling",r,parent,1,t2,3); + }, + function() { + var t = text("foobar"); + var parent = div(t); + var r = createRange(t,2,t,t.length); + var t2 = t.splitText(1); + verifyRange("split before, parent",r,t2,1,t2,5); + parent.removeChild(t2); + verifyRange("removed right, parent",r,parent,1,parent,1); + }, + function() { + var t = text("foobar"); + var parent = div(t); + var r = createRange(t,0,t,t.length); + var n = t.length; + var t2 = t.splitText(n); + verifyRange("split after, parent",r,t,0,t,n); + r.setEnd(t2,0); + verifyRange("split after, parent, extend",r,t,0,t2,0); + t2.splitText(0); + verifyRange("split after, parent, extend, split end",r,t,0,t2,0); + t2.textContent = "baz"; + t2.splitText(2); + verifyRange("split after, parent, extend, split after end",r,t,0,t2,0); + r.setEnd(t2,2); + var t2b = t2.splitText(1); + verifyRange("split after, parent, split end",r,t,0,t2b,1); + }, + function() { + var t = text("foobar"); + var parent = div(t); + document.body.appendChild(parent); + var r = createRange(t,0,t,t.length); + var t2 = t.splitText(3); + verifyRange("split middle, in document",r,t,0,t2,3); + }, + function() { + var t = text("foobar"); + var parent = div(t); + document.body.appendChild(parent); + var r = createRange(t,2,t,t.length); + var t2 = t.splitText(1); + verifyRange("split before, in document",r,t2,1,t2,5); + }, + function() { + var t = text("foobar"); + var parent = div(t); + document.body.appendChild(parent); + var r = createRange(t,0,t,t.length); + var n = t.length; + var t2 = t.splitText(n); + verifyRange("split after, in document",r,t,0,t,n); + } + ]; + + function runTests() { + var len = tests.length; + for (var i = 0; i < len; ++i) { + tests[i](); + } + SimpleTest.finish(); + } + +addLoadEvent(runTests); +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug682554.html b/dom/base/test/test_bug682554.html new file mode 100644 index 0000000000..1f0ca4b63b --- /dev/null +++ b/dom/base/test/test_bug682554.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=682554 +--> +<head> + <title>Test for Bug 682554</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=682554">Mozilla Bug 682554</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 682554 **/ +is("onreadystatechange" in window, false, + "Window should not have an onreadystatechange"); +is("onreadystatechange" in document, true, + "Document should have an onreadystatechange"); +is("onreadystatechange" in document.createElement("script"), false, + "<script> element should not have an onreadystatechange"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug682592.html b/dom/base/test/test_bug682592.html new file mode 100644 index 0000000000..c2dc8ed3a4 --- /dev/null +++ b/dom/base/test/test_bug682592.html @@ -0,0 +1,178 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=682592 +--> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" > + <title>Test for bug 682592</title> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content"> +<iframe id="iframe-ref"></iframe> +<iframe id="iframe-test"></iframe> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript;version=1.7"> +/** Test for Bug 682592 **/ + +/* + We want to check that bidi is detected correctly. So, we have a reference + document where ltr is set explicitely with <bdo> element. Then, we compare + it with test document. + + In mozilla, once bidi has been detected in a document, document always + consider it's in bidi mode. So, if one fragment enables bidi correctly, and + we create or update a fragment in the same document, that operation may not + enable bidi by itself, but it will not be detected. So, we need to have new + document for each test. + + So, instead of many diferent reftests, this mochitest implements a + reftest-like. It creates reference text fragments in reference iframe, test + text fragments in test iframe, and compare the documents. Then, it reloads + test iframe. Reference iframe does not need to be reloaded between tests. + It's ok (and maybe, desired) to keep bidi always enabled in that document. +*/ + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestLongerTimeout(3); +if (navigator.platform.startsWith("Linux arm")) { /* bugs 982875, 999429 */ + SimpleTest.expectAssertions(0, 4); +} + +var page = `data:text/html;charset=UTF-8,<!DOCTYPE html> +<html><body><p id="content"></p></body></html>`; +var refFrame = document.getElementById("iframe-ref") +var testFrame = document.getElementById("iframe-test"); + +refFrame.addEventListener("load", function() { + testFrame.addEventListener("load", function() { + try { + tests.next(); + ok(compareSnapshots(snapshotWindow(testFrame.contentWindow), + snapshotWindow(refFrame.contentWindow), true)[0], + "bidi is not detected correctly"); + + testFrame.contentWindow.location.reload(); + } catch (err if err instanceof StopIteration) { + SimpleTest.finish(); + } + }, false); + testFrame.src = page; +}, false); +refFrame.src = page; + +var rtl = "עִבְרִית"; +var non8bit = "ʃ"; +var is8bit = "a"; + +// concats aStr aNumber of times +function strMult(aStr, aNumber) { + if (aNumber === 0) { + return ""; + } + return strMult(aStr, aNumber - 1) + aStr; +} + +function runTests () { + var ltr = "", prefix = null; + var refContainer = refFrame.contentDocument.getElementById('content'); + var testContainer, textNode; + var i = 0; + + // 8bit chars + bidi + for (i = 0; i <= 16; i++) { + ltr = strMult(is8bit, i); + refContainer.innerHTML = ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + testContainer.innerHTML = ltr + rtl; + yield undefined; + } + + // non-8bit char + 8bit chars + bidi + for (i = 0; i <= 16; i++) { + ltr = non8bit + strMult(is8bit, i); + refContainer.innerHTML = ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + testContainer.innerHTML = ltr + rtl; + yield undefined; + } + + // appendData + for (i = 0; i <= 16; i++) { + ltr = strMult(is8bit, i); + refContainer.innerHTML = ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + textNode = document.createTextNode(""); + testContainer.appendChild(textNode); + textNode.appendData(ltr + rtl); + yield undefined; + } + + for (i = 0; i <= 16; i++) { + ltr = non8bit + strMult(is8bit, i); + refContainer.innerHTML = ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + textNode = document.createTextNode(""); + testContainer.appendChild(textNode); + textNode.appendData(ltr + rtl); + yield undefined; + } + + // appendData with 8bit prefix + for (i = 0; i <= 16; i++) { + prefix = is8bit; + ltr = strMult(is8bit, i); + refContainer.innerHTML = prefix + ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + textNode = document.createTextNode(prefix); + testContainer.appendChild(textNode); + textNode.appendData(ltr + rtl); + yield undefined; + } + + for (i = 0; i <= 16; i++) { + prefix = is8bit; + ltr = non8bit + strMult(is8bit, i); + refContainer.innerHTML = prefix + ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + textNode = document.createTextNode(prefix); + testContainer.appendChild(textNode); + textNode.appendData(ltr + rtl); + yield undefined; + } + + // appendData with non-8bit prefix + for (i = 0; i <= 16; i++) { + prefix = non8bit; + ltr = strMult(is8bit, i); + refContainer.innerHTML = prefix + ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + textNode = document.createTextNode(prefix); + testContainer.appendChild(textNode); + textNode.appendData(ltr + rtl); + yield undefined; + } + + for (i = 0; i <= 16; i++) { + prefix = non8bit; + ltr = non8bit + strMult(is8bit, i); + refContainer.innerHTML = prefix + ltr + '<bdo dir="rtl">' + rtl + '</bdo>'; + testContainer = testFrame.contentDocument.getElementById('content'); + textNode = document.createTextNode(prefix); + testContainer.appendChild(textNode); + textNode.appendData(ltr + rtl); + yield undefined; + } +}; + +var tests = runTests(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug684671.html b/dom/base/test/test_bug684671.html new file mode 100644 index 0000000000..1b67ca6ca0 --- /dev/null +++ b/dom/base/test/test_bug684671.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=684671 +--> +<head> + <title>Test for Bug 684671</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=684671">Mozilla Bug 684671</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 684671 **/ +function f() {} +document.onreadystatechange = f; +is(document.onreadystatechange, f, + "Document onreadystatechange should be settable"); + +window.onreadystatechange = f; +is(window.onreadystatechange, f, + "Window onreadystatechange should be settable"); + +document.documentElement.onreadystatechange = f; +is(document.documentElement.onreadystatechange, f, + "Element onreadystatechange should be settable"); + +var canSetReadyStateChange; +try { + XMLDocument.prototype.onreadystatechange = null; + canSetReadyStateChange = true; +} catch (e) { + canSetReadyStateChange = false; +} +ok(canSetReadyStateChange, "This may break web pages"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug685798.html b/dom/base/test/test_bug685798.html new file mode 100644 index 0000000000..2dcff21125 --- /dev/null +++ b/dom/base/test/test_bug685798.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=685798 +--> +<head> + <title>Test for Bug 685798</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=685798">Mozilla Bug 685798</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 685798 **/ + + +is(document.parentElement, null, + "Document shouldn't have parentElement."); +is(document.documentElement.parentElement, null, + "DocumentElement shouldn't have parentElement."); +is(document.documentElement.firstChild.parentElement, document.documentElement, + "DocumentElement's child should have DocumentElement as parent."); + +var df = document.createRange().createContextualFragment("<div>foo</div>"); +is(df.parentElement, null, + "DocumentFragment should be null."); +is(df.firstChild.parentElement, null, + "DocumentFragment's child shouldn't have parentElement"); +is(df.firstChild.firstChild.parentElement, df.firstChild, + "Text node's parent should be element."); + +is(document.createTextNode("foo").parentElement, null, + "Text node shouldn't have parent element."); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug686449.xhtml b/dom/base/test/test_bug686449.xhtml new file mode 100644 index 0000000000..fe59afb62c --- /dev/null +++ b/dom/base/test/test_bug686449.xhtml @@ -0,0 +1,79 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=686449 +--> +<head> + <title>Test for Bug 686449</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=686449">Mozilla Bug 686449</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="rangetest">abcd<div id="picontainer1"><?pi efgh?></div><div>ijkl</div><div id="picontainer2"><?pi mnop?></div>qrst</div> +<pre id="test"> +<script type="application/javascript"> +<![CDATA[ + +/** Test for Bug 686449 **/ + +var pi = document.createProcessingInstruction("t", "data"); +ok("target" in pi, "No target?"); +ok("data" in pi, "No data?"); +ok("length" in pi, "No length?"); +ok("substringData" in pi, "No substringData?"); +ok("appendData" in pi, "No appendData?"); +ok("insertData" in pi, "No insertData?"); +ok("deleteData" in pi, "No deleteData?"); +ok("replaceData" in pi, "No replaceData?"); + +is(pi.substringData(0, pi.length), pi.data, "wrong data?"); +var olddata = pi.data; +var appenddata = "foo" +pi.appendData(appenddata); +is(pi.data, olddata + appenddata, "appendData doesn't work?"); +pi.deleteData(olddata.length, appenddata.length); +is(pi.data, olddata, "deleteData doesn't work?"); +pi.replaceData(0, 0, olddata); +is(pi.data, olddata + olddata, "replaceData doesn't work?"); +pi.insertData(0, olddata); +is(pi.data, olddata + olddata + olddata, "insertData doesn't work?"); +pi.data = olddata; +is(pi.data, olddata, "setting data doesn't work?"); + +var r = document.createRange(); +r.selectNodeContents(pi); +is(r.startContainer, pi, "Wrong startContainer!"); +is(r.startOffset, 0, "Wrong startOffset!"); +is(r.endContainer, pi, "Wrong endContainer!"); +is(r.endOffset, pi.length, "Wrong endOffset!"); + +var df = r.cloneContents(); +is(df.childNodes.length, 1, "Unexpected child nodes?"); +ok(df.firstChild.isEqualNode(pi), "Wrong cloning?"); + +r.setStart(pi, 1); +r.setEnd(pi, 3); +df = r.cloneContents(); +is(df.childNodes.length, 1, "Unexpected child nodes?"); +ok(!df.firstChild.isEqualNode(pi), "Should clone to similar pi!"); +is(df.firstChild.data, "at", "Wrong data cloning?"); + +r.selectNode(document.getElementById("rangetest")); +is(r.toString(), document.getElementById("rangetest").textContent, + "Wrong range stringification!"); +ok(r.cloneContents().firstChild.firstChild.nextSibling.firstChild. + isEqualNode(document.getElementById("picontainer1").firstChild), + "Wrong pi cloning!"); +ok(r.cloneContents().firstChild.firstChild.nextSibling.nextSibling.nextSibling.firstChild. + isEqualNode(document.getElementById("picontainer2").firstChild), + "Wrong pi cloning!"); + +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug687859.html b/dom/base/test/test_bug687859.html new file mode 100644 index 0000000000..d05cdc0493 --- /dev/null +++ b/dom/base/test/test_bug687859.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=687859 +--> +<head> + <meta charset="windows-1251"> + <title>Test for Bug 687859</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=687859">Mozilla Bug 687859</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script charset="ISO-8859-2" src="file_bug687859-bom.js"></script> +<script charset="ISO-8859-2" src="file_bug687859-16.js"></script> +<script charset="ISO-8859-2" src="file_bug687859-http.js"></script> +<script charset="ISO-8859-2" src="file_bug687859-charset.js"></script> +<script src="file_bug687859-inherit.js"></script> +<script type="application/javascript"> +is(stringFromBomScript, "\u20AC", "Bogus encoding for UTF-8 BOM case."); +is(stringFrom16Script, "\u20AC", "Bogus encoding for UTF-16 BOM case."); +is(stringFromHttpScript, "\u0E44", "Bogus encoding for HTTP case."); +is(stringFromCharsetScript, "\u0104", "Bogus encoding for charset case."); +is(stringFromInheritScript, "\u040E", "Bogus encoding for inherit case."); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug690056.html b/dom/base/test/test_bug690056.html new file mode 100644 index 0000000000..7562259a36 --- /dev/null +++ b/dom/base/test/test_bug690056.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=690056 +--> +<head> + <title>Test for Bug 690056</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=690056">Mozilla Bug 690056</a> +<p id="display"> + <iframe id="x"></iframe> + <iframe style="display: none" id="y"></iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 690056 **/ +SimpleTest.waitForExplicitFinish(); +is(document.hidden, false, "Document should not be hidden during load"); +is(document.visibilityState, "visible", + "Document should be visible during load"); + +addLoadEvent(function() { + var doc = document.implementation.createDocument("", "", null); + is(doc.hidden, true, "Data documents should be hidden"); + is(doc.visibilityState, "hidden", "Data documents really should be hidden"); + + is(document.hidden, false, "Document should not be hidden onload"); + is(document.visibilityState, "visible", + "Document should be visible onload"); + + is($("x").contentDocument.hidden, false, + "Subframe document should not be hidden onload"); + is($("x").contentDocument.visibilityState, "visible", + "Subframe document should be visible onload"); + is($("y").contentDocument.hidden, false, + "display:none subframe document should not be hidden onload"); + is($("y").contentDocument.visibilityState, "visible", + "display:none subframe document should be visible onload"); + + SimpleTest.finish(); +}); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug692434.html b/dom/base/test/test_bug692434.html new file mode 100644 index 0000000000..c38c6349c9 --- /dev/null +++ b/dom/base/test/test_bug692434.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=692434 +--> +<head> + <title>Test for Bug 692434</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload=runTest();> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=692434">Mozilla Bug 692434</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 692434 **/ +SimpleTest.waitForExplicitFinish(); + +var xhr = new XMLHttpRequest(); + +function runTest() { + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + ok(this.responseXML, "Should have gotten responseXML"); + is(this.responseXML.characterSet, "windows-1251", "Wrong character encoding"); + is(this.responseXML.documentElement.firstChild.data, "\u042E", "Decoded using the wrong encoding."); + is(this.responseText.indexOf("\u042E"), 51, "Bad responseText"); + SimpleTest.finish(); + } + } + xhr.open("GET", "file_bug692434.xml"); + xhr.send(); +} + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug693615.html b/dom/base/test/test_bug693615.html new file mode 100644 index 0000000000..7a9b39c064 --- /dev/null +++ b/dom/base/test/test_bug693615.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=693615 +--> +<head> + <title>Test for Bug 693615</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=693615">Mozilla Bug 693615</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 693615 **/ +/* +The following code tests if calling the DOM method Node::lookupNamespaceURI +directly (with quickstubs) and through XPCOM leads to the same result. +*/ + +var content = document.getElementById("content"); + +// called directly (quickstubs) +var defaultNS = content.lookupNamespaceURI(null); +is(defaultNS, null, "direct access working"); + +// called via XPCOM +// deleting the method from the prototype forces the engine to go through XPCOM +var proto = Object.getPrototypeOf(content); +delete(proto.lookupNamespaceURI); +var wrapperNS = content.lookupNamespaceURI(null); +is(wrapperNS, null, "access through XPCOM working"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug693875.html b/dom/base/test/test_bug693875.html new file mode 100644 index 0000000000..71741e2369 --- /dev/null +++ b/dom/base/test/test_bug693875.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=693875 +--> +<head> + <title>Test for Bug 693875</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=693875">Mozilla Bug 693875</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 693875 **/ + +var dp = new DOMParser(); +var d = dp.parseFromString("<?xml version='1.0'?><svg xmlns='http://www.w3.org/2000/svg'></svg>", + "image/svg+xml"); + +ok(d instanceof XMLDocument, "Should have created an XML document."); +ok("documentElement" in d, "Should have created an XML document, which has .documentElement."); +is(d.documentElement.localName, "svg", "Root element should be svg."); +is(d.documentElement.namespaceURI, "http://www.w3.org/2000/svg", + "Root element should be in svg namespace."); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug694754.xhtml b/dom/base/test/test_bug694754.xhtml new file mode 100644 index 0000000000..f688fb9c32 --- /dev/null +++ b/dom/base/test/test_bug694754.xhtml @@ -0,0 +1,70 @@ +<!DOCTYPE HTML> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:test="http://example.com/test"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=694754 +--> +<head> + <title>Test for Bug 694754</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=694754">Mozilla Bug 694754</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 694754 **/ +/* +The following code tests if calling the DOM methods Document::lookupNamespaceURI +and Document::lookupPrefix directly (with quickstubs) and through XPCOM leads +to the same result. + +This test makes use of the bug/feature that deleting a method from the +prototype forces the engine to go through XPCOM. +*/ + +// Document::lookupPrefix called directly (quickstubs) +var prefixDirect = document.lookupPrefix("http://example.com/test"); +is(prefixDirect, "test", + "calling Document::lookupPrefix through quickstubs works"); + +// Document::lookupPrefix called via XPCOM +var proto = Object.getPrototypeOf(document); +delete(proto.lookupPrefix); +var prefixThroughXPCOM = document.lookupPrefix("http://example.com/test"); +is(prefixThroughXPCOM, "test", + "calling Document::lookupPrefix through XPCOM works"); + + + +// Document::lookupNamespaceURI called directly (quickstubs) +var namespaceDirect = document.lookupNamespaceURI(null); +is(namespaceDirect, "http://www.w3.org/1999/xhtml", + "calling Document::lookupNamespaceURI through quickstubs works"); + +// Document::lookupNamespaceURI called via XPCOM +delete(proto.lookupNamespaceURI); +var namespaceThroughXPCOM = document.lookupNamespaceURI(null); +is(namespaceThroughXPCOM, "http://www.w3.org/1999/xhtml", + "calling Document::lookupNamespaceURI through XPCOM works"); + +// Document::isDefaultNamespace called directly (quickstubs) +var isDefaultNamespaceDirect = document.isDefaultNamespace("http://www.w3.org/1999/xhtml"); +is(isDefaultNamespaceDirect, true, + "Default namespace correctly detected through quickstubs"); + +// Document::isDefaultNamespace called via XPCOM +delete(proto.isDefaultNamespace); +var isDefaultNamespaceXPCOM = document.isDefaultNamespace("http://www.w3.org/1999/xhtml"); +is(isDefaultNamespaceXPCOM, true, + "Default namespace correctly detected through XPCOM"); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug696301-1.html b/dom/base/test/test_bug696301-1.html new file mode 100644 index 0000000000..2fb4c3c97c --- /dev/null +++ b/dom/base/test/test_bug696301-1.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=696301 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 696301</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +var errorFired = false; +var global = ""; +window.onerror = function(message, uri, line) { + is(message, "Script error.", "Should have empty error message"); + is(uri, + "http://example.com/tests/dom/base/test/bug696301-script-1.js", + "Should have correct script URI"); + is(line, 0, "Shouldn't have a line here"); + errorFired = true; +} +</script> +<script src="http://example.com/tests/dom/base/test/bug696301-script-1.js"></script> +<script> + is(errorFired, true, "Should have error in different origin script"); + is(global, "ran", "Different origin script should have run"); +</script> + +<script type="application/javascript"> +errorFired = false; +global = ""; +window.onerror = function(message, uri, line) { + is(message, "ReferenceError: c is not defined", "Should have correct error message"); + is(uri, + "http://example.com/tests/dom/base/test/bug696301-script-1.js", + "Should also have correct script URI"); + is(line, 3, "Should have a line here"); + errorFired = true; +} +</script> +<script src="http://example.com/tests/dom/base/test/bug696301-script-1.js" + crossorigin></script> +<script> + is(errorFired, true, "Should have error in different origin script with CORS"); + is(global, "ran", "Different origin script with CORS should have run"); +</script> + +<script type="application/javascript"> +errorFired = false; +global = ""; +window.addEventListener("error", function(e) { + is(Object.getPrototypeOf(e), Event.prototype, + "Object prototype should be Event"); + var externalScripts = document.querySelectorAll("script[src]"); + is(e.target, externalScripts[externalScripts.length - 1], + "Event's target should be the right <script>"); + errorFired = true; +}, true); +</script> +<script src="http://example.com/tests/dom/base/test/bug696301-script-2.js" + crossorigin></script> +<script> + is(errorFired, true, + "Should have error when different origin script fails CORS check"); + is(global, "", "Different origin script that fails CORS should not have run"); +</script> + +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug696301-2.html b/dom/base/test/test_bug696301-2.html new file mode 100644 index 0000000000..c27b8a5556 --- /dev/null +++ b/dom/base/test/test_bug696301-2.html @@ -0,0 +1,80 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=696301 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 696301</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<!-- Test SVG script here --> +<svg> +<script type="application/javascript"> +var errorFired = false; +var global = ""; +window.onerror = function(message, uri, line) { + is(message, "Script error.", "Should have empty error message"); + is(uri, + "http://example.com/tests/dom/base/test/bug696301-script-1.js", + "Should have correct script URI"); + is(line, 0, "Shouldn't have a line here"); + errorFired = true; +} +</script> +<script xlink:href="http://example.com/tests/dom/base/test/bug696301-script-1.js"></script> +<script> + is(errorFired, true, "Should have error in different origin script"); + is(global, "ran", "Different origin script should have run"); +</script> + +<script type="application/javascript"> +errorFired = false; +global = ""; +window.onerror = function(message, uri, line) { + is(message, "ReferenceError: c is not defined", "Should have correct error message"); + is(uri, + "http://example.com/tests/dom/base/test/bug696301-script-1.js", + "Should also have correct script URI"); + is(line, 3, "Should have a line here"); + errorFired = true; +} +</script> +<script xlink:href="http://example.com/tests/dom/base/test/bug696301-script-1.js" + crossorigin></script> +<script> + is(errorFired, true, "Should have error in different origin script with CORS"); + is(global, "ran", "Different origin script with CORS should have run"); +</script> + +<script type="application/javascript"> +errorFired = false; +global = ""; +window.addEventListener("error", function(e) { + is(Object.getPrototypeOf(e), Event.prototype, + "Object prototype should be Event"); + var scripts = document.querySelectorAll("script"); + is(e.target, scripts[scripts.length - 1], + "Event's target should be the right <script>"); + errorFired = true; +}, true); +</script> +<script xlink:href="http://example.com/tests/dom/base/test/bug696301-script-2.js" + crossorigin></script> +<script> + is(errorFired, true, + "Should have error when different origin script fails CORS check"); + is(global, "", "Different origin script that fails CORS should not have run"); +</script> +</svg> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug698381.html b/dom/base/test/test_bug698381.html new file mode 100644 index 0000000000..8396ba2623 --- /dev/null +++ b/dom/base/test/test_bug698381.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=698381 + --> + <head> + <title>Test for Bug 698381</title> + <script type="text/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js" + type="text/javascript"></script> + <link rel="stylesheet" type="text/css" + href="/tests/SimpleTest/test.css" /> + </head> + <body onload="runTests();"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=698381"> + Mozilla Bug 698381</a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <div id="noChildren" style="display: none"></div> + <div id="hasChildren" style="display: none"> + <div id="childOne" style="display: none"></div> + </div> + <pre id="test"> + <script type="text/javascript"> + /* + Checks to see if default parameter handling is correct when 0 + parameters are passed. + + If none are passed, then Node.cloneNode should default aDeep + to true. + */ + SimpleTest.waitForExplicitFinish(); + + var hasChildren = document.getElementById("hasChildren"), + noChildren = document.getElementById("noChildren"), + clonedNode; + + function runTests() { + + // Test Node.cloneNode when no arguments are given + clonedNode = hasChildren.cloneNode(); + is(clonedNode.hasChildNodes(), false, "Node.cloneNode with false " + + "default on a node with children does not clone the child nodes."); + + clonedNode = noChildren.cloneNode(); + is(clonedNode.hasChildNodes(), false, "Node.cloneNode with false " + + "default on a node without children doesn't clone child nodes." ); + + SimpleTest.finish(); + } + </script> + </pre> + </body> +</html> diff --git a/dom/base/test/test_bug698384.html b/dom/base/test/test_bug698384.html new file mode 100644 index 0000000000..f55a5f7f98 --- /dev/null +++ b/dom/base/test/test_bug698384.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=698384 + --> + <head> + <title>Test for Bug 698384</title> + <script type="text/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js" + type="text/javascript"></script> + <link rel="stylesheet" type="text/css" + href="/tests/SimpleTest/test.css" /> + </head> + <body onload="runTests();"> + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=698384"> + Mozilla Bug 698384</a> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"> + <script type="text/javascript"> + /* + Checks to see if default parameter handling is correct when 0, 1 + or 2 parameters are passed. + + If one is only passed, aFilter should default to null + If none are passed, aFilter should be null and aWhatToShow should + be NodeFilter.SHOW_ALL + */ + SimpleTest.waitForExplicitFinish(); + + var content = $('content'), + ni; + + content.innerHTML = ('<span id="A"><\/span><span id="B"><\/span>' + + '<span id="C"><\/span>'); + + function runTests() { + + // Test NodeIterator when no optional arguments are given + ni = document.createNodeIterator(content); + is(ni.whatToShow, NodeFilter.SHOW_ALL, "whatToShow should be " + + "NodeFilter.SHOW_ALL when both " + + " optionals are not given"); + is(ni.filter, null, "filter should be defaulted to null when both " + + " optionals are not given"); + + // Test NodeIterator when first optional is passed + ni = document.createNodeIterator(content, NodeFilter.SHOW_ELEMENT); + is(ni.filter, null, "filter should be defaulted to null when only " + + " first argument is passed"); + is(ni.whatToShow, NodeFilter.SHOW_ELEMENT, "whatToShow should " + + "properly be set to NodeFilter.SHOW_ELEMENT when whatToShow is " + + "provided and filter is not"); + + SimpleTest.finish(); + } + </script> + </pre> + </body> +</html> diff --git a/dom/base/test/test_bug704063.html b/dom/base/test/test_bug704063.html new file mode 100644 index 0000000000..39759f1543 --- /dev/null +++ b/dom/base/test/test_bug704063.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id= +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug </title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug **/ + SimpleTest.waitForExplicitFinish(); + var firstRan = false; + var secondRan = false; + function second(time) { + is(firstRan, true, "We were called second"); + secondRan = true; + ok(Math.abs(time - performance.now()) < 3600000, + "An hour really shouldn't have passed here"); + ok(Math.abs(time - Date.now()) > 3600000, + "More than an hour should have passed since 1970"); + } + function first(time) { + is(secondRan, false, "second() was called first"); + firstRan = true; + ok(Math.abs(time - performance.now()) < 3600000, + "An hour really shouldn't have passed here either"); + ok(Math.abs(time - Date.now()) > 3600000, + "More than an hour should have passed since 1970 here either"); + } + function third() { + ok(firstRan, "We should be after the first call"); + ok(secondRan, "We should be after the second call"); + SimpleTest.finish(); + } + + window.onload = function() { + window.requestAnimationFrame(first); + window.requestAnimationFrame(second); + window.requestAnimationFrame(third); + } + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug704320.html b/dom/base/test/test_bug704320.html new file mode 100644 index 0000000000..5c8e46c03d --- /dev/null +++ b/dom/base/test/test_bug704320.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=704320 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 704320</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="referrerHelper.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script type="application/javascript;version=1.7"> + +//generates URLs to test +var generateURLArray = (function(from, to){ + const baseURL = '://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from='; + const schemeTo = '&scheme-to='; + + return [ + from + baseURL + from + schemeTo + to + '&policy=no-referrer-when-downgrade', + from + baseURL + from + schemeTo + to + '&policy=no-referrer', + from + baseURL + from + schemeTo + to + '&policy=unsafe-url', + from + baseURL + from + schemeTo + to + '&policy=origin', + from + baseURL + from + schemeTo + to + '&policy=origin-when-cross-origin', + from + baseURL + from + schemeTo + to + '&policy=same-origin', + from + baseURL + from + schemeTo + to + '&policy=strict-origin', + from + baseURL + from + schemeTo + to + '&policy=strict-origin-when-cross-origin', + ]; +}); + +var testIframeUrls = generateURLArray('http', 'http'); +testIframeUrls = testIframeUrls.concat(generateURLArray('https', 'https')); +testIframeUrls = testIframeUrls.concat(generateURLArray('http', 'https')); +testIframeUrls = testIframeUrls.concat(generateURLArray('https', 'http')); + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * This is the main test routine -- serialized by use of a generator. + * It performs all tests in sequence using in the same iframe. + */ +var tests = (function() { + SimpleTest.requestLongerTimeout(4); + var iframe = document.getElementById("testframe"); + iframe.onload = function() { + advance(); + } + + // load the test frame from testIframeUrls[url] + // it will call back into this function via postMessage when it finishes loading. + // and continue beyond the yield. + for(url in testIframeUrls) { + yield iframe.src = testIframeUrls[url]; + // run test and check result for loaded test URL + yield checkExpectedGlobalResults(); + } + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=704320">Mozilla Bug 704320 - HTTP/HTTPS to HTTPS/HTTP</a> +<p id="display"></p> +<pre id="content"> +</pre> + <iframe id="testframe"></iframe> + +</body> diff --git a/dom/base/test/test_bug704320_policyset.html b/dom/base/test/test_bug704320_policyset.html new file mode 100644 index 0000000000..8188a94806 --- /dev/null +++ b/dom/base/test/test_bug704320_policyset.html @@ -0,0 +1,104 @@ +<!DOCTYPE HTML> +<html> +<!-- +This checks if the right policies are applied from a given string (including whitespace, invalid policy strings, etc). It doesn't do a complete check for all load types; that's done in another test. +https://bugzilla.mozilla.org/show_bug.cgi?id=704320 +--> + +<head> + <meta charset="utf-8"> + <title>Test policies for Bug 704320</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="referrerHelper.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * This is the main test routine -- serialized by use of a generator. + * It resets the counter, then performs two tests in sequence using + * the same iframe. + */ +var tests = (function() { + var iframe = document.getElementById("testframe"); + const sjs = "/tests/dom/base/test/bug704320.sjs?action=generate-policy-test"; + + + // basic calibration check + // reset the counter + yield resetCounter(); + + // load the first test frame + // it will call back into this function via postMessage when it finishes loading. + // and continue beyond the yield. + yield iframe.src = sjs + "&policy=" + escape('default'); + + // check the first test (two images, no referrers) + yield checkIndividualResults("default", ["full"]); + + // check invalid policy + // According to the spec section Determine token's Policy,if there is a policy + // token and it is not one of the expected tokens, Empty string should be the + // policy used. + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape('invalid-policy'); + yield checkIndividualResults("invalid", ["full"]); + + // whitespace checks. + // according to the spec section 4.1, the content attribute's value + // is fed to the token policy algorithm after stripping leading and + // trailing whitespace. + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape('default '); + yield checkIndividualResults("trailing whitespace", ["full"]); + + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape(' origin\f'); + yield checkIndividualResults("trailing form feed", ["origin"]); + + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape('\f origin'); + yield checkIndividualResults("leading form feed", ["origin"]); + + // origin when cross-origin (trimming whitespace) + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape(' origin-when-cross-origin'); + yield checkIndividualResults("origin-when-cross-origin", ["origin", "full"]); + + // according to the spec section 4.1: + // "If the meta element lacks a content attribute, or if that attribute’s + // value is the empty string, then abort these steps." + // This means empty or missing content attribute means to ignore the meta + // tag and use default policy. + // Whitespace here is space, tab, LF, FF and CR. + // http://www.w3.org/html/wg/drafts/html/CR/infrastructure.html#space-character + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape(' \t '); + yield checkIndividualResults("basic whitespace only policy", ["full"]); + + // and double-check that no-referrer works. + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape('no-referrer'); + yield checkIndividualResults("no-referrer", ["none"]); + + // Case insensitive + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape('\f OrigIn'); + yield checkIndividualResults("origin case insensitive", ["origin"]); + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> + diff --git a/dom/base/test/test_bug704320_policyset2.html b/dom/base/test/test_bug704320_policyset2.html new file mode 100644 index 0000000000..b9cc74e3d7 --- /dev/null +++ b/dom/base/test/test_bug704320_policyset2.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +This checks if the right policies are applied from a given string (including whitespace, invalid policy strings, etc). It doesn't do a complete check for all load types; that's done in another test. +https://bugzilla.mozilla.org/show_bug.cgi?id=704320 +--> + +<head> + <meta charset="utf-8"> + <title>Test policies for Bug 704320</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="referrerHelper.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * This is the main test routine -- serialized by use of a generator. + * It resets the counter, then performs two tests in sequence using + * the same iframe. + */ +var tests = (function() { + var iframe = document.getElementById("testframe"); + const sjs = "/tests/dom/base/test/bug704320.sjs?action=generate-policy-test"; + + yield resetCounter(); + yield iframe.src = sjs + "&policy=" + escape(' \f\r\n\t '); + yield checkIndividualResults("whitespace only policy", ["full"]); + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> + diff --git a/dom/base/test/test_bug704320_preload.html b/dom/base/test/test_bug704320_preload.html new file mode 100644 index 0000000000..d7f2fc72d3 --- /dev/null +++ b/dom/base/test/test_bug704320_preload.html @@ -0,0 +1,145 @@ +<!DOCTYPE HTML> +<html> +<!-- +This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed. +https://bugzilla.mozilla.org/show_bug.cgi?id=704320 +--> + +<head> + <meta charset="utf-8"> + <title>Test preloads for Bug 704320</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="referrerHelper.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * This is the main test routine -- serialized by use of a generator. + * It resets the counter, then performs two tests in sequence using + * the same iframe. + */ +var tests = (function() { + var iframe = document.getElementById("testframe"); + + // reset the counter + yield resetCounter(); + + // load the first test frame + // it will call back into this function via postMessage when it finishes loading. + // and continue beyond the yield. + yield iframe.src = 'file_bug704320_preload_noreuse.html'; + + // check the first test + yield checkResults(finalizePreloadNoreuse); + + // reset the counter + yield resetCounter(); + + // load the second test frame + // it will call back into this function via postMessage when it finishes loading. + // and continue beyond the yield. + yield iframe.src = 'file_bug704320_preload_reuse.html'; + + // check the second test + yield checkResults(finalizePreloadReuse); + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +// Helper functions below. + +/** + * This checks the first test: a test where the preloads should not + * be reused. * we expect two requests for each image, script, js request + * since the referrer policy changed after speculative loads were started. + * Problem is that the "origin"/revised loads won't necessarily happen, + * so we test for one or two loads (both are OK) and make the 'origin' + * referrer optional. + */ +function finalizePreloadNoreuse(results) { + console.log("<br/><pre>" + JSON.stringify(results) + "</pre>"); + var expected = {'css': {'count': 2, 'referrers': ['full', 'origin']}, + 'img': {'count': 2, 'referrers': ['full', 'origin']}, + 'js': {'count': 2, 'referrers': ['full', 'origin']}}; + + for (var x in expected) { + ok(x in results, "some " + x + " loads required in results object."); + + ok(results[x].count == 1 || results[x].count == 2, + "Expected 1-2 loads for " + x + " requests."); + + // the 'full' preload is optional, but required if count > 1 + if (results[x].count > 1) { + ok(results[x].referrers.indexOf('full') >= 0, + "More than one load for " + x + ", so expected an 'full' referrer preload.") + } + + // 'origin' (final load) is required + ok(results[x].referrers.indexOf('origin') >= 0, + "One load for " + x + " should have had 'origin' referrer."); + + // no other values should be in the referrers. + is(results[x].referrers.indexOf('none'), -1, + "No loads for " + x + " should have a missing referrer."); + } + + advance(); +} + +/** + * This checks the second test: a test where preloads SHOULD be reused. + * We expect one request for each image, script, js request since + * the referrer policy does not change after speculative loads. + */ +function finalizePreloadReuse(results) { + var expected = {'css': {'count': 1, 'referrers': ['origin']}, + 'img': {'count': 1, 'referrers': ['origin']}, + 'js': {'count': 1, 'referrers': ['origin']}}; + + for (var x in expected) { + ok(x in results, "some " + x + " loads required in results object."); + + is(results[x].count, expected[x].count, + "Expected " + expected[x].count + " loads for " + x + " requests."); + + // 'origin' is required + ok(results[x].referrers.indexOf('origin') >= 0, + "One load for " + x + " should have had 'origin' referrer."); + + // no other values should be in the referrers. + is(results[x].referrers.indexOf('none'), -1, + "No loads for " + x + " should have a missing referrer."); + is(results[x].referrers.indexOf('full'), -1, + "No loads for " + x + " should have an 'full' referrer.") + } + + advance(); +} + + +/** + * Grabs the results via XHR and passes to checker. + */ +function checkResults(checker) { + doXHR('/tests/dom/base/test/bug704320_counter.sjs?results', + function(xhr) { + checker(JSON.parse(xhr.responseText)); + }, + function(xhr) { + ok(false, "Can't get results from the counter server."); + }); +} + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> diff --git a/dom/base/test/test_bug707142.html b/dom/base/test/test_bug707142.html new file mode 100644 index 0000000000..2cde32fd58 --- /dev/null +++ b/dom/base/test/test_bug707142.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=707142 +--> +<head> + <title>Test for Bug 707142</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=707142">Mozilla Bug 707142</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 707142 **/ + +SimpleTest.waitForExplicitFinish(); + +var xhr = new XMLHttpRequest(); +xhr.onload = function() { + is(xhr.response["foo"], "bar", "Should have gotten bar on baseline"); + + xhr.onload = function() { + is(xhr.response["foo"], "bar", "Should have gotten bar with BOM"); + + xhr.onload = function() { + is(xhr.response, null, "Should have gotten null response with UTF-16 JSON"); + + SimpleTest.finish(); + }; + xhr.open("GET", "file_bug707142_utf-16.json"); + xhr.responseType = "json"; + xhr.send(); + }; + xhr.open("GET", "file_bug707142_bom.json"); + xhr.responseType = "json"; + xhr.send(); +}; +xhr.open("GET", "file_bug707142_baseline.json"); +xhr.responseType = "json"; +xhr.send(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug708620.html b/dom/base/test/test_bug708620.html new file mode 100644 index 0000000000..d6b5b0c6d8 --- /dev/null +++ b/dom/base/test/test_bug708620.html @@ -0,0 +1,41 @@ +<!doctype html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=708620 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 708620</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=708620" + >Mozilla Bug 708620</a> +<iframe></iframe> +<script> +/** Test for Bug 708620 **/ + +SimpleTest.waitForExplicitFinish(); +SimpleTest.monitorConsole(SimpleTest.finish, [ + { errorMessage: "A form was submitted in the windows-1252 encoding "+ + "which cannot encode all Unicode characters, so user "+ + "input may get corrupted. To avoid this problem, the "+ + "page should be changed so that the form is submitted "+ + "in the UTF-8 encoding either by changing the encoding "+ + "of the page itself to UTF-8 or by specifying "+ + "accept-charset=utf-8 on the form element.", + isWarning: true } +]); + +window.onload = function () { + document.getElementsByTagName("iframe")[0].src = "file_bug708620.html"; +} + +function finish() { + SimpleTest.endMonitorConsole(); +} +</script> +</body> +</html> diff --git a/dom/base/test/test_bug711047.html b/dom/base/test/test_bug711047.html new file mode 100644 index 0000000000..65bc20c35f --- /dev/null +++ b/dom/base/test/test_bug711047.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=711047 +--> +<title>Test for Bug 711047</title> +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=711047">Mozilla Bug 711047</a> +<div id="content"> +</div> +<pre id="test"> +<script> +/** Test for Bug 711047 **/ +ok(!("RangeException" in window), "RangeException shouldn't exist"); +</script> +</pre> diff --git a/dom/base/test/test_bug711180.html b/dom/base/test/test_bug711180.html new file mode 100644 index 0000000000..c92be3dd18 --- /dev/null +++ b/dom/base/test/test_bug711180.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=711180 +--> +<head> + <title>Test for Bug 711180</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=711180">Mozilla Bug 711180</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 711180 **/ +is(atob("aQ=="), atob("\t a\rQ\n=\f="), "Base64 space removal"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug715041.xul b/dom/base/test/test_bug715041.xul new file mode 100644 index 0000000000..c269b461b2 --- /dev/null +++ b/dom/base/test/test_bug715041.xul @@ -0,0 +1,815 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=715041 +--> + <window title="Mozilla Bug 715041" +xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=715041" +target="_blank">Mozilla Bug 715041</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Mock Idle Service Test for Bug 715041 **/ + //class mock javascript idle service + var idleServiceObj = { + observers: [], + windowObservers: [], + idleTimeInMS: 5000, //in milli seconds + + // takes note of the idle observers added as the minimum idle observer + // with the idle service + timesAdded: [], + + QueryInterface: function(iid) { + if (iid.equals(Components.interfaces.nsISupports) || + iid.equals(Components.interfaces.nsIFactory) || + iid.equals(Components.interfaces.nsIIdleService)) { + return this; + } + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + + createInstance: function(outer, iid) { + return this.QueryInterface(iid); + }, + + get idleTime() { + return this.idleTimeInMS; //in milli seconds + }, + + set idleTime(timeInMS) { + this.idleTimeInMS = timeInMS; + }, + + getWindowFromObserver: function(observer) { + try { + var interfaceRequestor = observer.QueryInterface(Components.interfaces.nsIInterfaceRequestor); + var window = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); + return window; + } + catch (e) {} + + return null; + }, + + testIdleBackService: function(observer, topic) { + dump("\nJS FAKE IDLE SERVICE\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + + if (this.observers.length > 1) { + this.observers[1].observer.observe(observer, topic, '\0'); + dump("JS CALLED OBSERVE FUNCTION!!!\n\n"); + } + }, + + addIdleObserver: function(observer, time) { + dump("\nJS FAKE IDLE SERVICE add idle observer before\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + + var window = this.getWindowFromObserver(observer); + dump("window is: " + window + "\n"); + + if (window) { + this.observers.push({ observer: observer, time: time, }); + addedIdleObserver = true; + numIdleObserversAdded++; + this.timesAdded.push(time); + + dump ("\nMOCK IDLE SERVICE ADDING idle observer with time: " + time + "\n"); + dump("MOCK IDLE SERVICE: num idle observers added: " + numIdleObserversAdded + "\n\n"); + } + else { + dump("SHOULD NEVER GET HERE!"); + oldIdleService.addIdleObserver(observer, time); + addedIdleObserver = false; + } + + dump("\nJS FAKE IDLE SERVICE end of add idle observer\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + }, + + removeIdleObserver: function(observer, time) { + dump("\nJS REMOVE IDLE OBSERVER () time to be removed: " + time + "\n"); + var window = this.getWindowFromObserver(observer); + if (!window) { + oldIdleService.removeIdleObserver(observer, time); + } + else { + var observerIndex = -1; + for (var i=0; i<this.observers.length; i++) { + dump("JS removeIdleObserver() observer time: " + this.observers[i].time + "\n"); + if (this.observers[i].time === time) { + observerIndex = i; + break; + } + } + + if (observerIndex != -1 && this.observers.length > 0) { + numIdleObserversRemoved++; + this.observers.splice(observerIndex, 1); + removedIdleObserver = true; + dump("MOCK IDLE SERVICE REMOVING idle observer with time " + time + "\n"); + dump("MOCK IDLE SERVICE numIdleObserversRemoved: " + numIdleObserversRemoved + " numIdleObserversAdded: " + numIdleObserversAdded + "\n\n"); + } + else { + removedIdleObserver = false; + } + } + dump("\nJS FAKE IDLE SERVICE end of remove idle observer\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + }, + }; + + /** Test for Bug 715041 **/ + dump("\n\n\nJS STARTING TESTING FOR BUG 715041\n"); + + //bool variables + var addedIdleObserver = removedIdleObserver = passed = cleanUp = false; + + //test case enabled + var AddOutOfOrderActiveEnabled = AddOutOfOrderIdleEnabled = + AddShiftLocalEnabled = AddNewLocalWhileAllIdleEnabled = + TestActiveToActiveNotification = ShiftLocalTimerBackEnabled = + AddRemoveIdleObserverWithInvalidTimeEnabled = true; + + //msgXCount + var msg0Count = msg1Count = msg2Count = msg3Count = msg4Count = msg5Count = + msg6Count = tcZero = currTestCaseNum = prevMsgNum = + numIdleObserversRemoved = numIdleObserversAdded = 0; + + //test case number + var tcZero = 0; + var tcAddOutOfOrderActive = 1; + var tcAddOutOfOrderIdle = 2; + var tcAddShiftLocal = 3; + var tcAddNewLocalWhileAllIdle = 4; + var tcShiftLocalTimerBack = 5; + var tcAddRemoveIdleObserverWithInvalidTime = 6; + var tcTestActiveToActiveNotification = 7; + + function ResetMsgCounts() { + msg0Count = msg1Count = msg2Count = msg3Count = msg4Count = msg5Count = + msg6Count = prevMsgNum = 0; + } + + function ResetVars() { + msg0Count = msg1Count = msg2Count = msg3Count = msg4Count = msg5Count = + msg6Count = prevMsgNum = 0; + + numIdleObserversAdded = numIdleObserversRemoved = 0; + currTestCaseNum = -1; + addedIdleObserver = removedIdleObserver = passed = cleanUp = false; + } + + /* + * - function printMsgCounts() + */ + function printMsgCounts() { + dump("\nmsg0Count: " + msg0Count + + "\nmsg1Count: " + msg1Count + + "\nmsg2Count: " + msg2Count + + "\nmsg3Count: " + msg3Count + + "\nmsg5Count: " + msg5Count + + "\nmsg6Count: " + msg6Count + + "\n" + ); + } + + function performNextTest() { + dump("\nfunction performNextTest()\ncurrTestCaseNum: " + currTestCaseNum + + "\ncleanUp: " + cleanUp + + "\npassed: " + passed + + "\nnumIdleObserversRemoved: " + numIdleObserversRemoved + + "\nnumIdleObservesAdded: " + numIdleObserversAdded + "\n"); + + switch (currTestCaseNum) { + case tcZero: + ok(passed, "Test case 0 failed clean up!"); + caseZeroCleanUp(); + break; + case tcAddShiftLocal: + if (cleanUp && numIdleObserversRemoved === 1) { + passed = true; + ok(passed, "Failed test case AddShiftLocalCleanUp()"); + if (AddNewLocalWhileAllIdleEnabled) { + AddNewLocalWhileAllIdle(); + } + else { + SimpleTest.finish(); + } + } + break; + case tcAddNewLocalWhileAllIdle: + ok(passed, "Failed test case: AddNewLocalWhileAllIdle()"); + AddNewLocalWhileAllIdleCleanUp(); + break; + default: + //do nothing. + break; + } + } + + //Place Holder. + var idleHandler0 = function() { dump("rmsg 0, should never be used!\n"); }; + + //idleHandler1 + function idleHandler1() { + msg1Count++; + dump("msg 1 Count: " + msg1Count + "\n"); + + switch (currTestCaseNum) { + case tcAddOutOfOrderIdle: + if (msg1Count === 1 && msg2Count === 1 && msg3Count === 1) { + idleServiceObj.idleTime = 0; + idleServiceObj.testIdleBackService(idleObserversArray[1], "active"); + } + else if (msg1Count === 4 && msg2Count === 4 && msg3Count === 4) { + passed = true; + AddOutOfOrderIdleCleanUp(); + } + break; + case tcTestActiveToActiveNotification: + if (msg1Count === 1 && !msg2Count && !msg3Count && !msg4Count && !msg5Count) { + idleServiceObj.idleTime = 500; + idleServiceObj.testIdleBackService(idleObserversArray[1], "active"); + return; + } + + if (msg1Count === 2 && !msg2Count && !msg3Count && !msg4Count && !msg5Count) { + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + return; + } + + if (msg1Count === 3 && !msg2Count && !msg3Count && !msg4Count && !msg5Count) { + return; + } + ok(false, "Failed test active to active notification."); + SimpleTest.finish(); + break; + default: + break; + } + } + + //idleHandler2 + function idleHandler2() { + msg2Count++; + dump("msg 2 Count: " + msg2Count + "\n"); + + switch (currTestCaseNum) { + case tcZero: + switch (msg2Count) { + case 2: + passed = true; + performNextTest(); + break; + default: + break; + } + break; + case tcAddOutOfOrderIdle: + if (msg3Count === 1 && msg2Count === 1 && !msg1Count) { + idleServiceObj.idleTime = 4000; + window.navigator.addIdleObserver(idleObserversArray[1]); + } + break; + case tcAddShiftLocal: + if (!msg1Count && msg2Count === 1 && !msg3Count && !msg4Count) { + window.navigator.addIdleObserver(idleObserversArray[3]); + } + AddShiftLocalCleanUp(); + break; + case tcAddNewLocalWhileAllIdle: + if (msg1Count === 1 && msg2Count === 2) { + idleServiceObj.idleTime = 3500; + window.navigator.addIdleObserver(idleObserversArray[5]); + } + break; + case (tcShiftLocalTimerBack): + if (!msg1Count && msg2Count === 1 && !msg3Count && !msg4Count && !msg5Count) { + window.navigator.addIdleObserver(idleObserversArray[5]); + window.navigator.addIdleObserver(idleObserversArray[4]); + } + break; + default: + //do nothing. + break; + } + } + + //idleHandler3 + function idleHandler3() { + msg3Count++; + dump("msg 3 Count: " + msg3Count + "\n"); + + switch (currTestCaseNum) { + case (tcAddOutOfOrderIdle): + if (msg3Count === 1) { + idleServiceObj.idleTime = 3500; + window.navigator.addIdleObserver(idleObserversArray[2]); + } + if (msg1Count === 2 && msg2Count === 2 && msg3Count === 2) { + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + else if (msg1Count === 3 && msg2Count === 3 && msg3Count === 3) { + AddOutOfOrderIdle(); + } + else if (msg1Count === 3 && msg2Count === 3 && msg3Count === 4) { + passed = true; + AddOutOfOrderIdleCleanUp(); + } + break; + default: + break; + } + } + + //idleHandler4 + function idleHandler4() { + msg4Count++; + dump("msg 4 Count: " + msg4Count + "\n"); + + switch (currTestCaseNum) { + case tcAddOutOfOrderActive: + if (msg1Count && msg2Count && msg3Count && msg4Count) { + passed = true; + ok(passed, "idleHandler4: failed AddOutOfOrderActive()"); + AddOutOfOrderActiveCleanUp(); + cleanUp = true; + } + break; + case tcAddShiftLocal: + if (msg1Count === 1 && msg3Count === 1 && msg4Count === 1) { + idleServiceObj.idleTime = 3200; + window.navigator.addIdleObserver(idleObserversArray[2]); + } + break; + default: + //do nothing. + break; + } + } + + //idleHandler5 + function idleHandler5() { + msg5Count++; + dump("msg 5 Count: " + msg5Count + "\n"); + + switch (currTestCaseNum) { + case tcAddNewLocalWhileAllIdle: + if (msg1Count === 1 && msg2Count === 2 && msg5Count === 1) { + passed = true; + performNextTest(); + } + break; + case tcShiftLocalTimerBack: + if (!msg1Count && msg2Count === 1 && !msg3Count && msg4Count === 1 && msg5Count === 1) { + passed = true; + ShiftLocalTimerBackCleanUp(); + } + break; + case tcTestActiveToActiveNotification: + passed = false; + if (msg1Count === 3 && !msg2Count && !msg3Count && !msg4Count && msg5Count === 1) { + passed = true; + } + ok(passed, "Failed TestActiveToActiveNotification."); + TestActiveNotificationCleanUp(); + break; + default: + //do nothing. + break; + } + } + + //idleHandler6 + function idleHandler6() { + dump("msg 6 Count: " + msg6Count + "\n"); + } + + var idleObserversArray = []; + idleObserversArray[0] = {time: 0, onidle: idleHandler0, onactive: idleHandler0}; + idleObserversArray[1] = {time: 1, onidle: idleHandler1, onactive: idleHandler1}; + idleObserversArray[2] = {time: 2, onidle: idleHandler2, onactive: idleHandler2}; + idleObserversArray[3] = {time: 3, onidle: idleHandler3, onactive: idleHandler3}; + idleObserversArray[4] = {time: 4, onidle: idleHandler4, onactive: idleHandler4}; + idleObserversArray[5] = {time: 5, onidle: idleHandler5, onactive: idleHandler5}; + idleObserversArray[6] = {time: 0, onidle: idleHandler6, onactive: idleHandler6}; + idleObserversArray[7] = {time: 2, onidle: null, onactive: null}; + + idleServiceObj.observers.push( {observer: idleObserversArray[0], time: 0, } ); + + /* + * - case 0 + * - AddSingleIdleObserver + * - takes care of adding duplicate local too + * - user is currently idle since the + * requested idle time of 2s < current idle time of 5000ms set below. + */ + function caseZero() { + dump("\n\nTESTING CASE 0\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcZero; + idleServiceObj.idleTime = 5000; + + window.navigator.addIdleObserver(idleObserversArray[2]); + idleServiceObj.testIdleBackService(idleObserversArray[2], "idle"); + window.navigator.addIdleObserver(idleObserversArray[2]); + } + + function caseZeroCleanUp() { + dump("\ncaseZeroCleanUp()\n"); + dump("==============\n"); + ResetVars(); + currTestCaseNum = tcZero; + cleanUp = false; + + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[2]); + + if (AddOutOfOrderActiveEnabled) { + AddOutOfOrderActive(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + /* + AddOutOfOrderActive() + - Tests if the idle observer with the min time is always registered correctly + with the idle service. + */ + function AddOutOfOrderActive() { + dump("\n\nTESTING CASE AddOutOfOrderActive\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcAddOutOfOrderActive; + idleServiceObj.idleTime = 500; + + window.navigator.addIdleObserver(idleObserversArray[3]); //msg3 + window.navigator.addIdleObserver(idleObserversArray[4]); //msg4 + window.navigator.addIdleObserver(idleObserversArray[1]); //msg1 + window.navigator.addIdleObserver(idleObserversArray[2]); //msg2 + passed = false; + + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + /* + - AddOutOfOrderActiveCleanUp() + */ + function AddOutOfOrderActiveCleanUp() { + dump("\nAddOutOfOrderActiveCleanUp()\n"); + dump("==============================\n"); + ResetVars(); + currTestCaseNum = tcAddOutOfOrderActive; + cleanUp = false; + idleServiceObj.idleTime = 4500; + + for (var i=1; i<5; i++) { + window.navigator.removeIdleObserver(idleObserversArray[i]); + } + dump("JS AddOutOfOrderActiveCleanUp() DONE\n"); + if (AddOutOfOrderIdleEnabled) { + AddOutOfOrderIdle(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + /* + - AddOutOfOrderIdle() + */ + function AddOutOfOrderIdle() { + dump("\nAddOutOfOrderIdle()\n"); + dump("======================================================================\n"); + + dump("\nJS AddOutOfOrderIdle\n"); + dump("JS NUM OBSERVERS: " + idleServiceObj.observers.length + "\n"); + + if (!msg1Count && !msg2Count && !msg3Count) { + ResetVars(); + } + currTestCaseNum = tcAddOutOfOrderIdle; + cleanUp = false; + + if (!msg1Count && !msg2Count && !msg3Count) { + idleServiceObj.idleTime = 3100; + } + window.navigator.addIdleObserver(idleObserversArray[3]); + if (!msg1Count && !msg2Count && !msg3Count) { + idleServiceObj.testIdleBackService(idleObserversArray[3], "idle"); + } + } + + /* + - AddOutOfOrderIdleCleanUp() + */ + function AddOutOfOrderIdleCleanUp() { + ok(passed, "Failed test case: AddOutOfOrderIdle()"); + dump("\nAddOutOfOrderIdleCleanUp()\n"); + dump("==========================\n"); + ResetVars(); + currTestCaseNum = tcAddOutOfOrderIdle; + cleanUp = true; + idleServiceObj.idleTime = 4100; + + for (var j=1; j<4; j++) { + window.navigator.removeIdleObserver(idleObserversArray[j]); + } + window.navigator.removeIdleObserver(idleObserversArray[3]); + + if (idleServiceObj.observers.length === 1) { + passed = true; + } + else { + passed = false; + } + ok(passed, "Failed test case: AddOutOfOrderIdleCleanUp()"); + if (AddShiftLocalEnabled) { + AddShiftLocal(); + } + else { + dump("Finished AddOutOfOrderIdleCleanUp() test.\n"); + SimpleTest.finish(); + } + } + + /* + * function AddShiftLocal() + * - user is idle + * - check that local idle timer is shifted correctly + * - msg 1 fired when user is idle + * - msg 3 fired when 3000 + * - msg 2 fired immediately when added at 3200 ms + * - msg 4 fired by local timer. + */ + function AddShiftLocal() + { + dump("\n\nTESTING CASE AddShiftLocal\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcAddShiftLocal; + idleServiceObj.idleTime = 500; + + window.navigator.addIdleObserver(idleObserversArray[1]); + window.navigator.addIdleObserver(idleObserversArray[3]); + window.navigator.addIdleObserver(idleObserversArray[4]); + + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + /* + * function AddShiftLocalCleanUp() + */ + function AddShiftLocalCleanUp() + { + dump("\n\nTESTING CASE AddShiftLocalCleanUp\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcAddShiftLocal; + + for (var i=1; i<5; i++) { + window.navigator.removeIdleObserver(idleObserversArray[i]); + } + dump("AddShiftLocalCleanUp() done clean up\n"); + if (AddNewLocalWhileAllIdleEnabled) { + AddNewLocalWhileAllIdle(); + } + else { + dump("Finished testing AddShiftLocal()\n"); + SimpleTest.finish(); + } + } + + /* + * AddNewLocalWhileAllIdle() + * - no local idle timer exists because all of the idle observers that were added had a requested + * idle time of < curr user idle time and so were fired immediately. No local timer was required. + * - now add an idle observer whose requested idle time is > current use idle time and > min idle + * requested time in the list of idle observers. + */ + function AddNewLocalWhileAllIdle() + { + dump("\n\nTESTING CASE AddNewLocalWhileAllIdle\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcAddNewLocalWhileAllIdle; + idleServiceObj.idleTime = 500; + + window.navigator.addIdleObserver(idleObserversArray[1]); + window.navigator.addIdleObserver(idleObserversArray[2]); + window.navigator.addIdleObserver(idleObserversArray[2]); + + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function AddNewLocalWhileAllIdleCleanUp() + { + dump("\n\nTESTING CASE AddNewLocalWhileAllIdleCleanUp\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcAddNewLocalWhileAllIdle; + + window.navigator.removeIdleObserver(idleObserversArray[1]); + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[5]); + + if (ShiftLocalTimerBackEnabled) { + ShiftLocalTimerBack(); + } + else { + dump("Finished testing TestActiveToActiveNotificationCleanUp()\n"); + SimpleTest.finish(); + } + } + + /* + * ShiftLocalTimerBack() + * - add a new idle observer whose requested time is > current user idle time + * but < the current local timer that has been set. + * - the local timer will need to be reset to fire the new msg added. + * RESULT + * - should print all of them in order + */ + function ShiftLocalTimerBack() + { + dump("\n\nTESTING CASE ShiftLocalTimerBack()\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcShiftLocalTimerBack; + idleServiceObj.idleTime = 2100; + + window.navigator.addIdleObserver(idleObserversArray[2]); + idleServiceObj.testIdleBackService(idleObserversArray[2], "idle"); + } + + function ShiftLocalTimerBackCleanUp() + { + dump("\n\nTESTING CASE ShiftLocalTimerBackCleanUp\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcShiftLocalTimerBack; + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[4]); + window.navigator.removeIdleObserver(idleObserversArray[5]); + dump("ShiftLocalTimerBackCleanUp() done clean up\n"); + + if (TestActiveToActiveNotificationEnabled) { + TestActiveNotification(); + } + else { + dump("Finished testing AddNewLocalWhileAllIdle()\n"); + SimpleTest.finish(); + } + } + + function TestActiveNotification() + { + dump("\n\nTESTING CASE TestActiveNotification\n"); + dump("===============================================\n"); + + ResetVars(); + currTestCaseNum = tcTestActiveToActiveNotification; + + idleServiceObj.idleTime = 500; + window.navigator.addIdleObserver(idleObserversArray[1]); + window.navigator.addIdleObserver(idleObserversArray[5]); + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function TestActiveNotificationCleanUp() + { + dump("\n\nTESTING CASE TestActiveNotificationCleanUp\n"); + dump("===============================================\n"); + + try { + componentMgr.unregisterFactory(idleServiceCID, idleServiceObj); + } + catch(err) { + dump("test_bug715041.xul: ShiftLocalTimerBackCleanUp() Failed to unregister factory, mock idle service!\n"); + } + + try { + componentMgr.registerFactory(oldIdleServiceCID, "Re registering old idle service", idleServiceContractID, oldIdleServiceFactoryObj); + } + catch(err) { + dump("test_bug715041.xul: ShiftLocalTimerBackCleanUp() Failed to register factory, original idle service!\n"); + } + + SimpleTest.finish(); + } + + /* + * function AddRemoveIdleObserverWithInvalidTime() + */ + function AddRemoveIdleObserverWithInvalidTime() + { + dump("\n\nTESTING CASE AddRemoveIdleObserverWithInvalidTime()\n"); + dump("==============\n"); + + ResetVars(); + currTestCaseNum = tcAddRemoveIdleObserverWithInvalidTime; + + //while idle + idleServiceObj.idleTime = 2100; + var rv = window.navigator.addIdleObserver(idleObserversArray[6]); + dump("rv: " + rv + "\n"); + rv = window.navigator.removeIdleObserver(idleObserversArray[6]); + + idleServiceObj.idleTime = 0; + window.navigator.addIdleObserver(idleObserversArray[6]); + window.navigator.removeIdleObserver(idleObserversArray[6]); + + SimpleTest.finish(); + } + + try { + var idleServiceCID = Components.ID("287075a6-f968-4516-8043-406c46f503b4"); + var idleServiceContractID = "@mozilla.org/widget/idleservice;1"; + var oldIdleService = Components.classes[idleServiceContractID].getService(Components.interfaces.nsIIdleService); + } + catch(ex) { + dump("test_bug715041.xul: 1) Failed to get old idle service.\n"); + } + + try { + // Registering new moch JS idle service + var componentMgr = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar); + } + catch(err) { + dump("test_bug715041.xul: Failed to query component registrar interface.\n"); + } + + try { + var oldIdleServiceFactoryObj = componentMgr.getClassObjectByContractID(idleServiceContractID, Components.interfaces.nsIFactory); + } + catch(err) { + dump("test_bug715041.xul: Failed to get old idle service.\n"); + } + + try { + var oldIdleServiceCID = componentMgr.contractIDToCID(idleServiceContractID); + } + catch(err) { + dump("test_bug715041.xul: Failed to convert ID to CID for old idle service.\n"); + } + + try { + componentMgr.unregisterFactory(oldIdleServiceCID, oldIdleServiceFactoryObj); + } + catch(err) { + dump("test_bug715041.xul: Failed to unregister old idle service factory object!\n"); + } + + try { + componentMgr.registerFactory(idleServiceCID, "Test Simple Idle/Back Notifications", idleServiceContractID, idleServiceObj); + } + catch(err) { + dump("test_bug715041.xul: Failed to register mock idle service.\n"); + } + + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestLongerTimeout(10); + + AddOutOfOrderActiveEnabled = true; + AddOutOfOrderIdleEnabled = true; + AddNewLocalWhileAllIdleEnabled = true; + TestActiveToActiveNotificationEnabled = true; + AddShiftLocalEnabled = true; + AddIdleObserverWithInvalidTimeEnabled = false; + + SpecialPowers.pushPrefEnv({"set":[['dom.idle-observers-api.fuzz_time.disabled', true]]}, caseZero); + ]]> + </script> + </window> + diff --git a/dom/base/test/test_bug715041_removal.xul b/dom/base/test/test_bug715041_removal.xul new file mode 100644 index 0000000000..1a61ed83d6 --- /dev/null +++ b/dom/base/test/test_bug715041_removal.xul @@ -0,0 +1,841 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=715041 +--> + <window title="Mozilla Bug 715041" +xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=715041" +target="_blank">Mozilla Bug 715041</a> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Mock Idle Service Test for Bug 715041 **/ + try { + var idleServiceCID = Components.ID("6f95d965-4322-4829-8a3c-5dc8a4587f4d"); + var idleServiceContractID = "@mozilla.org/widget/idleservice;1"; + var oldIdleService = Components.classes[idleServiceContractID].getService(Components.interfaces.nsIIdleService); + } + catch (ex) { + dump("test_bug715041_removal.xul: failed to get old idle service 1."); + } + + //class mock javascript idle service + var idleServiceObj = { + observers: [], + windowObservers: [], + idleTimeInMS: 5000, //in milli seconds + + // takes note of the idle observers added as the minimum idle observer + //with the idle service + timesAdded: [], + + QueryInterface: function(iid) { + if (iid.equals(Components.interfaces.nsISupports) || + iid.equals(Components.interfaces.nsIFactory) || + iid.equals(Components.interfaces.nsIIdleService)) { + return this; + } + throw Components.results.NS_ERROR_NO_INTERFACE; + }, + + createInstance: function(outer, iid) { + return this.QueryInterface(iid); + }, + + get idleTime() { + return this.idleTimeInMS; //in milli seconds + }, + + set idleTime(timeInMS) { + this.idleTimeInMS = timeInMS; + }, + + getWindowFromObserver: function(observer) { + try { + var interfaceRequestor = observer.QueryInterface(Components.interfaces.nsIInterfaceRequestor); + var window = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); + return window; + } + catch (e) {} + + return null; + }, + + testIdleBackService: function(observer, topic) { + dump("\nJS FAKE IDLE SERVICE\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + + if (this.observers.length > 1) { + this.observers[1].observer.observe(observer, topic, '\0'); + dump("JS CALLED OBSERVE FUNCTION!!!\n\n"); + } + }, + + addIdleObserver: function(observer, time) { + dump("\nJS FAKE IDLE SERVICE add idle observer before\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + var window = this.getWindowFromObserver(observer); + + if (window) { + this.observers.push({ observer: observer, time: time, }); + addedIdleObserver = true; + numIdleObserversAdded++; + this.timesAdded.push(time); + dump ("\nMOCK IDLE SERVICE ADDING idle observer with time: " + time + "\n"); + dump("MOCK IDLE SERVICE: num idle observers added: " + numIdleObserversAdded + "\n\n"); + } + else { + dump("SHOULD NEVER GET HERE!"); + oldIdleService.addIdleObserver(observer, time); + addedIdleObserver = false; + } + + dump("\nJS FAKE IDLE SERVICE end of add idle observer\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + }, + + removeIdleObserver: function(observer, time) { + dump("\nJS REMOVE IDLE OBSERVER () time to be removed: " + time + "\n"); + var window = this.getWindowFromObserver(observer); + if (!window) { + oldIdleService.removeIdleObserver(observer, time); + } + else { + var observerIndex = -1; + for (var i=0; i<this.observers.length; i++) { + dump("JS removeIdleObserver() observer time: " + this.observers[i].time + "\n"); + if (this.observers[i].time === time) { + observerIndex = i; + break; + } + } + + if (observerIndex != -1 && this.observers.length > 0) { + numIdleObserversRemoved++; + this.observers.splice(observerIndex, 1); + removedIdleObserver = true; + dump("MOCK IDLE SERVICE REMOVING idle observer with time " + time + "\n"); + dump("MOCK IDLE SERVICE numIdleObserversRemoved: " + numIdleObserversRemoved + " numIdleObserversAdded: " + numIdleObserversAdded + "\n\n"); + } + else { + removedIdleObserver = false; + } + } + dump("\nJS FAKE IDLE SERVICE end of remove idle observer\n"); + dump("JS NUM OBSERVERS: " + this.observers.length + "\n"); + }, + }; + + /** Test for Bug 715041 **/ + dump("\n\n\nJS STARTING TESTING FOR BUG 715041 REMOVAL\n"); + + //bool variables + var addedIdleObserver = removedIdleObserver = passed = cleanUp = false; + + //msgXCount + var msg0Count = msg1Count = msg2Count = msg3Count = msg4Count = msg5Count = + msg6Count = tcZero = currTestCaseNum = prevMsgNum = 0; + + //test case number + var tcRemoveHeadIdleObserverWhileActive = 0; + var tcRemoveLocalIdleObserverWhileIdle = 1; + var tcRemoveHeadIdleObserver = 2; + var tcRemoveLocalIdleTimerWhileIdle = 3; + var tcRemoveLocalIdleTimerLastElement = 4; + var tcRemoveHeadAfterLastLocalFired = 5; + var tcRemoveHeadIdleObserverWhileIdleCase1 = 6; + var tcRemoveLastAddLast = 7; + + function ResetMsgCounts() { + msg0Count = msg1Count = msg2Count = msg3Count = msg4Count = msg5Count = + msg6Count = prevMsgNum = 0; + } + + function ResetVars() { + msg0Count = msg1Count = msg2Count = msg3Count = msg4Count = msg5Count = + msg6Count = prevMsgNum = 0; + + numIdleObserversAdded = numIdleObserversRemoved = 0; + currTestCaseNum = -1; + addedIdleObserver = removedIdleObserver = passed = cleanUp = false; + } + + function printVariableValues() + { + dump("\nfunction printVariableValues()\ncurrTestCaseNum: " + currTestCaseNum + + "\ncleanUp: " + cleanUp + + "\npassed: " + passed + + "\nnumIdleObserversRemoved: " + numIdleObserversRemoved + + "\nnumIdleObservesAdded: " + numIdleObserversAdded + + "\nmsg1Count " + msg1Count + + "\nmsg2Count " + msg2Count + + "\nmsg3Count " + msg3Count + + "\nmsg4Count " + msg4Count + + "\nmsg5Count " + msg5Count + + "\n"); + } + + //Place Holder. + var idleHandler0 = function() { dump("msg 0, should never be used!\n"); }; + + //idleHandler1 + function idleHandler1() { + msg1Count++; + dump("msg 1 Count: " + msg1Count + "\n"); + + switch (currTestCaseNum) { + case tcRemoveHeadIdleObserver: + if (msg1Count === 1 && !msg2Count && !msg3Count && !msg4Count && !msg5Count) { + window.navigator.removeIdleObserver(idleObserversArray[1]); + } + break; + case tcRemoveLocalIdleObserverWhileIdle: + if (msg1Count === 1 && !msg2Count && !msg3Count && !msg4Count) { + window.navigator.removeIdleObserver(idleObserversArray[2]); + } + break; + case tcRemoveLocalIdleTimerWhileIdle: + if (msg1Count === 1 && !msg2Count && !msg3Count && !msg4Count) { + idleServiceObj.idleTime = 2000; + window.navigator.removeIdleObserver(idleObserversArray[3]); + } + break; + case tcRemoveHeadIdleObserverWhileIdleCase1: + if (msg1Count === 1 && !msg2Count && !msg3Count && !msg4Count) { + for (var i=1; i<4; i++) { + window.navigator.addIdleObserver(idleObserversArray[i]); + } + window.navigator.addIdleObserver(idleObserversArray[2]); + window.navigator.addIdleObserver(idleObserversArray[3]); + + idleServiceObj.idleTime = 1200; + window.navigator.removeIdleObserver(idleObserversArray[1]); + } + break; + case tcRemoveLocalIdleTimerLastElement: + if (msg1Count === 1 && !msg2Count && !msg3Count && !msg4Count && !msg5Count) { + idleServiceObj.idleTime = 1500; + window.navigator.removeIdleObserver(idleObserversArray[1]); + idleServiceObj.idleTime = 1700; + window.navigator.addIdleObserver(idleObserversArray[2]); + idleServiceObj.idleTime = 2000; + idleServiceObj.testIdleBackService(idleObserversArray[2], "idle"); + } + break; + case tcRemoveHeadAfterLastLocalFired: + if (msg1Count === 1 && !msg2Count && !msg3Count && !msg4Count && !msg5Count) { + dump("idle handler 1: case tcRemoveHeadAfterLastLocalFired:\n"); + window.navigator.addIdleObserver(idleObserversArray[2]); + window.navigator.addIdleObserver(idleObserversArray[3]); + window.navigator.addIdleObserver(idleObserversArray[4]); + } + break; + case tcRemoveLastAddLast: + window.navigator.addIdleObserver(idleObserversArray[2]); + window.navigator.addIdleObserver(idleObserversArray[3]); + break; + default: + break; + } + } + + //idleHandler2 + function idleHandler2() { + msg2Count++; + dump("msg 2 Count: " + msg2Count + "\n"); + + switch (currTestCaseNum) { + case tcRemoveLocalIdleTimerLastElement: + if (msg1Count === 1 && msg2Count === 1 && !msg3Count && !msg4Count) { + window.navigator.addIdleObserver(idleObserversArray[3]); + window.navigator.addIdleObserver(idleObserversArray[4]); + window.navigator.removeIdleObserver(idleObserversArray[3]); + } + break; + default: + //do nothing. + break; + } + } + + //idleHandler3 + function idleHandler3() { + msg3Count++; + dump("msg 3 Count: " + msg3Count + "\n"); + passed = false; + switch (currTestCaseNum) { + case tcRemoveHeadIdleObserverWhileActive: + if (!msg1Count && msg2Count === 1 && msg3Count === 1) { + passed = true; + } + dump("idleHandler3: passed: " + passed + "\n"); + RemoveHeadIdleObserverWhileActiveCleanUp(); + break; + case tcRemoveHeadIdleObserverWhileIdleCase1: + if (msg3Count != 2 && msg3Count != 4) { + return; + } + + if (msg1Count === 2 && msg2Count === 2 && msg3Count === 2 && !msg4Count) { + passed = true; + ok(passed, "Failed test case remove head idle observer while idle case 1, part 1.\n"); + idleServiceObj.testIdleBackService(idleObserversArray[1], "active"); + return; + } + + if (msg1Count === 3 && msg2Count === 4 && msg3Count === 4 && + !msg4Count && !msg5Count) { + passed = true; + } + RemoveHeadIdleObserverWhileIdleCase1CleanUp(); + break; + case tcRemoveLastAddLast: + if (msg1Count === 1 && msg2Count === 1 && msg3Count === 1 + && !msg4Count && !msg5Count) { + idleServiceObj.idleTime = 3200; + window.navigator.removeIdleObserver(idleObserversArray[3]); + idleServiceObj.idleTime = 3500; + window.navigator.addIdleObserver(idleObserversArray[4]); + return; + } + break; + case tcRemoveHeadAfterLastLocalFired: + if (msg3Count === 1) { + return; + } + + if (msg1Count === 2 && msg2Count === 2 && msg3Count === 2 && msg4Count === 1) { + passed = true; + } + RemoveHeadAfterLastLocalFiredCleanUp(); + break; + default: + break; + } + } + + //idleHandler4 + function idleHandler4() { + msg4Count++; + dump("msg 4 Count: " + msg4Count + "\n"); + + switch (currTestCaseNum) { + case tcRemoveLocalIdleObserverWhileIdle: + if (msg1Count === 1 && !msg2Count && msg3Count === 1 && msg4Count === 1) { + passed = true; + RemoveLocalIdleObserverWhileIdleCleanUp(); + } + break; + case tcRemoveHeadIdleObserver: + printVariableValues(); + if (msg1Count === 1 && msg2Count === 1 && msg3Count === 1 && msg4Count === 1) { + passed = true; + RemoveHeadIdleObserverCleanUp(); + } + break; + case tcRemoveLocalIdleTimerWhileIdle: + if (msg1Count === 1 && !msg2Count && !msg3Count && msg4Count === 1) { + passed = true; + RemoveLocalIdleTimerWhileIdleCleanUp(); + } + break + case tcRemoveLocalIdleTimerLastElement: + if (msg1Count === 1 && msg2Count === 1 && !msg3Count && msg4Count === 1) { + passed = true; + ok(passed, "Failed test case remove local idle timer last element.\n"); + RemoveLocalIdleTimerLastElementCleanUp(); + } + break; + case tcRemoveHeadAfterLastLocalFired: + if (msg1Count === 1 && msg2Count === 1 && msg3Count === 1 && msg4Count === 1) { + window.navigator.removeIdleObserver(idleObserversArray[4]); + passed = true; + ok(passed, "Failed remove head after last local fired.\n"); + idleServiceObj.testIdleBackService(idleObserversArray[1], "active"); + } + break; + case tcRemoveLastAddLast: + if (msg1Count === 1 && msg2Count === 1 && msg3Count === 1 && msg4Count == 1) { + idleServiceObj.idleTime = 4100; + passed = true; + RemoveLastAddLastCleanUp(); + } + break; + default: + //do nothing. + break; + } + } + + //idleHandler5 + function idleHandler5() { + msg5Count++; + dump("msg 5 Count: " + msg5Count + "\n"); + + switch (currTestCaseNum) { + + default: + //do nothing. + break; + } + } + + //idleHandler6 + function idleHandler6() { + dump("msg 6 Count: " + msg6Count + "\n"); + } + + var idleObserversArray = []; + idleObserversArray[0] = {time: 0, onidle: idleHandler0, onactive: idleHandler0}; + idleObserversArray[1] = {time: 1, onidle: idleHandler1, onactive: idleHandler1}; + idleObserversArray[2] = {time: 2, onidle: idleHandler2, onactive: idleHandler2}; + idleObserversArray[3] = {time: 3, onidle: idleHandler3, onactive: idleHandler3}; + idleObserversArray[4] = {time: 4, onidle: idleHandler4, onactive: idleHandler4}; + idleObserversArray[5] = {time: 5, onidle: idleHandler5, onactive: idleHandler5}; + idleObserversArray[6] = {time: 0, onidle: idleHandler6, onactive: idleHandler6}; + + //observers array space holder at index zero + idleServiceObj.observers.push( {observer: idleObserversArray[0], time: 0, } ); + + /* + * - function RemoveHeadIdleObserverWhileActive1() + * - Remove head idle observer before the head idle notification is fired by the + * idle service. I.e. remove the head idle observer while the user is active. + * - RESULT: prints 2 in 2ms, 3 + */ + function RemoveHeadIdleObserverWhileActive() { + dump("\n\nTESTING CASE RemoveHeadIdleObserverWhileActive\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadIdleObserverWhileActive; + idleServiceObj.idleTime = 500; + + window.navigator.addIdleObserver(idleObserversArray[1]); + dump("test_bug715041_removal.xul: RemoveHeadIdleObserverWhileActive() idle time " + idleServiceObj.idleTime + "\n"); + window.navigator.addIdleObserver(idleObserversArray[2]); + window.navigator.addIdleObserver(idleObserversArray[3]); + + idleServiceObj.idleTime = 800; + window.navigator.removeIdleObserver(idleObserversArray[1]); + + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[2], "idle"); + } + + function RemoveHeadIdleObserverWhileActiveCleanUp() { + dump("\nRemoveHeadIdleObserverWhileActiveCleanUp()\n"); + dump("=====================================\n"); + + dump("Passed: " + passed + "\n"); + ok(passed, "Failed test case: RemoveHeadIdleObserverWhileActive"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadIdleObserverWhileActive; + idleServiceObj.idleTime = 3500; + + for (var i=2; i<4; i++) { + window.navigator.removeIdleObserver(idleObserversArray[i]); + } + + dump("JS RemoveHeadIdleObserverWhileActiveCleanUp() DONE\n"); + if (RemoveLocalIdleObserverWhileIdleEnabled) { + RemoveLocalIdleObserverWhileIdle(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + /* + * function RemoveLocalIdleObserverWhileIdle() + * Remove local observer before the local oberver at index 1 is triggered while + * the user is idle. + * RESULT: should print 1, 3, 4 + */ + function RemoveLocalIdleObserverWhileIdle() { + dump("\n\nTESTING CASE RemoveLocalIdleObserverWhileIdle\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveLocalIdleObserverWhileIdle; + idleServiceObj.idleTime = 500; + + window.navigator.addIdleObserver(idleObserversArray[1]); + window.navigator.addIdleObserver(idleObserversArray[2]); + window.navigator.addIdleObserver(idleObserversArray[3]); + window.navigator.addIdleObserver(idleObserversArray[4]); + + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function RemoveLocalIdleObserverWhileIdleCleanUp() { + dump("\nRemoveLocalIdleObserverWhileIdleCleanUp()\n"); + dump("=====================================\n"); + + ok(passed, "Failed test case: RemoveLocalIdleObserverWhileIdleCleanUp()"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadIdleObserverWhileActive; + idleServiceObj.idleTime = 3500; + + window.navigator.removeIdleObserver(idleObserversArray[1]); + window.navigator.removeIdleObserver(idleObserversArray[3]); + window.navigator.removeIdleObserver(idleObserversArray[4]); + + dump("JS RemoveLocalIdleObserverWhileIdleCleanUp() DONE\n"); + if (RemoveHeadIdleObserverEnabled) { + RemoveHeadIdleObserver(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + + /* + * function RemoveHeadIdleObserver() + * Remove head idle observer while the user has been idle for 2400 ms. + * - RESULT: prints 1, 2, remove 2, 3, 4 + */ + function RemoveHeadIdleObserver() { + dump("\n\nTESTING CASE RemoveHeadIdleObserver\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadIdleObserver; + idleServiceObj.idleTime = 500; + + window.navigator.addIdleObserver(idleObserversArray[1]); + window.navigator.addIdleObserver(idleObserversArray[2]); + window.navigator.addIdleObserver(idleObserversArray[3]); + window.navigator.addIdleObserver(idleObserversArray[4]); + + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function RemoveHeadIdleObserverCleanUp() { + dump("\nRemoveHeadIdleObserverCleanUp()\n"); + dump("=====================================\n"); + + ok(passed, "Failed test case: RemoveHeadIdleObserverCleanUp()"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadIdleObserver; + idleServiceObj.idleTime = 3500; + + for (var i=2; i<5; i++) { + window.navigator.removeIdleObserver(idleObserversArray[i]); + } + + dump("JS RemoveHeadIdleObserverCleanUp() DONE\n"); + if (RemoveLocalIdleTimerWhileIdleEnabled) { + RemoveLocalIdleTimerWhileIdle(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + /* + * RemoveLocalIdleTimerWhileIdle() + * - Removes the idle observer that is also set as the current local idle timer callback + * local idle observer being removed is NOT at index 1! + * - RESULT: should trigger 1 in 1ms and 4 in 4ms + */ + function RemoveLocalIdleTimerWhileIdle() + { + dump("\n\nTESTING CASE RemoveLocalIdleTimerWhileIdle\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveLocalIdleTimerWhileIdle; + idleServiceObj.idleTime = 500; + + window.navigator.addIdleObserver(idleObserversArray[1]); + window.navigator.addIdleObserver(idleObserversArray[3]); + window.navigator.addIdleObserver(idleObserversArray[4]); + + idleServiceObj.idleTime = 1000; + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function RemoveLocalIdleTimerWhileIdleCleanUp() + { + dump("\nRemoveLocalIdleTimerWhileIdleCleanUp()\n"); + dump("=====================================\n"); + + ok(passed, "Failed test case: RemoveLocalIdleTimerWhileIdleCleanUp()"); + + ResetVars(); + currTestCaseNum = tcRemoveLocalIdleTimerWhileIdle; + + window.navigator.removeIdleObserver(idleObserversArray[1]); + window.navigator.removeIdleObserver(idleObserversArray[4]); + + dump("JS RemoveLocalIdleTimerWhileIdleCleanUp() DONE\n"); + if (RemoveLocalIdleTimerLastElementEnabled) { + RemoveLocalIdleTimerLastElement(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + /* + * function RemoveLocalIdleTimerLastElement() + */ + function RemoveLocalIdleTimerLastElement() + { + dump("\n\nTESTING CASE RemoveLocalIdleTimerLastElement\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveLocalIdleTimerLastElement; + idleServiceObj.idleTime = 1200; + + window.navigator.addIdleObserver(idleObserversArray[1]); + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function RemoveLocalIdleTimerLastElementCleanUp() { + dump("\nRemoveLocalIdleTimerLastElementCleanUp()\n"); + dump("=====================================\n"); + + ok(passed, "Failed test case: RemoveLocalIdleTimerLastElementCleanUp()"); + + ResetVars(); + currTestCaseNum = tcRemoveLocalIdleTimerLastElement; + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[4]); + + dump("JS RemoveLocalIdleTimerLastElementCleanUp() DONE\n"); + if (RemoveHeadAfterLastLocalFiredEnabled) { + RemoveHeadAfterLastLocalFired(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + /* + - Remove the head after the last local idle timer has been fired + - add 1 2 3 4 + - after 4 has been notified, removed idle observer with time 4 + - send a back topic + - message notification should be 1, 2, 3. + */ + function RemoveHeadAfterLastLocalFired() + { + dump("\n\nTESTING CASE RemoveHeadAfterLastLocalFired\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadAfterLastLocalFired; + idleServiceObj.idleTime = 1200; + + window.navigator.addIdleObserver(idleObserversArray[1]); + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function RemoveHeadAfterLastLocalFiredCleanUp() { + dump("\RemoveHeadAfterLastLocalFiredCleanUp()\n"); + dump("=====================================\n"); + + ok(passed, "Failed test case: RemoveHeadAfterLastLocalFiredCleanUp()"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadAfterLastLocalFired; + + window.navigator.removeIdleObserver(idleObserversArray[1]); + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[3]); + + dump("JS RemoveHeadAfterLastLocalFiredCleanUp() DONE\n"); + if (RemoveHeadIdleObserverWhileIdleCase1Enabled) { + RemoveHeadIdleObserverWhileIdleCase1(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + function RemoveHeadIdleObserverWhileIdleCase1() { + dump("\n\nTESTING CASE RemoveHeadIdleObserverWhileIdleCase1\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadIdleObserverWhileIdleCase1; + idleServiceObj.idleTime = 1000; + window.navigator.addIdleObserver(idleObserversArray[1]); + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function RemoveHeadIdleObserverWhileIdleCase1CleanUp() { + dump("\nRemoveHeadIdleObserverWhileIdleCase1CleanUp()\n"); + dump("=====================================\n"); + + ok(passed, "Failed test case: RemoveHeadIdleObserverWhileIdleCase1CleanUp()"); + + ResetVars(); + currTestCaseNum = tcRemoveHeadIdleObserverWhileIdleCase1; + + for (var i=1; i<4; i++) { + window.navigator.removeIdleObserver(idleObserversArray[i]); + } + + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[3]); + + dump("JS RemoveHeadIdleObserverWhileIdleCase1CleanUp() DONE\n"); + if (RemoveLastAddLastEnabled) { + RemoveLastAddLast(); + } + else { + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + } + + /* + * - RemoveLastAddLast() + * + * - User is currently idle. + * - Add callback 1, 2, 3, + * - Remove callback 3 after 3200 MS. I.e. after callback 3 has been notified. + * - Add callback 4 after 3500 MS + * - Output: 1, 2, 3, 4 + */ + function RemoveLastAddLast() + { + dump("\n\nTESTING CASE RemoveLastAddLast()\n"); + dump("=================================\n"); + + ResetVars(); + currTestCaseNum = tcRemoveLastAddLast; + idleServiceObj.idleTime = 1000; + window.navigator.addIdleObserver(idleObserversArray[1]); + idleServiceObj.testIdleBackService(idleObserversArray[1], "idle"); + } + + function RemoveLastAddLastCleanUp() + { + dump("\RemoveLastAddLastCleanUp()\n"); + dump("=====================================\n"); + + ok(passed, "Failed test case: RemoveLastAddLastCleanUp()"); + + ResetVars(); + currTestCaseNum = tcRemoveLastAddLast; + + window.navigator.removeIdleObserver(idleObserversArray[1]); + window.navigator.removeIdleObserver(idleObserversArray[2]); + window.navigator.removeIdleObserver(idleObserversArray[4]); + + if (numIdleObserversRemoved === 1 && !numIdleObserversAdded) { + ok(true, "Failed test case: RemoveLastAddLastCleanUp()"); + } + else { + ok(false, "Failed test case: RemoveLastAddLastCleanUp()"); + } + + + try { + componentMgr.unregisterFactory(idleServiceCID, idleServiceObj); + } + catch(err) { + dump("test_bug715041_removal.xul: RemoveLastAddLastCleanUp() Failed to unregister factory, mock idle service!\n"); + } + + try { + componentMgr.registerFactory(oldIdleServiceCID, "Re registering old idle service", idleServiceContractID, oldIdleServiceFactoryObj); + } + catch(err) { + dump("test_bug715041_removal.xul: RemoveLastAddLastCleanUp() Failed to register factory, original idle service!\n"); + } + + dump("JS RemoveLastAddLastCleanUp() DONE\n"); + dump("Finishing testing idle API.\n"); + SimpleTest.finish(); + } + + + // Registering new moch JS idle service + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestLongerTimeout(10); + + try { + var idleServiceCID = Components.ID("0fdc1bbf-3868-4660-9855-0c2e376922bc"); + var idleServiceContractID = "@mozilla.org/widget/idleservice;1"; + var oldIdleService = Components.classes[idleServiceContractID].getService(Components.interfaces.nsIIdleService); + } + catch(ex) { + dump("test_bug715041_removal.xul: 1) Failed to get old idle service.\n"); + } + + try { + // Registering new moch JS idle service + var componentMgr = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar); + } + catch(err) { + dump("test_bug715041_removal.xul: Failed to query component registrar interface.\n"); + } + + try { + var oldIdleServiceFactoryObj = componentMgr.getClassObjectByContractID(idleServiceContractID, Components.interfaces.nsIFactory); + } + catch(err) { + dump("test_bug715041_removal.xul: Failed to get old idle service.\n"); + } + + try { + var oldIdleServiceCID = componentMgr.contractIDToCID(idleServiceContractID); + } + catch(err) { + dump("test_bug715041._removalxul: Failed to convert ID to CID for old idle service.\n"); + } + + try { + componentMgr.unregisterFactory(oldIdleServiceCID, oldIdleServiceFactoryObj); + } + catch(err) { + dump("test_bug715041_removal.xul: Failed to unregister old idle service factory object!\n"); + } + + try { + componentMgr.registerFactory(idleServiceCID, "Test Simple Idle/Back Notifications", idleServiceContractID, idleServiceObj); + } + catch(err) { + dump("test_bug715041_removal.xul: Failed to register mock idle service.\n"); + } + + //test case enabled + var RemoveLocalIdleObserverWhileIdleEnabled = true; + var RemoveHeadIdleObserverEnabled = true; + var RemoveLocalIdleTimerWhileIdleEnabled = true; + var RemoveLocalIdleTimerLastElementEnabled = true; + var RemoveHeadAfterLastLocalFiredEnabled = true; + var RemoveHeadIdleObserverWhileIdleCase1Enabled = true; + var RemoveLastAddLastEnabled = true; + SpecialPowers.pushPrefEnv({"set":[['dom.idle-observers-api.fuzz_time.disabled', true]]}, RemoveHeadIdleObserverWhileActive); +]]> + </script> + </window> + diff --git a/dom/base/test/test_bug719533.html b/dom/base/test/test_bug719533.html new file mode 100644 index 0000000000..4154b3bdb2 --- /dev/null +++ b/dom/base/test/test_bug719533.html @@ -0,0 +1,27 @@ +<!doctype html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=719544 +--> +<title>Test for Bug 719544</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=719544">Mozilla Bug 719544</a> +<script> + +/** Test for Bug 719544 **/ +var threw = false; +var origLength = document.childNodes.length; +try { + var range = document.createRange(); + range.selectNodeContents(document); + range.extractContents(); +} catch(e) { + threw = true; + is(Object.getPrototypeOf(e), DOMException.prototype, + "Must throw DOMException"); + is(e.name, "HierarchyRequestError", "Must throw HierarchyRequestError"); +} +ok(threw, "Must throw"); +is(document.childNodes.length, origLength, "Must preserve original children"); + +</script> diff --git a/dom/base/test/test_bug726364.html b/dom/base/test/test_bug726364.html new file mode 100644 index 0000000000..97db677551 --- /dev/null +++ b/dom/base/test/test_bug726364.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=726364 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 726364</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=726364">Mozilla Bug 726364</a> +<p id="display"><div id="v">ABC</div></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 726364 **/ +function boom() +{ + var v = document.getElementById("v"); + var t = v.firstChild; + is(v.childNodes.length,1, "child count"); + + var f = function(event) { + window.removeEventListener("DOMCharacterDataModified", f, true); + is(v.childNodes[0],t, "first child is the same"); + is(v.childNodes.length,2, "child count"); + r.setEnd(v, 0); + SimpleTest.finish(); + }; + window.addEventListener("DOMCharacterDataModified", f, true); + + var r = document.createRange(); + r.setStart(t, 2); + t.splitText(1); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(boom); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug737087.html b/dom/base/test/test_bug737087.html new file mode 100644 index 0000000000..008ad3bc03 --- /dev/null +++ b/dom/base/test/test_bug737087.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=737087 +--> +<title>Test for Bug 737087</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=737087">Mozilla Bug 737087</a> +<script> + +/** Test for Bug 737087 **/ +SimpleTest.waitForExplicitFinish(); + +var bubbled = false; +var capturedEvent = null; +var inlineFiredEvent = null; + +addEventListener("error", function() { bubbled = true }); +addEventListener("error", function(e) { + capturedEvent = e; + is(typeof e, "object", "Error event must be object"); + is(Object.getPrototypeOf(e), Event.prototype, "Error event must be Event"); + is(e.bubbles, false, "e.bubbles must be false"); + is(e.cancelable, false, "e.cancelable must be false"); +}, true); + +addLoadEvent(function() { + is(bubbled, false, "Error event must not bubble"); + isnot(capturedEvent, null, "Error event must be captured"); + isnot(inlineFiredEvent, null, "Inline error handler must fire"); + is(capturedEvent, inlineFiredEvent, + "Same event must be handled by both handlers"); + SimpleTest.finish(); +}); +</script> +<script src=nonexistent + onerror="inlineFiredEvent = event"></script> diff --git a/dom/base/test/test_bug737565.html b/dom/base/test/test_bug737565.html new file mode 100644 index 0000000000..9a24a70b9d --- /dev/null +++ b/dom/base/test/test_bug737565.html @@ -0,0 +1,64 @@ +<!doctype html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=737565 +--> +<title>Test for Bug 737565</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=737565">Mozilla Bug 737565</a> +<script> + +/** Test for Bug 737565 **/ +var offsets = [-1, 0, 1, 2, 3, 65536, 1 << 31]; +// This is supposed to be an unsigned long, so adding or subtracting 1 << 32 +// should have no effect +var offsetOffsets = [0, -Math.pow(2, 32), Math.pow(2, 32)]; + +for (var i = 0; i < offsets.length; i++) { + for (var j = 0; j < offsetOffsets.length; j++) { + var offset = offsets[i] + offsetOffsets[j]; + + // Doctype always needs to throw + var threw = false; + try { + var range = document.createRange(); + range.comparePoint(document.doctype, offset); + } catch(e) { + threw = true; + is(e.name, "InvalidNodeTypeError", + "comparePoint(document.doctype, " + offset + + ") must throw InvalidNodeTypeError"); + is(Object.getPrototypeOf(e), DOMException.prototype, + "comparePoint(document.doctype, " + offset + + ") must throw DOMException"); + is(e.code, DOMException.INVALID_NODE_TYPE_ERR, + "comparePoint(document.doctype, " + offset + + ") must throw INVALID_NODE_TYPE_ERR"); + } + ok(threw, "comparePoint(document.doctype, " + offset + ") must throw"); + + threw = false; + // document.documentElement has two children, head and body + var expectedThrew = offsets[i] < 0 || offsets[i] > 2; + try { + var range = document.createRange(); + range.comparePoint(document.documentElement, offset); + } catch(e) { + threw = true; + is(e.name, "IndexSizeError", + "comparePoint(document.documentElement, " + offset + + ") must throw IndexSizeError"); + is(Object.getPrototypeOf(e), DOMException.prototype, + "comparePoint(document.documentElement, " + offset + + ") must throw DOMException"); + is(e.code, DOMException.INDEX_SIZE_ERR, + "comparePoint(document.documentElement, " + offset + + ") must throw INDEX_SIZE_ERR"); + } + is(threw, expectedThrew, + "comparePoint(document.documentElement, " + offset + + ") must " + (expectedThrew ? "" : "not ") + "throw"); + } +} + +</script> diff --git a/dom/base/test/test_bug737612.html b/dom/base/test/test_bug737612.html new file mode 100644 index 0000000000..9a17ab06e6 --- /dev/null +++ b/dom/base/test/test_bug737612.html @@ -0,0 +1,29 @@ +<!doctype html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=737612 +--> +<title>Test for Bug 737612</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=737612">Mozilla Bug 737612</a> +<script> + +/** Test for Bug 737612 **/ +var text = document.createTextNode("abc"); +var range = document.createRange(); +range.setStart(text, 1); +var threw = false; +try { + range.insertNode(document.head); +} catch(e) { + var threw = true; + is(e.name, "HierarchyRequestError", + "Must throw HierarchyRequestError"); + is(Object.getPrototypeOf(e), DOMException.prototype, + "Must throw DOMException"); + is(e.code, DOMException.HIERARCHY_REQUEST_ERR, + "Must throw HIERARCHY_REQUEST_ERR"); +} +ok(threw, "Must throw when insertNode()ing into detached text node"); + +</script> diff --git a/dom/base/test/test_bug738108.html b/dom/base/test/test_bug738108.html new file mode 100644 index 0000000000..4fa00fba9b --- /dev/null +++ b/dom/base/test/test_bug738108.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=738108 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 738108</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=738108">Mozilla Bug 738108</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="foo"></div> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 738108 **/ +is(document.querySelector("#foo"), $("foo"), + "querySelector on document should find element by id") +is($("content").querySelector("#foo"), $("foo"), + "querySelector on parent element should find element by id") +is($("foo").querySelector("#foo"), null, + "querySelector on element should not find the element itself by id") + +is(document.querySelectorAll("#foo").length, 1, + "querySelectorAll on document should find element by id") +is($("content").querySelectorAll("#foo").length, 1, + "querySelectorAll on parent element should find element by id") +is($("foo").querySelectorAll("#foo").length, 0, + "querySelectorall on element should not find the element itself by id") + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug744830.html b/dom/base/test/test_bug744830.html new file mode 100644 index 0000000000..4376b7447e --- /dev/null +++ b/dom/base/test/test_bug744830.html @@ -0,0 +1,132 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=744830 +--> +<head> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=166235">Mozilla Bug 166235</a> +<div id="testnodes"><span>hi</span> there <!-- mon ami --></div> +<pre id="test"> +<script type="application/javascript"> + var t = document.getElementById('testnodes'); + is(t.innerHTML, + "<span>hi</span> there <!-- mon ami -->", + "comment nodes should be included"); + + var PI = document.createProcessingInstruction('foo', 'bar="1.0"'); + t.appendChild(PI); + is(t.innerHTML, '<span>hi</span> there <!-- mon ami --><?foo bar="1.0">', + "pi nodes should be included"); + + t.innerHTML = null; + t.appendChild(document.createElement("textarea")); + t.firstChild.appendChild(document.createTextNode("\nhello")); + // This is the old behavior. Spec requires something else. + is(t.innerHTML, "<textarea>\nhello</textarea>", + "No extra newlines should be inserted to the textarea!"); + + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg:svg")); + t.firstChild.textContent = "<foo>"; + is(t.innerHTML, "<svg><foo></svg>"); + + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "math:math")); + t.firstChild.textContent = "<foo>"; + is(t.innerHTML, "<math><foo></math>"); + + // Prefix is serialized if element isn't HTML/SVG/MathML + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.example.org", "ex:example")); + t.firstChild.textContent = "<foo>"; + is(t.innerHTML, "<ex:example><foo></ex:example>"); + + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.example.org", "example")); + t.firstChild.textContent = "<foo>"; + is(t.innerHTML, "<example><foo></example>"); + + t.firstChild.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "us-en"); + is(t.innerHTML, '<example xml:lang="us-en"><foo></example>'); + + t.firstChild.setAttributeNS("http://www.w3.org/1999/xlink", "href", "foo"); + is(t.innerHTML, '<example xml:lang="us-en" xlink:href="foo"><foo></example>'); + + t.firstChild.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://foo"); + is(t.innerHTML, '<example xml:lang="us-en" xlink:href="foo" xmlns="http://foo"><foo></example>'); + + t.firstChild.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:bar", "http://bar"); + is(t.innerHTML, '<example xml:lang="us-en" xlink:href="foo" xmlns="http://foo" xmlns:bar="http://bar"><foo></example>'); + + t.firstChild.setAttributeNS("http://www.helloworldns.org", "hello:world", "!"); + is(t.innerHTML, '<example xml:lang="us-en" xlink:href="foo" xmlns="http://foo" xmlns:bar="http://bar" hello:world="!"><foo></example>'); + + t.firstChild.setAttribute("foo", '-"&\xA0-'); + is(t.innerHTML, '<example xml:lang="us-en" xlink:href="foo" xmlns="http://foo" xmlns:bar="http://bar" hello:world="!" foo="-"& -"><foo></example>'); + + t.innerHTML = null; + t.appendChild(document.createElement("div")); + t.firstChild.appendChild(document.implementation + .createDocument(null, null, null) + .createCDATASection("foo")); + is(t.innerHTML, '<div>foo</div>'); + + t.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<div>1&2<3>4 </div>'); + + t.innerHTML = null; + t.appendChild(document.createElement("script")); + t.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<script>1&2<3>4\xA0\u003C/script>'); + + t.innerHTML = null; + t.appendChild(document.createElement("style")); + t.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<style>1&2<3>4\xA0\u003C/style>'); + + t.innerHTML = null; + t.appendChild(document.createElement("span")); + t.firstChild.setAttributeNS("ext", "attr", "foo"); + t.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<span attr="foo">1&2<3>4 \u003C/span>'); + + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); + is(t.firstChild.namespaceURI, "http://www.w3.org/2000/svg"); + t.firstChild.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "script")); + is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/2000/svg"); + t.firstChild.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<svg><script>1&2<3>4 \u003C/script></svg>'); + + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); + is(t.firstChild.namespaceURI, "http://www.w3.org/2000/svg"); + t.firstChild.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "style")); + is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/2000/svg"); + t.firstChild.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<svg><style>1&2<3>4 \u003C/style></svg>'); + + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "math")); + is(t.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML"); + t.firstChild.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "script")); + is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML"); + t.firstChild.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<math><script>1&2<3>4 \u003C/script></math>'); + + t.innerHTML = null; + t.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "math")); + is(t.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML"); + t.firstChild.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "style")); + is(t.firstChild.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML"); + t.firstChild.firstChild.textContent = "1&2<3>4\xA0"; + is(t.innerHTML, '<math><style>1&2<3>4 \u003C/style></math>'); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_bug749367.html b/dom/base/test/test_bug749367.html new file mode 100644 index 0000000000..565588f411 --- /dev/null +++ b/dom/base/test/test_bug749367.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=749367 +--> + +<head> + <title>Test for Bug 749367</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=749367">Mozilla Bug 749367</a> +<div id="content" style="display: none"></div> + <pre id="test"> + + <script type="text/template"> + ok(false, "Shouldn't execute"); + </script> + + <script type="text/javascript"> + ok(true, "Should execute"); + </script> + + </pre> +</body> + +</html> diff --git a/dom/base/test/test_bug750096.html b/dom/base/test/test_bug750096.html new file mode 100644 index 0000000000..29044a0130 --- /dev/null +++ b/dom/base/test/test_bug750096.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=750096 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 750096</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=750096">Mozilla Bug 750096</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 750096 **/ + +SimpleTest.waitForExplicitFinish(); + +var u = SpecialPowers.Ci.nsIParserUtils; +var s = SpecialPowers.ParserUtils; + +var elt = document.getElementById("content"); + +var embed = s.parseFragment("<embed src=\'javascript:this.fail = true;\'>", 0, false, null, elt); +var img = s.parseFragment("<img src=\'javascript:this.fail = true;\'>", 0, false, null, elt); +var video = s.parseFragment("<video src=\'javascript:this.fail = true;\'></video>", 0, false, null, elt); +var object = s.parseFragment("<object data=\'javascript:this.fail = true;\'></object>", 0, false, null, elt); +var iframe = s.parseFragment("<iframe src=\'javascript:this.fail = true;\'></iframe>", 0, false, null, elt); + +setTimeout(function() { + ok(!window.fail, "Should not have failed."); + SimpleTest.finish(); +}, 0); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug753278.html b/dom/base/test/test_bug753278.html new file mode 100644 index 0000000000..91da668772 --- /dev/null +++ b/dom/base/test/test_bug753278.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=753278 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 753278</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=753278">Mozilla Bug 753278</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 753278 **/ + +SimpleTest.waitForExplicitFinish(); + +var f = document.getElementsByTagName("iframe")[0]; + +function runTest() { + f.contentDocument.open(); + f.contentDocument.write('<script>window.location = "data:text/html;charset=utf-8,\\u003Cscript>parent.pass();\\u003C/script>"; document.close(); document.open(); document.write("\\u003Cscript>parent.fail();\\u003C/script>"); document.close();\u003c/script>'); + f.contentDocument.close(); +} + +function pass() { + ok(true, "window.location took precedence"); + SimpleTest.finish(); +} + +function fail() { + ok(false, "window.location should have taken precedence"); + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug761120.html b/dom/base/test/test_bug761120.html new file mode 100644 index 0000000000..28991e52fb --- /dev/null +++ b/dom/base/test/test_bug761120.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=761120 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 761120</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=761120">Mozilla Bug 761120</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 761120 **/ +var doc = document.implementation.createHTMLDocument("title"); +try { + doc.appendChild(doc.createTextNode("text")); + ok(false, "Didn't throw"); +} catch (e) { + is(e.name, "HierarchyRequestError"); +} + +var el = document.createElement("div"); +var text = document.createTextNode("text"); +el.appendChild(text); +is(el.firstChild, text); + +var df = document.createDocumentFragment(); +text = document.createTextNode("text"); +df.appendChild(text); +is(df.firstChild, text); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug769117.html b/dom/base/test/test_bug769117.html new file mode 100644 index 0000000000..6a5cc723e4 --- /dev/null +++ b/dom/base/test/test_bug769117.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=769117 + --> + <head> + <meta charset="utf-8"> + <title>Test for Bug 769117</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + /** Test for Bug 769117 **/ + "use strict"; + function onLoad () { + SpecialPowers.pushPrefEnv({"set": [["plugins.rewrite_youtube_embeds", true]]}, function() { + + let youtube_url = "https://mochitest.youtube.com/v/Xm5i5kbIXzc"; + let youtube_changed_url = "https://mochitest.youtube.com/embed/Xm5i5kbIXzc"; + let static_iframe = document.getElementById("staticiframe"); + + function testEmbed(embed) { + ok (embed, "Embed node exists"); + embed = SpecialPowers.wrap(embed); + is (embed.srcURI.spec, youtube_changed_url, "Should have src uri of " + youtube_changed_url); + } + + function testStatic() { + info("Running static embed youtube rewrite test"); + iframe_doc = static_iframe.contentWindow.document; + testEmbed(iframe_doc.getElementById("testembed")); + testEmbed(iframe_doc.getElementById("testobject")); + SimpleTest.executeSoon(() => { + testEmbed(embed_dynamic); + SimpleTest.finish(); + }); + } + + info("Running dynamic embed youtube rewrite test"); + let embed_dynamic = document.createElement("embed"); + embed_dynamic.src = "https://mochitest.youtube.com/v/Xm5i5kbIXzc"; + embed_dynamic.type = "application/x-shockwave-flash"; + document.body.appendChild(embed_dynamic); + + static_iframe.onload = testStatic; + static_iframe.src = "file_bug769117.html" + + }); + } + </script> + </head> + <body onload="onLoad()"> + <iframe id="staticiframe"></iframe> + </body> +</html> diff --git a/dom/base/test/test_bug782342.html b/dom/base/test/test_bug782342.html new file mode 100644 index 0000000000..9bc3d0e848 --- /dev/null +++ b/dom/base/test/test_bug782342.html @@ -0,0 +1,85 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=782342 +--> +<head> + <title>Test for bug 782342 - blob: protocol no Content-Length header</title> + + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=782342">Mozilla Bug 782342 - blob: protocol no Content-Length header</a> +<p id="display"> + <input id="fileList" type="file"></input> +</p> + +<script type="text/javascript;version=1.7"> +SimpleTest.waitForExplicitFinish(); + +var url = "file_bug782342.txt"; +var xhr = new XMLHttpRequest(); +xhr.open("GET", url, true); +xhr.responseType = "blob"; + +function checkHeaders(xhr) { + var headers = xhr.getAllResponseHeaders(); + dump(headers + "\n"); + var p = headers.split("\n"); + + var contentType = false; + var contentLength = false; + + for (var i = 0; i < p.length; ++i) { + var header = p[i].split(':')[0]; + if (header.toLowerCase() == 'content-type') + contentType = true; + else if (header.toLowerCase() == 'content-length') + contentLength = true; + } + + ok(contentLength == true, "Content-length is part of the headers!"); + ok(contentType == true, "Content-type is part of the headers!"); + + var ct = xhr.getResponseHeader('content-type'); + ok(ct.length > 0, 'Get Response Header - content type: ' + ct); + var cl = xhr.getResponseHeader('content-length'); + ok(cl.length > 0, 'Get Response Header - content length: ' + cl); +} + +xhr.addEventListener("load", function () { + ok(xhr.status === 200, "Status 200!"); + if (xhr.status === 200) { + var blob = xhr.response; + ok(blob, "Blob is: " + blob); + var blobUrl = window.URL.createObjectURL(blob); + ok(blobUrl, "Blob URL is: " + blobUrl); + checkHeaders(xhr); + + var xhrBlob = new XMLHttpRequest(); + xhrBlob.open("GET", blobUrl, true); + xhrBlob.responseType = "blob"; + + xhrBlob.addEventListener("load", function () { + var blob2 = xhr.response; + ok(blob2, "Blob is: " + blob2); + var blob2Url = window.URL.createObjectURL(blob); + ok(blob2Url, "Blob URL is: " + blob2Url); + checkHeaders(xhrBlob); + + ok(blob2.size == blob.size, "Blob sizes are: " + blob2.size + " - " + blob.size); + ok(blob2.type == blob.type, "Blob types are: " + blob2.type + " - " + blob.type); + + SimpleTest.finish(); + }, false); + xhrBlob.send(); + } +}, false); +xhr.send(); +</script> +</body> + +</html> diff --git a/dom/base/test/test_bug787778.html b/dom/base/test/test_bug787778.html new file mode 100644 index 0000000000..998701d55d --- /dev/null +++ b/dom/base/test/test_bug787778.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=787778 + --> +<html> + <head> + <meta charset="utf-8"> + <title>Test for Bug 787778</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript"> + SimpleTest.waitForExplicitFinish(); + window.onload = function() { + window.document.x.src='a'; + SimpleTest.executeSoon(function () { + ok(true, "Didn't crash!"); + SimpleTest.finish(); + }); + } + </script> + </head> + <body> + <embed name="x" src="./file_bug787778.sjs"> + </body> +</html> diff --git a/dom/base/test/test_bug789315.html b/dom/base/test/test_bug789315.html new file mode 100644 index 0000000000..e3081f36e3 --- /dev/null +++ b/dom/base/test/test_bug789315.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789315 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 789315</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="text/javascript"> + (function() { + const observerConfig = { + childList: true, + }; + + var observer = new MutationObserver(onMutations); + observer.observe(document.head, observerConfig); + + function onMutations(mutations) { + for (var i in mutations) { + var mutation = mutations[i]; + for (var j in mutation.addedNodes) { + var addedNode = mutation.addedNodes[j]; + addedNode.mutationObserverHasNotified = true; + } + } + } + + })(); + </script> + + <link id="testnode" rel="localization" href="dummy"></link> + + <script type="text/javascript"> + var testNode = document.getElementById("testnode"); + ok(testNode.mutationObserverHasNotified); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=789315">Mozilla Bug 789315</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug789856.html b/dom/base/test/test_bug789856.html new file mode 100644 index 0000000000..6cf30a7a42 --- /dev/null +++ b/dom/base/test/test_bug789856.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=789856 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 789856</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=789856">Mozilla Bug 789856</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 789856 **/ +SimpleTest.waitForExplicitFinish(); + +var script = document.createElement("script"); +script.onload = function() { + ok(false, "This script should not load"); + SimpleTest.finish(); +} +script.onerror = function() { + ok(true, "This script should fail to load"); + SimpleTest.finish(); +} +// If neither one fires, the test fails, as it should + +// Use a URL the test is not allowed to load +script.src = "file:///tmp/" +document.body.appendChild(script); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug793311.html b/dom/base/test/test_bug793311.html new file mode 100644 index 0000000000..5c1e8e7d39 --- /dev/null +++ b/dom/base/test/test_bug793311.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=793311 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 793311</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug {793311} **/ + SimpleTest.waitForExplicitFinish(); + + try { + SpecialPowers.DOMWindowUtils.wrapDOMFile(null); + ok(false, "wrapDOMFile(null) throws an exception"); + } catch(e) { + ok(true, "wrapDOMFile(null) throws an exception"); + } + SimpleTest.finish(); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=793311">Mozilla Bug 793311</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug804395.html b/dom/base/test/test_bug804395.html new file mode 100644 index 0000000000..58e5fcf380 --- /dev/null +++ b/dom/base/test/test_bug804395.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=804395 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 804395</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=804395">Mozilla Bug 804395</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +function test200() { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open('GET', 'jar:http://example.org/tests/dom/base/test/file_bug804395.jar!/foo.bar', true); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + ok(xhr.status == 200, "Existing file must have Status 200!"); + runTests(); + } + } + xhr.send(null); +} + +function test404() { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open('GET', 'jar:http://example.org/tests/dom/base/test/file_bug804395.jar!/foo.do_not_exist', true); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + ok(xhr.status == 404, "Non existing file must have Status 404!"); + runTests(); + } + } + xhr.send(null); +} + +function test0() { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open('GET', 'jar:http://example.org/tests/dom/base/test/file_bug804395.jar!/foo.bar', true); + ok(xhr.status == 0, "Not Sent request must have status 0"); + runTests(); +} + +var tests = [ test200, test404, test0 ]; +function runTests() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +/** Test for Bug 804395 **/ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + SpecialPowers.pushPrefEnv({"set": [["network.jar.block-remote-files", false]]}, function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTests); + }); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug809003.html b/dom/base/test/test_bug809003.html new file mode 100644 index 0000000000..06515b1785 --- /dev/null +++ b/dom/base/test/test_bug809003.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=809003 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 809003</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <style> + #testdiv:before { + content: url('data:image/gif,GIF89a%01%00%01%00%80%01%00%FF%00%00%FF%FF%FF!%F9%04%01%00%00%01%00%2C%00%00%00%00%01%00%01%00%00%02%02D%01%00%3B'); + } + #testdiv:after { + content: url('non_existing_image.gif'); + } + </style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=809003">Mozilla Bug 809003</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 809003 **/ + +window.didGetLoad = false; +window.didGetError = false; + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("untriaged"); + +setTimeout(function() { + is(window.didGetLoad, false, "Shouldn't have got load event!"); + is(window.didGetError, false, "Shouldn't have got error event!"); + SimpleTest.finish(); +}, 1000); + +</script> +</pre> +<div id="testdiv" onload="window.didGetLoad = true;" onerror="window.didGetError = true;"></div> +</body> +</html> diff --git a/dom/base/test/test_bug810494.html b/dom/base/test/test_bug810494.html new file mode 100644 index 0000000000..2aa659b80b --- /dev/null +++ b/dom/base/test/test_bug810494.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=810494 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 810494</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SpecialPowers.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=810494">Mozilla Bug 810494</a> +<pre id="test"> +<script type="application/javascript;version=1.8"> + +function test(tag, type) { + "use strict"; + info("testing " + tag + " tag with type " + type); + + const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent; + let obj = document.createElement(tag); + obj.type = type; + document.body.appendChild(obj); + + obj instanceof OBJLC; + obj = SpecialPowers.wrap(obj); + + // We expect this tag to simply go to alternate content, not get a + // pluginProblem binding or fire any events. + ok(obj.displayedType == OBJLC.TYPE_NULL, "expected null type"); + ok(obj.pluginFallbackType == OBJLC.PLUGIN_ALTERNATE, + "expected alternate fallback mode"); +} + +// Test all non-plugin types these tags can load to make sure none of them +// trigger plugin-specific fallbacks when loaded with no URI +test("object", "text/html"); // Document +test("object", "image/png"); // Image +test("object", "image/svg+xml"); // SVG Document + +test("embed", "image/png"); // Image +test("embed", "image/svg+xml"); // SVG Document +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug811701.html b/dom/base/test/test_bug811701.html new file mode 100644 index 0000000000..70c5abe0b4 --- /dev/null +++ b/dom/base/test/test_bug811701.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=811701 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 811701</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811701">Mozilla Bug 811701</a> +<p id="display"></p> +<div id="content" style="display: none"> +<math><mtext>test</mtext></math> +<svg><polygon points="0,0 100,100 200,300"/></svg> +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + /** Test for Bug 811701 **/ + var math = document.querySelector("math"); + is(math.innerHTML, "<mtext>test</mtext>", "<math> should have innerHTML"); + is(math.outerHTML, "<math><mtext>test</mtext></math>", + "<math> should have innerHTML"); + math.innerHTML = "<mo>+</mo>"; + is(math.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML", + "Should have the right namespace after setting innerHTML on <math>"); + + var polygon = document.querySelector("polygon"); + is(polygon.parentNode.innerHTML, + '<polygon points="0,0 100,100 200,300"></polygon>', + "<svg> should have innerHTML"); + is(polygon.parentNode.outerHTML, + '<svg><polygon points="0,0 100,100 200,300"></polygon></svg>', + "<svg> should have outerHTML"); + is(polygon.outerHTML, '<polygon points="0,0 100,100 200,300"></polygon>', + "<polygon> should have outerHTML"); + + var svg = document.querySelector("svg"); + svg.innerHTML = "<rect/>"; + is(svg.firstChild.namespaceURI, "http://www.w3.org/2000/svg", + "Should have the right namespace after setting innerHTML on <svg>"); + </script> +</body> +</html> diff --git a/dom/base/test/test_bug811701.xhtml b/dom/base/test/test_bug811701.xhtml new file mode 100644 index 0000000000..10e11013db --- /dev/null +++ b/dom/base/test/test_bug811701.xhtml @@ -0,0 +1,52 @@ +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=811701 +--> +<head> + <title>Test for Bug 811701</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=811701">Mozilla Bug 811701</a> +<p id="display"></p> +<div id="content" style="display: none"> +<math xmlns="http://www.w3.org/1998/Math/MathML"><mtext>test</mtext></math> +<svg xmlns="http://www.w3.org/2000/svg"><polygon points="0,0 100,100 200,300"/></svg> +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + <![CDATA[ + + + /** Test for Bug 811701 **/ + var math = document.querySelector("math"); + is(math.innerHTML, + '<mtext xmlns="http://www.w3.org/1998/Math/MathML">test</mtext>', + "<math> should have innerHTML"); + is(math.outerHTML, + '<math xmlns="http://www.w3.org/1998/Math/MathML"><mtext>test</mtext></math>', + "<math> should have innerHTML"); + math.innerHTML = "<mo>+</mo>"; + is(math.firstChild.namespaceURI, "http://www.w3.org/1998/Math/MathML", + "Should have the right namespace after setting innerHTML on <math>"); + + var polygon = document.querySelector("polygon"); + is(polygon.parentNode.innerHTML, + '<polygon xmlns="http://www.w3.org/2000/svg" points="0,0 100,100 200,300"/>', + "<svg> should have innerHTML"); + is(polygon.parentNode.outerHTML, + '<svg xmlns="http://www.w3.org/2000/svg"><polygon points="0,0 100,100 200,300"/></svg>', + "<svg> should have outerHTML"); + is(polygon.outerHTML, '<polygon xmlns="http://www.w3.org/2000/svg" points="0,0 100,100 200,300"/>', + "<polygon> should have outerHTML"); + + var svg = document.querySelector("svg"); + svg.innerHTML = "<rect/>"; + is(svg.firstChild.namespaceURI, "http://www.w3.org/2000/svg", + "Should have the right namespace after setting innerHTML on <math>"); + ]]> +</script> +</body> +</html> diff --git a/dom/base/test/test_bug813919.html b/dom/base/test/test_bug813919.html new file mode 100644 index 0000000000..5afa50444a --- /dev/null +++ b/dom/base/test/test_bug813919.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=813919 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 813919</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=813919">Mozilla Bug 813919</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 813919 **/ + + function testDataNode(dataNode) { + var div = document.createElement("div"); + div.appendChild(dataNode); + var span = document.createElement("span"); + div.appendChild(span); + var r = document.createRange(); + r.setStart(dataNode, 0); + r.setEnd(div, div.childNodes.length); + r.deleteContents(); + ok(r.collapsed, "Range should be collapsed!"); + is(r.startContainer, div, "startContainer should be div."); + is(r.startOffset, div.childNodes.length, + "Range should be collaped to the end of the div element."); + } + + testDataNode(document.createProcessingInstruction("x", "x")); + testDataNode(document.createComment("x")); + testDataNode(document.createTextNode("x")); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug814576.html b/dom/base/test/test_bug814576.html new file mode 100644 index 0000000000..8ed47a5b87 --- /dev/null +++ b/dom/base/test/test_bug814576.html @@ -0,0 +1,41 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=814576 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 814576</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=814576">Mozilla Bug 814576</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 814576 **/ +var xhr = new XMLHttpRequest(); +xhr.open("GET", ""); +xhr.send(); +var called = false; +// Add an event listener that only listens for trusted events +xhr.addEventListener("abort", function() { called = true; }, false, false); + +// Check that synthetic events don't trigger the listener +var ev = document.createEvent("Events"); +ev.initEvent("abort", false, false); +xhr.dispatchEvent(ev); +is(called, false, "Should not call listener for untrusted events"); + +// And now make sure we get our abort +xhr.abort(); +is(called, true, "Should call listener when we abort"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug819051.html b/dom/base/test/test_bug819051.html new file mode 100644 index 0000000000..bb4f152043 --- /dev/null +++ b/dom/base/test/test_bug819051.html @@ -0,0 +1,59 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=819051 +--> +<head> + <title>Test for Bug 819051</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="test_headers_append();"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var url = "http://mochi.test:8888/tests/dom/base/test/bug819051.sjs"; + +function test_headers_append() +{ + var xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.setRequestHeader("X-appended-to-this", "True"); + xhr.setRequestHeader("X-appended-to-this", "False"); + + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + is(xhr.getResponseHeader("X-appended-result"), "True, False", "Headers should have been appended."); + test_headers_clear(); + } + } + + xhr.send(); +} + +function test_headers_clear() +{ + var xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.setRequestHeader("X-appended-to-this", "True"); + xhr.setRequestHeader("Accept", "foo/bar"); + + xhr.open("GET", url); + xhr.setRequestHeader("X-appended-to-this", "True"); + xhr.setRequestHeader("Accept", "bar/foo"); + + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + is(xhr.getResponseHeader("X-Accept-Result"), "bar/foo", "Set headers record should have been cleared by open."); + SimpleTest.finish(); + } + } + + xhr.send(); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug820909.html b/dom/base/test/test_bug820909.html new file mode 100644 index 0000000000..21ecb2f045 --- /dev/null +++ b/dom/base/test/test_bug820909.html @@ -0,0 +1,87 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=820909 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 820909</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=820909">Mozilla Bug 820909</a> +<p id="display"></p> +<div id="content" style="display: none"> + <span dİsabled="CAPS"></span> +</div> +<pre id="test"> +<script> + var bogusScriptRan = false; +</script> +<script type="applİcation/javascript"> + bogusScriptRan = true; +</script> +<script type="application/javascript"> + +/** Test for Bug 820909 **/ +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=820909#c7 item 1 +ok(!bogusScriptRan, "Script types should be ASCII case-insensitive"); + +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=820909#c7 item 2 +var input = document.createElement("input"); +input.type = "radİo"; +is(input.type, "text", "Input types should be ASCII case-insensitive"); + +// XXX Not sure how to test items 3, 4, 5 + +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=820909#c7 item 6 +is(document.querySelector("[dİsabled='caps']"), null, + "Checking whether an attribute is case-sensitive for selector-matching " + + "purposes should be ASCII case-insensitive on the attr name"); + +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=820909#c7 item 7 +$("content").style.width = "0"; +$("content").style.width = "1İn"; +is($("content").style.width, "0px", + "CSS unit names should be ASCII case-insensitive"); + +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=820909#c7 item 8 +$("content").style.setProperty("animation-name", "a"); +$("content").style.setProperty("-moz-anİmation-name", "b"); +is($("content").style.animationName, "a", + "CSS property aliases should be ASCII case-insensitive"); + +// XXXbz don't know how to test item 9 + +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=820909#c7 item 10 +$("content").innerHTML = "<table><input type='hİdden'></table>"; +is($("content").querySelector("input").parentNode, $("content"), + "Inputs that aren't actually type='hidden' should not be allowed as " + + "table kids"); + +// XXXbz add test for item 11? + +// XXXbz add test for item 12? + +// Test for https://bugzilla.mozilla.org/show_bug.cgi?id=820909#c7 item 13 +$("content").style.setProperty("animation-name", "a"); +$("content").style.setProperty("anİmation-name", "b"); +is($("content").style.animationName, "a", + "CSS property names should be ASCII case-insensitive"); + +$("content").style.setProperty("display", "none"); +$("content").style.setProperty("display", "İnline"); +is($("content").style.display, "none", + "CSS keywords should be ASCII case-insensitive"); + +$("content").style.setProperty("color", "white"); +$("content").style.setProperty("color", "İndigo"); +is($("content").style.color, "white", + "CSS color names should be ASCII case-insensitive"); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug840098.html b/dom/base/test/test_bug840098.html new file mode 100644 index 0000000000..8eaceb5892 --- /dev/null +++ b/dom/base/test/test_bug840098.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=840098 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 840098</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=840098">Mozilla Bug 840098</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id="foo"></div> +</div> +<marquee id="m">Hello</marquee> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 840098 **/ + +var mar = document.getElementById("m"); +var anonymousNode = SpecialPowers.wrap(document).getAnonymousNodes(mar)[0]; +try { + SpecialPowers.wrap(document).implementation.createDocument("", "", null).adoptNode(anonymousNode); + ok(false, "shouldn't be able to adopt the root of an anonymous subtree"); +} catch (e) { + is(e.name, "NotSupportedError", "threw the correct type of error"); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug864595.html b/dom/base/test/test_bug864595.html new file mode 100644 index 0000000000..37504353fe --- /dev/null +++ b/dom/base/test/test_bug864595.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=864595 +--> +<head> + <title>Test for Bug 864595</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=864595">Mozilla Bug 864595</a> +<div id='editable' style='display:inline-block;'>abcd </div> +<script type="application/javascript"> +/** Test for Bug 864595 **/ +var range = document.createRange(); +var elt = document.getElementById('editable'); +var eltRect = elt.getBoundingClientRect(); + +var txtNode = elt.childNodes[0]; +range.setStart(txtNode, 0); +range.setEnd(txtNode, 5); +var rect = range.getBoundingClientRect(); +ok(rect.left >= eltRect.left && rect.right <= eltRect.right, "rect.left >= eltRect.left && rect.right <= eltRect.right"); + +/* Put caret in the space */ +var caretPosX = rect.right + 10; +var caretPosY = (rect.top + rect.bottom ) / 2; +var caretRect = document.caretPositionFromPoint(caretPosX, caretPosY).getClientRect(); +ok(caretRect.right >= rect.right, "caretRect.right >= rect.right"); + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug868999.html b/dom/base/test/test_bug868999.html new file mode 100644 index 0000000000..0d189004ba --- /dev/null +++ b/dom/base/test/test_bug868999.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=868999 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 868999</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868999">Mozilla Bug 869006</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 868999 **/ + +var r = new Range(); +ok(r, "Range has been created"); + +var doc = document.implementation.createDocument("", "", null); +var h1 = doc.createElement('h1'); +doc.appendChild(h1); + +var t = doc.createTextNode('Hello world'); +h1.appendChild(t); + +r.selectNodeContents(doc); +is(r.toString(), "Hello world", "new Range() works!"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug869000.html b/dom/base/test/test_bug869000.html new file mode 100644 index 0000000000..71ecea55be --- /dev/null +++ b/dom/base/test/test_bug869000.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=869000 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 869000</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=869000">Mozilla Bug 869006</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 869000 **/ + +var c = new Text(); +ok(c, "Text has been created without content"); +is(c.data, "", "Text.data is ok"); + +c = new Text('foo'); +ok(c, "Text has been created"); +is(c.data, "foo", "Text.data is ok"); + +document.getElementById('display').appendChild(c); +ok(true, "Text has been added to the document"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug869002.html b/dom/base/test/test_bug869002.html new file mode 100644 index 0000000000..a93200a1bf --- /dev/null +++ b/dom/base/test/test_bug869002.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=868999 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 868999</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868999">Mozilla Bug 869002</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 868999 **/ + +var d = new DocumentFragment(); +ok(d, "DocumentFragment has been created"); + +document.appendChild(d); +ok(true, "DocumentFragment has been added to the document"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug869006.html b/dom/base/test/test_bug869006.html new file mode 100644 index 0000000000..9471660309 --- /dev/null +++ b/dom/base/test/test_bug869006.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=869006 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 869006</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=869006">Mozilla Bug 869006</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 869006 **/ + +var c = new Comment(); +ok(c, "Comment has been created without content"); +is(c.data, "", "Comment.data is ok"); + +c = new Comment('foo'); +ok(c, "Comment has been created"); +is(c.data, "foo", "Comment.data is ok"); + +document.appendChild(c); +ok(true, "Comment has been added to the document"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug876282.html b/dom/base/test/test_bug876282.html new file mode 100644 index 0000000000..bb5a6a02a2 --- /dev/null +++ b/dom/base/test/test_bug876282.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=647518 +--> +<head> + <title>Test for Bug 647518</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=647518">Mozilla Bug 647518</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 647518 **/ +SimpleTest.waitForExplicitFinish(); +var counter = 3; + +var called = false; +var handle1 = window.requestAnimationFrame(function() { + called = true; +}); +ok(handle1 > 0, "Should get back a nonzero handle"); + +function checker() { + --counter; + if (counter == 0) { + is(called, false, "Canceled callback should not have been called"); + SimpleTest.finish(); + } else { + window.requestAnimationFrame(checker); + } +} +window.requestAnimationFrame(checker); +window.cancelAnimationFrame(handle1); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug890580.html b/dom/base/test/test_bug890580.html new file mode 100644 index 0000000000..808a4a868e --- /dev/null +++ b/dom/base/test/test_bug890580.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=890580 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 883129</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + function testPaintextSerializerWithPlaceHolder() { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + const Cc = SpecialPowers.Cc; + + // Create a plaintext encoder with the flag OutputNonTextContentAsPlaceholder. + var encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/plain"] + .createInstance(de); + var flags = de.OutputRaw | + de.OutputNonTextContentAsPlaceholder; + encoder.init(document, "text/plain", flags); + + function toPlaintext(id) { + var element = document.getElementById(id); + var range = document.createRange(); + range.selectNodeContents(element); + encoder.setRange(range); + return encoder.encodeToString(); + } + + // The follows are test cases. + is(toPlaintext("case1"), "This is a button. Hello!", "test with <button>"); + is(toPlaintext("case2"), "There is an\uFFFCimage.", "test with <img>"); + is(toPlaintext("case3"), "\uFFFC with text.", "test with <input>"); + is(toPlaintext("case4"), "There is an\uFFFCimage and a \uFFFC.", + "test with <img> and <input>"); + + SimpleTest.finish(); + } + + addLoadEvent(testPaintextSerializerWithPlaceHolder); + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=890580">Mozilla Bug 890580</a> +<p id="display"></p> +<div id="content" style="display: none"> + <span id="case1"><button id="b">This is a button.</button> Hello!</span> + <span id="case2">There is an<img>image.</span> + <span id="case3"><input type="button" value="Input button"> with text.</span> + <span id="case4" contenteditable="true">There is an<img>image and + a <input type="button" value="button">.</span> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug891952.html b/dom/base/test/test_bug891952.html new file mode 100644 index 0000000000..471e727122 --- /dev/null +++ b/dom/base/test/test_bug891952.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=891952 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 891952</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 891952 **/ + SimpleTest.waitForExplicitFinish(); + addLoadEvent(function() { + var all = document.all; + is(all["content"], $("content"), "Should find the content"); + ok(!("" in all), "Should not have an empty string prop on document.all"); + is(all[""], undefined, "Should not get empty string on document.all"); + is(all.namedItem(""), null, + "namedItem for empty string should return null on document.all"); + + var divs = document.getElementsByTagName("div"); + ok(!("" in divs), "Should not have an empty string prop on getElementsByTagName"); + is(divs[""], undefined, "Should not get empty string on getElementsByTagName"); + is(divs.namedItem(""), null, + "namedItem for empty string should return null on getElementsByTagName"); + var forms = document.forms; + ok(!("" in forms), "Should not have an empty string prop on document.forms"); + is(forms[""], undefined, "Should not get empty string on document.forms"); + is(forms.namedItem(""), null, + "namedItem for empty string should return null on document.forms"); + + var form = $("form"); + ok(!("" in form), "Should not have an empty string prop on form"); + is(form[""], undefined, "Should not get empty string on form"); + + var formEls = $("form").elements; + ok(!("" in formEls), "Should not have an empty string prop on form.elements"); + is(formEls[""], undefined, "Should not get empty string on form.elements"); + is(formEls.namedItem(""), null, + "namedItem for empty string should return null on form.elements"); + SimpleTest.finish(); + }); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=891952">Mozilla Bug 891952</a> +<p id="display"></p> +<div id="content" style="display: none"> + <div id=""></div> + <div name=""></div> + <form id="form" name=""> + <input name=""> + </form> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug894874.html b/dom/base/test/test_bug894874.html new file mode 100644 index 0000000000..f9a0c4fce5 --- /dev/null +++ b/dom/base/test/test_bug894874.html @@ -0,0 +1,45 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=894874 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 894874</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <!-- IMPORTANT: Keep the sheets in this order! --> + <link rel="stylesheet" type="text/css" href="data:text/css,"> + <link rel="stylesheet" type="text/css" title="one" href="data:text/css,"> + <link rel="stylesheet" type="text/css" title="two" href="data:text/css,"> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 894874 **/ + SimpleTest.waitForExplicitFinish(); + addLoadEvent(function() { + is(document.styleSheets[0].disabled, false, + "Sheet with no title should be enabled"); + is(document.styleSheets[1].disabled, false, + "First preferred sheet should be enabled"); + is(document.styleSheets[2].disabled, true, + "Second preferred sheet should be disabled"); + is(document.selectedStyleSheetSet, "one", "Sheet one is enabled"); + document.styleSheets[0].disabled = true; + document.styleSheets[2].disabled = false; + ok(document.selectedStyleSheetSet === null, + "Sheet one and sheet two are both enabled"); + SimpleTest.finish(); + }); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=894874">Mozilla Bug 894874</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug895239.html b/dom/base/test/test_bug895239.html new file mode 100644 index 0000000000..32c0717e5a --- /dev/null +++ b/dom/base/test/test_bug895239.html @@ -0,0 +1,123 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=895239 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 895239</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + function testPaintextSerializerWithPlaceHolder() { + + const de = SpecialPowers.Ci.nsIDocumentEncoder; + const Cc = SpecialPowers.Cc; + + // Create a plaintext encoder with the flag OutputNonTextContentAsPlaceholder. + var encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/plain"] + .createInstance(de); + var flags = de.OutputRaw | + de.OutputNonTextContentAsPlaceholder; + encoder.init(document, "text/plain", flags); + + function toPlaintext(id) { + var element = document.getElementById(id); + var range = document.createRange(); + range.selectNodeContents(element); + encoder.setRange(range); + return encoder.encodeToString(); + } + + // Test cases to serialize all nodes including invisible nodes. + is(toPlaintext("case1"), "This is an audio \uFFFC! ", "test with <audio>"); + is(toPlaintext("case2"), "This is a canvas \uFFFC! ", "test with <canvas>"); + is(toPlaintext("case3"), "This is an iframe \uFFFC! ", "test with one <iframe>"); + is(toPlaintext("case4"), "One iframe \uFFFC with another iframe \uFFFC. ", "test with two <iframes>"); + is(toPlaintext("case5"), "This is a meter \uFFFC! ", "test with <meter>"); + is(toPlaintext("case6"), "This is a progress \uFFFC! ", "test with <progress>"); + is(toPlaintext("case7"), "This is an object \uFFFC! ", "test with <object>"); + is(toPlaintext("case8"), "This is a svg \uFFFC! ", "test with <svg>"); + is(toPlaintext("case9"), "This is a video \uFFFC! ", "test with <video>"); + is(toPlaintext("case10"), "This is a video \uFFFC! ", "test with nested tags"); + + // Test cases to serialize visible nodes only. + encoder.init(document, "text/plain", flags | de.SkipInvisibleContent); + is(toPlaintext("case1"), "This is an audio \uFFFC! ", "test with <audio> for visible nodes"); + is(toPlaintext("case2"), "This is a canvas \uFFFC! ", "test with <canvas> for visible nodes"); + is(toPlaintext("case3"), "This is an iframe \uFFFC! ", "test with one <iframe> for visible nodes"); + is(toPlaintext("case4"), "One iframe \uFFFC with another iframe . ", "test with two <iframes> for visible nodes"); + is(toPlaintext("case5"), "This is a meter \uFFFC! ", "test with <meter> for visible nodes"); + is(toPlaintext("case6"), "This is a progress \uFFFC! ", "test with <progress> for visible nodes"); + is(toPlaintext("case7"), "This is an object \uFFFC! ", "test with <object> for visible nodes"); + is(toPlaintext("case8"), "This is a svg \uFFFC! ", "test with <svg> for visible nodes"); + is(toPlaintext("case9"), "This is a video \uFFFC! ", "test with <video> for visible nodes"); + is(toPlaintext("case10"), "This is a video \uFFFC! ", "test with nested tags for visible nodes"); + SimpleTest.finish(); + } + + addLoadEvent(testPaintextSerializerWithPlaceHolder); + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=895239">Mozilla Bug 895239</a> +<p id="display"></p> +<div id="content"> + <span id="case1">This is an audio + <audio controls="controls"> + Your browser does not support <code>audio</code> element. + </audio>! + </span> + <span id="case2">This is a canvas + <canvas height="100" width="100"> + Your browser does not support canvas element. + </canvas>! + </span> + <span id="case3">This is an iframe + <iframe src="about:blank"> + Your browser does not support iframes. + </iframe>! + </span> + <span id="case4">One iframe + <iframe src="about:blank"> + Your browser does not support iframes. + </iframe> with another iframe + <iframe src="about:blank" style="display: none"></iframe>. + </span> + <span id="case5">This is a meter + <meter min="0" max="100" value="50"> + 50% + </meter>! + </span> + <span id="case6">This is a progress + <progress max="100" value="70"> + 70% + </progress>! + </span> + <span id="case7">This is an object + <object type="application/x-shockware-flash"> + <a href="#">Download the plugin.</a> + </object>! + </span> + <span id="case8">This is a svg + <svg height="100" width="100"> + Your browser does not support svg. + <circle cx="100" cy="100" r="80" fill="green"></circle> + </svg>! + </span> + <span id="case9">This is a video + <video> + Your browser does not support videos. + </video>! + </span> + <span id="case10">This is a video + <video> + Your browser does not support videos.<iframe src="about:blank"></iframe> + </video>! + </span> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug895974.html b/dom/base/test/test_bug895974.html new file mode 100644 index 0000000000..25499d5a2c --- /dev/null +++ b/dom/base/test/test_bug895974.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=895974 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 895974</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 895974 **/ + SimpleTest.waitForExplicitFinish(); + + addLoadEvent(function() { + var frag = document.createDocumentFragment(); + var span = document.createElement("span"); + var div = document.createElement("div"); + var text = document.createTextNode("help"); + frag.appendChild(document.createTextNode("fail")); + frag.appendChild(span); + frag.appendChild(text); + frag.appendChild(div); + frag.appendChild(document.createTextNode("fail")); + + is(text.nextElementSibling, div, "nextElementSibling should work on text"); + is(text.previousElementSibling, span, + "previousElementSibling should work on text"); + + is(document.firstElementChild, document.documentElement, + "firstElementChild should work on document"); + is(document.lastElementChild, document.documentElement, + "lastElementChild should work on document"); + is(document.children.length, 1, "Document has one element kid"); + is(document.children[0], document.documentElement, + "Document only element child is <html>"); + + is(frag.firstElementChild, span, + "firstElementChild should work on document fragment"); + is(frag.lastElementChild, div, + "lastElementChild should work on document fragment"); + is(frag.children.length, 2, "Document fragment has two element kids"); + is(frag.children[0], span, "Document fragment first element child is span"); + is(frag.children[1], div, "Document fragment second element child is div"); + + is(document.documentElement.firstElementChild, document.head, + "firstElementChild should work on element"); + is(document.documentElement.lastElementChild, document.body, + "lastElementChild should work on element"); + is(document.documentElement.children.length, 2, "<html> has two element kids"); + is(document.documentElement.children[0], document.head, + "<html> first element child is head"); + is(document.documentElement.children[1], document.body, + "<html> second element child is body"); + SimpleTest.finish(); + }); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=895974">Mozilla Bug 895974</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug902847.html b/dom/base/test/test_bug902847.html new file mode 100644 index 0000000000..b8ab1bfc42 --- /dev/null +++ b/dom/base/test/test_bug902847.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=902847 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 902847</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + function testPaintextSerializerWithPlaceHolder() { + + const de = SpecialPowers.Ci.nsIDocumentEncoder; + const Cc = SpecialPowers.Cc; + + // Create a plaintext encoder. + var encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/plain"] + .createInstance(de); + var flags = de.OutputRaw | + de.OutputLFLineBreak | + de.OutputDontRemoveLineEndingSpaces; + encoder.init(document, "text/plain", flags); + + function toPlaintext(id) { + var element = document.getElementById(id); + var range = document.createRange(); + range.selectNodeContents(element); + encoder.setRange(range); + return encoder.encodeToString().replace(/\n/g, '\\n') + .replace(/\r/g, '\\r'); + } + + // Test cases. + is(toPlaintext("case1"), "Hello \\nboy!", "Case 1 failed."); + is(toPlaintext("case2"), "Hello \\nboy!", "Case 2 failed."); + is(toPlaintext("case3"), "Hello \\nboy!", "Case 3 failed."); + is(toPlaintext("case4"), "Hello \\nboy!", "Case 4 failed."); + SimpleTest.finish(); + } + + addLoadEvent(testPaintextSerializerWithPlaceHolder); + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=902847">Mozilla Bug 902847</a> +<p id="display"></p> +<div id="content"> + <p id="case1">Hello <br>boy!</p> + <p id="case2">Hello <br>boy!</p> + <p id="case3">Hello <br>boy!</p> + <p id="case4">Hello <br>boy!</p> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug907892.html b/dom/base/test/test_bug907892.html new file mode 100644 index 0000000000..a62cf90a17 --- /dev/null +++ b/dom/base/test/test_bug907892.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=907892 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 907892</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 907892 **/ + SimpleTest.waitForExplicitFinish(); + + var expectedMessages = 2; + window.onmessage = function (ev) { + if (ev.data.sandboxed) { + ok(ev.data.threw, + "Should have thrown when setting document.domain in sandboxed iframe"); + } else { + ok(!ev.data.threw, + "Should not have thrown when setting document.domain in iframe"); + } + + --expectedMessages; + if (expectedMessages == 0) { + SimpleTest.finish(); + } + }; + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=907892">Mozilla Bug 907892</a> +<p id="display"></p> +<div id="content" style="display: none"> +<!-- Set all the sandbox flags to "allow" to make sure we cover that case --> +<iframe + sandbox="allow-same-origin allow-scripts allow-forms allow-top-navigation alllow-pointer-lock" + src="http://test1.example.org/tests/dom/base/test/file_bug907892.html?sandboxed"> +</iframe> +<iframe + src="http://test1.example.org/tests/dom/base/test/file_bug907892.html?normal"> +</iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug913761.html b/dom/base/test/test_bug913761.html new file mode 100644 index 0000000000..bfa05b1501 --- /dev/null +++ b/dom/base/test/test_bug913761.html @@ -0,0 +1,40 @@ + +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=913761 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 913761 - basic support</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=913761">Mozilla Bug 913761</a> +<script type="application/javascript"> + + var transportChannel = new MessageChannel(); + transportChannel.port1.onmessage = function (event) { + ok(true, 'Port Returned.'); + var portToService = event.data.port; + portToService.onmessage = function (event) { + ok(true, "message received"); + SimpleTest.finish(); + }; + portToService.postMessage('READY?'); + } + + var serviceChannel = new MessageChannel(); + serviceChannel.port1.onmessage = function (event) { + if (event.data == 'READY?') { + this.postMessage('READY!'); + } + } + + transportChannel.port2.postMessage({ port: serviceChannel.port2}, [serviceChannel.port2]); + + SimpleTest.waitForExplicitFinish(); +</script> +</body> +</html> diff --git a/dom/base/test/test_bug922681.html b/dom/base/test/test_bug922681.html new file mode 100644 index 0000000000..b04c0c675c --- /dev/null +++ b/dom/base/test/test_bug922681.html @@ -0,0 +1,113 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=922681 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 922681</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + function testInnerHTMLParserInsertionMode() { + + function testInnerHTML(el, input, output) { + el.innerHTML = input; + is(el.innerHTML, output, el.tagName.toLowerCase() + ': "' + input + '"'); + } + + var c; + + c = document.createElement("html"); + testInnerHTML(c, "", "<head></head><body></body>"); + testInnerHTML(c, "xyz", "<head></head><body>xyz</body>"); + testInnerHTML(c, "<input>", "<head></head><body><input></body>"); + + c = document.createElement("colgroup"); + testInnerHTML(c, "abcdef", ""); + testInnerHTML(c, "", ""); + testInnerHTML(c, "\n", "\n"); + testInnerHTML(c, "<col>", "<col>"); + + c = document.createElement("select"); + testInnerHTML(c, "123", "123"); + testInnerHTML(c, "<input>", ""); + testInnerHTML(c, "\0", ""); + testInnerHTML(c, "<col>", ""); + testInnerHTML(c, "<option>", "<option></option>"); + + c = document.createElement("head"); + testInnerHTML(c, "123", "123"); + testInnerHTML(c, "\n", "\n"); + + c = document.createElement("frameset"); + testInnerHTML(c, "456", ""); + testInnerHTML(c, "\n", "\n"); + testInnerHTML(c, "<input>", ""); + testInnerHTML(c, "\0", ""); + + c = document.createElement("table"); + testInnerHTML(c, "abc", "abc"); + testInnerHTML(c, "<td>", "<tbody><tr><td></td></tr></tbody>"); + testInnerHTML(c, "</body>", ""); + testInnerHTML(c, "<input>", "<input>"); + + c = document.createElement("tr"); + testInnerHTML(c, "xyz", "xyz"); + testInnerHTML(c, "<td>", "<td></td>"); + testInnerHTML(c, "</body>", ""); + testInnerHTML(c, "<table>", ""); + + c = document.createElement("td"); + testInnerHTML(c, "789", "789"); + testInnerHTML(c, "\0", ""); + testInnerHTML(c, "<td>", ""); + + c = document.createElement("th"); + testInnerHTML(c, "789", "789"); + testInnerHTML(c, "\0", ""); + testInnerHTML(c, "</tr>", ""); + + c = document.createElement("caption"); + testInnerHTML(c, "xyz", "xyz"); + testInnerHTML(c, "\0", ""); + testInnerHTML(c, "<td>", ""); + testInnerHTML(c, "<dd>", "<dd></dd>"); + testInnerHTML(c, "<body>", ""); + + function testTableBody(tag) { + var c = document.createElement(tag); + testInnerHTML(c, "abc", "abc"); + testInnerHTML(c, "<td>", "<tr><td></td></tr>"); + testInnerHTML(c, "</body>", ""); + testInnerHTML(c, "<input>", "<input>"); + } + testTableBody("thead"); + testTableBody("tbody"); + testTableBody("tfoot"); + + c = document.createElement("template"); + testInnerHTML(c, "abc", "abc"); + testInnerHTML(c, "<td>", "<td></td>"); + testInnerHTML(c, "</template>", ""); + testInnerHTML(c, "<input>", "<input>"); + + c = document.createElement("div"); + testInnerHTML(c, "abc", "abc"); + testInnerHTML(c, "<td>", ""); + testInnerHTML(c, "</body>", ""); + testInnerHTML(c, "<input>", "<input>"); + + SimpleTest.finish(); + } + + addLoadEvent(testInnerHTMLParserInsertionMode); + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=922681">Mozilla Bug 922681</a> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug927196.html b/dom/base/test/test_bug927196.html new file mode 100644 index 0000000000..0a28681713 --- /dev/null +++ b/dom/base/test/test_bug927196.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=426308 +--> +<head> + <title>Test for Bug 426308</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=927196">Mozilla Bug 927196</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 927196 **/ + +function startTest() { + req = new XMLHttpRequest({mozSystem: true}); + is(req.mozAnon, true, "XMLHttpRequest should be mozAnon (3)"); + + req = new XMLHttpRequest({mozAnon: true}); + is(req.mozAnon, true, "XMLHttpRequest should be mozAnon (4)"); + is(req.mozSystem, false, "XMLHttpRequest should not be mozSystem (4)"); + + req = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + is(req.mozAnon, true, "XMLHttpRequest should be mozAnon (5)"); + is(req.mozSystem, true, "XMLHttpRequest should be mozSystem (5)"); + + req = new XMLHttpRequest({mozAnon: false, mozSystem: true}); + is(req.mozAnon, true, "XMLHttpRequest should be mozAnon (6)"); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); + +var req = new XMLHttpRequest({mozAnon: true}); +is(req.mozAnon, true, "XMLHttpRequest should be mozAnon"); +is(req.mozSystem, false, "XMLHttpRequest should not be mozSystem"); + +req = new XMLHttpRequest({mozAnon: true, mozSystem: true}); +is(req.mozAnon, true, "XMLHttpRequest should be mozAnon (2)"); +is(req.mozSystem, false, "XMLHttpRequest should not be mozSystem (2)"); + +addLoadEvent(function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], startTest); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug945152.html b/dom/base/test/test_bug945152.html new file mode 100644 index 0000000000..aa4bf7c3ec --- /dev/null +++ b/dom/base/test/test_bug945152.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=945152 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 945152</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=945152">Mozilla Bug 945152</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript;version=1.7"> +function translateChrome(uriStr) { + const { Cc, Ci } = SpecialPowers; + let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry); + let uri = ios.newURI(uriStr, null, ios.newURI(document.baseURI, null, null)); + return chromeReg.convertChromeURL(uri).spec; +} + +function runTest() { + var worker = new Worker("file_bug945152_worker.js"); + + worker.onmessage = function(event) { + if (event.data.type == 'finish') { + SimpleTest.finish(); + } else if (event.data.type == 'status') { + ok(event.data.status, event.data.msg); + } + }; + + worker.onerror = function(event) { + is(event.target, worker); + ok(false, "Worker had an error: " + event.filename + ":" + event.lineno + ":" + event.colno + ": " + event.message); + SimpleTest.finish(); + }; + + worker.postMessage(translateChrome("file_bug945152.jar")); +} + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + SpecialPowers.pushPrefEnv({"set": [["dom.mapped_arraybuffer.enabled", true]]}, function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], runTest); + }); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug962251.html b/dom/base/test/test_bug962251.html new file mode 100644 index 0000000000..8b870d899b --- /dev/null +++ b/dom/base/test/test_bug962251.html @@ -0,0 +1,258 @@ + +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=962251 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 962251</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + SimpleTest.waitForExplicitFinish(); + + function Test_ElementsInTheSameDocument() { + var button1 = document.getElementById("button1"); + var button2 = document.getElementById("button2"); + + button1.focus(); + is(button1.id, document.activeElement.id, "How did we call focus on button1 and it did" + + " not become the active element?"); + + var getBlurEvent = false; + button1.addEventListener("blur", function onBlur(aEvent) { + button1.removeEventListener("blur", onBlur); + is(aEvent.target.id, "button1", "Button1 should lose focus."); + ok(aEvent.relatedTarget, "The relatedTarget should not be null."); + is(aEvent.relatedTarget.id, "button2", "The relatedTarget should be button2."); + getBlurEvent = true; + }); + + button2.addEventListener("focus", function onFocus(aEvent) { + button2.removeEventListener("focus", onFocus); + ok(getBlurEvent, "Must get blur event first."); + is(aEvent.target.id, "button2", "Button2 should be focused."); + ok(aEvent.relatedTarget, "The relatedTarget should not be null."); + is(aEvent.relatedTarget.id, "button1", "The relatedTarget should be button1."); + button2.blur(); + }); + + button2.addEventListener("blur", function onBlur(aEvent) { + button2.removeEventListener("blur", onBlur); + is(aEvent.target.id, "button2", "Button2 should lose focus."); + ok(aEvent.relatedTarget === null, "The relatedTarget should be null."); + runTests(); + }); + + button2.focus(); + } + + function Test_ElementsInDifferentDocument() { + var button2 = document.getElementById("button2"); + button2.focus(); + button2.addEventListener("blur", function onBlur(aEvent) { + button2.removeEventListener("blur", onBlur); + is(aEvent.target.id, "button2", "Button2 should lose focus."); + ok(aEvent.relatedTarget === null, "The relatedTarget should be null, since it's in another document."); + }); + + var iframe = document.createElement("iframe"); + iframe.id = "iframe"; + iframe.src = "iframe_bug962251.html"; + window.addEventListener("message", function onMessage(aEvent) { + window.removeEventListener("message", onMessage); + if (aEvent.data == "runNextTest") { + runTests(); + } + }); + document.getElementById("content").appendChild(iframe); + } + + function Test_FocusEventOnWindow() { + var iframe1 = document.createElement("iframe"); + iframe1.id = "iframe1"; + iframe1.src = "about:blank"; + + document.getElementById("content").appendChild(iframe1); + document.getElementById("button2").focus(); + var iframe = document.getElementById("iframe"); + var expectedEventTarget = [iframe.contentDocument, iframe.contentWindow]; + var expectedEventTarget1 = [iframe1.contentDocument, iframe1.contentWindow]; + iframe.contentWindow.addEventListener("focus", function onFocus(aEvent) { + var eventTarget = expectedEventTarget.shift(); + ok(aEvent.target === eventTarget, "Get expected focus event target."); + ok(aEvent.relatedTarget === null, "relatedTarget should be null."); + if (!expectedEventTarget.length) { + iframe.contentWindow.removeEventListener("focus", onFocus, true); + runTests(); + } + }, true); + iframe1.contentWindow.addEventListener("focus", function onFocus(aEvent) { + var eventTarget = expectedEventTarget1.shift(); + ok(aEvent.target === eventTarget, "Get expected focus event target."); + ok(aEvent.relatedTarget === null, "relatedTarget should be null."); + if (!expectedEventTarget1.length) { + iframe1.contentWindow.removeEventListener("focus", onFocus, true); + // Append items for blur event listener + expectedEventTarget1.push(iframe1.contentDocument); + expectedEventTarget1.push(iframe1.contentWindow); + iframe.contentWindow.focus(); + } + }, true); + iframe1.contentWindow.addEventListener("blur", function onBlur(aEvent) { + var eventTarget = expectedEventTarget1.shift(); + ok(aEvent.target === eventTarget, "Get expected blur event target."); + ok(aEvent.relatedTarget === null, "relatedTarget should be null."); + if (!expectedEventTarget1.length) { + iframe1.contentWindow.removeEventListener("blur", onBlur, true); + } + }, true); + iframe1.contentWindow.focus(); + } + + function Test_SetFocusInBlurEvent() { + var button1 = document.getElementById("button1"); + var button2 = document.getElementById("button2"); + var button3 = document.getElementById("button3"); + + button1.focus(); + is(button1.id, document.activeElement.id, "document.activeElement.id is button1"); + + button1.addEventListener("blur", function onBlur(aEvent) { + button1.removeEventListener("blur", onBlur); + info("button1 blur"); + is(aEvent.relatedTarget.id, button2.id, "relatedTarget.id should be button2."); + button3.focus(); + }); + button1.addEventListener("focus", function onFocus(aEvent) { + button1.removeEventListener("focus", onFocus); + info("button1 focus"); + }); + + button2.addEventListener("blur", function onBlur(aEvent) { + button2.removeEventListener("blur", onBlur); + info("button2 blur"); + }); + button2.addEventListener("focus", function onFocus(aEvent) { + button2.removeEventListener("focus", onFocus); + info("button2 focus"); + }); + + button3.addEventListener("blur", function onBlur(aEvent) { + button3.removeEventListener("blur", onBlur); + info("button3 blur"); + }); + button3.addEventListener("focus", function onFocus(aEvent) { + button3.removeEventListener("focus", onFocus); + info("button3 focus"); + ok(aEvent.relatedTarget === null, "aEvent.relatedTarget is null."); + runTests(); + }); + + button2.focus(); + } + + function Test_ListenFocusBlurEventOnWindow1() { + var button2 = document.getElementById("button2"); + button2.focus(); + + var iframe = document.getElementById("iframe"); + var input = iframe.contentDocument.getElementById("textinput"); + var expectedEventTarget = [button2, document, window]; + var expectedEventTarget1 = [iframe.contentDocument, iframe.contentWindow, input]; + window.addEventListener("blur", function onBlur(aEvent) { + var item = expectedEventTarget.shift(); + ok(aEvent.target === item, "Get an expected blur event."); + ok(aEvent.relatedTarget === null, "relatedTarget should be null."); + if (!expectedEventTarget.length) { + iframe.contentWindow.removeEventListener("blur", onBlur, true); + } + }, true); + iframe.contentWindow.addEventListener("focus", function onFocus(aEvent) { + var item = expectedEventTarget1.shift(); + ok(aEvent.target === item, "Get an expected focus event."); + ok(aEvent.relatedTarget === null, "relatedTarget should be null."); + if (!expectedEventTarget1.length) { + iframe.contentWindow.removeEventListener("focus", onFocus, true); + runTests(); + } + }, true); + + input.focus(); + } + + function Test_ListenFocusBlurEventOnWindow2() { + var iframe = document.getElementById("iframe"); + var input = iframe.contentDocument.getElementById("textinput"); + var input1 = iframe.contentDocument.getElementById("textinput1"); + + ok(iframe.contentDocument.activeElement === input, "Current focused element should be input."); + iframe.contentWindow.addEventListener("focus", function onFocus(aEvent) { + iframe.contentWindow.removeEventListener("focus", onFocus, true); + ok(aEvent.target === input1, "Input1 is focused."); + ok(aEvent.relatedTarget === input, "relatedTarget should be input."); + runTests(); + }, true); + iframe.contentWindow.addEventListener("blur", function onBlur(aEvent) { + iframe.contentWindow.removeEventListener("blur", onBlur, true); + ok(aEvent.target === input, "Input is not focused."); + ok(aEvent.relatedTarget === input1, "relatedTarget should be input1."); + }, true); + + input1.focus(); + } + + function Test_ListenFocusBlurEventOnWindow3() { + var iframe = document.getElementById("iframe"); + var input1 = iframe.contentDocument.getElementById("textinput1"); + + ok(iframe.contentDocument.activeElement === input1, "Current focused element should be input1."); + iframe.contentWindow.addEventListener("blur", function onBlur(aEvent) { + iframe.contentWindow.removeEventListener("blur", onBlur, true); + ok(aEvent.target === input1, "Input1 is not focused."); + ok(aEvent.relatedTarget === null, "relatedTarget should be null."); + runTests(); + }, true); + + input1.blur(); + } + + var tests = [ + Test_ElementsInTheSameDocument, + Test_ElementsInDifferentDocument, + Test_FocusEventOnWindow, + Test_SetFocusInBlurEvent, + Test_ListenFocusBlurEventOnWindow1, + Test_ListenFocusBlurEventOnWindow2, + Test_ListenFocusBlurEventOnWindow3 + ]; + + function runTests() + { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + window.setTimeout(function () { + test(); + }); + } + + </script> +</head> +<body onload="runTests();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=962251">Mozilla Bug 962251</a> +<p id="display"></p> +<div id="content"> + <button id="button1">1</button> + <button id="button2">2</button> + <button id="button3">3</button> +</div> +<pre id="test"> +</pre> +</body> +</html>
\ No newline at end of file diff --git a/dom/base/test/test_bug976673.html b/dom/base/test/test_bug976673.html new file mode 100644 index 0000000000..d028f70d8a --- /dev/null +++ b/dom/base/test/test_bug976673.html @@ -0,0 +1,107 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=976673 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 976673</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=976673">Mozilla Bug 976673</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<input id="input" onfocus="event.target.value = event.type;" + onblur="event.target.value = event.type;"> +<button id="button">set focus</button> +<iframe id="iframe" src="http://example.org:80/tests/dom/base/test/iframe_bug976673.html"></iframe> +<script> + +SimpleTest.waitForExplicitFinish(); + +// In e10s mode, ContentCacheInChild tries to retrieve selected text and +// caret position when IMEContentObserver notifies IME of focus. At this time, +// we hit assertion in nsContentIterator. +SimpleTest.expectAssertions(0, 6); + +window.addEventListener("mousedown", function (aEvent) { aEvent.preventDefault(); }, false); + +function testSetFocus(aEventType, aCallback) +{ + var description = "Setting focus from " + aEventType + " handler: "; + + var iframe = document.getElementById("iframe"); + iframe.contentWindow.focus(); + + window.addEventListener("message", function (aEvent) { + window.removeEventListener("message", arguments.callee, false); + is(aEvent.data, "input-value: focus", + description + "<input> in the iframe should get focus"); + + + var input = document.getElementById("input"); + input.value = ""; + + var button = document.getElementById("button"); + + var movingFocus = false; + button.addEventListener(aEventType, + function (aEvent) { + movingFocus = true; + input.focus(); + aEvent.preventDefault(); + button.removeEventListener(aEventType, arguments.callee, true); + }, true); + + synthesizeMouseAtCenter(button, {}); + + window.addEventListener("message", function (aEvent) { + window.removeEventListener("message", arguments.callee, false); + if (movingFocus) { + is(aEvent.data, "input-value: blur", + description + "<input> in the iframe should get blur"); + is(input.value, "focus", + description + "<input> in the parent should get focus"); + } else { + is(aEvent.data, "input-value: focus", + description + "<input> in the iframe should keep having focus"); + } + + setTimeout(aCallback, 0); + }, false); + + iframe.contentWindow.postMessage("check", "*"); + }, false); + + iframe.contentWindow.postMessage("init", "*"); +} + +function runTests() +{ + testSetFocus("mousedown", + function () { + testSetFocus("mouseup", + function () { + testSetFocus("click", + function () { + testSetFocus("DoNothing", // testing wihout moving focus by script + function () { + SimpleTest.finish(); + }); + }); + }); + }); +} + +SimpleTest.waitForFocus(runTests); + +</script> +</body> +</html> diff --git a/dom/base/test/test_bug982153.html b/dom/base/test/test_bug982153.html new file mode 100644 index 0000000000..17121d4e2b --- /dev/null +++ b/dom/base/test/test_bug982153.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=982153 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 982153</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script> + +var sc = document.createElement("script"); +var error = null; +sc.textContent = "try {\n reference_error; } catch(e) { error = e; }"; +document.documentElement.appendChild(sc); +is(error.lineNumber, 2, "Error line number must be correct"); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=982153">Mozilla Bug 982153</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_bug999456.html b/dom/base/test/test_bug999456.html new file mode 100644 index 0000000000..6f5cd7a006 --- /dev/null +++ b/dom/base/test/test_bug999456.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=999456 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 999456</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 999456 **/ + + SimpleTest.waitForExplicitFinish(); + addEventListener("load", function (e) { + is(e.cancelable, false, "Load events should not be cancelable"); + SimpleTest.finish(); + }); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=999456">Mozilla Bug 999456</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_caretPositionFromPoint.html b/dom/base/test/test_caretPositionFromPoint.html new file mode 100644 index 0000000000..50f12b1ef6 --- /dev/null +++ b/dom/base/test/test_caretPositionFromPoint.html @@ -0,0 +1,123 @@ +<!doctype html> +<html> +<!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=654352 +--> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <title>Test for Bug 654352</title> + <style> + @font-face { + font-family: Ahem; + src: url("Ahem.ttf"); + } + + #a { + font-family: Ahem; + padding: 10px; + border: 8px solid black; + width: 450px; + } + + #test5 { + height: 100px; + } + + textarea, input { + -moz-appearance: none; + } + </style> +<script> + function convertEmToPx(aEm) { + // Assumes our base font size is 16px = 12pt = 1.0em. + var pxPerEm = 16.0 / 1.0; + return pxPerEm * aEm; + } + + function checkOffsetsFromPoint(aX, aY, aExpected, aElementName='no-name') { + var cp = document.caretPositionFromPoint(aX, aY); + if (!cp) { + ok(false, 'caretPositionFromPoint returned null for point: (' + aX + ', ' + aY + ')'); + return; + } + + ok(aExpected == cp.offset, 'expected offset at (' + aX + ', ' + aY + ') [' + aElementName + ']: ' + aExpected + ', got: ' + cp.offset); + } + + function doTesting() { + var test1Element = document.getElementById("test1"); + var test1Rect = test1Element.getBoundingClientRect(); + + // Check the first and last characters of the basic div. + checkOffsetsFromPoint(Math.round(test1Rect.left + 1), Math.round(test1Rect.top + 1), 0, 'test1'); + checkOffsetsFromPoint(Math.round(test1Rect.left + test1Rect.width - 1), Math.round(test1Rect.top + 1), 13, 'test1'); + + // Check a middle character in the second line of the div. + // To do this, we calculate 7em in from the left of the bounding + // box, and convert this to PX. (Hence the reason we need the AHEM + // font). + var pixelsLeft = convertEmToPx(7); + var test2Element = document.getElementById("test2"); + var test2Rect = test2Element.getBoundingClientRect(); + checkOffsetsFromPoint(Math.round(test2Rect.left + pixelsLeft + 1), Math.round(test2Rect.top + 1), 7, 'test2'); + + // Check the first and last characters of the textarea. + var test3Element = document.getElementById('test3'); + var test3Rect = test3Element.getBoundingClientRect(); + checkOffsetsFromPoint(test3Rect.left + 5, test3Rect.top + 5, 0, 'test3'); + checkOffsetsFromPoint(Math.round(test3Rect.left + test3Rect.width - 15), Math.round(test3Rect.top + 5), 3, 'test3'); + + // Check the first and last characters of the input. + var test4Element = document.getElementById('test4'); + var test4Rect = test4Element.getBoundingClientRect(); + checkOffsetsFromPoint(test4Rect.left + 5, test4Rect.top + 5, 0, 'test4'); + checkOffsetsFromPoint(Math.round(test4Rect.left + test4Rect.width - 10), Math.round(test4Rect.top + 10), 6, 'test4'); + + // Check to make sure that x or y outside the viewport returns null. + var nullCp1 = document.caretPositionFromPoint(-10, 0); + ok(!nullCp1, "caret position with negative x should be null"); + var nullCp2 = document.caretPositionFromPoint(0, -10); + ok(!nullCp2, "caret position with negative y should be null"); + var nullCp3 = document.caretPositionFromPoint(9000, 0); + ok(!nullCp3, "caret position with x > viewport width should be null"); + var nullCp4 = document.caretPositionFromPoint(0, 9000); + ok(!nullCp4, "caret position with x > viewport height should be null"); + + // Check a point within the bottom whitespace of the input. + var test5Element = document.getElementById('test5'); + var test5Rect = test5Element.getBoundingClientRect(); + var test5x = test5Rect.left + 5; + var test5y = test5Rect.bottom - 10; + + todo(false, "test5Rect: (" + test5Rect.top + ", " + test5Rect.left + ", " + test5Rect.width + ", " + test5Rect.height + ")"); + checkOffsetsFromPoint(test5x, test5y, 0, 'test5'); + + // Check the first and last characters of the numeric input. + var test6Element = document.getElementById("test6"); + var test6Rect = test6Element.getBoundingClientRect(); + checkOffsetsFromPoint(Math.round(test6Rect.left + 5), + Math.round(test6Rect.top + (test6Rect.height / 2)), + 0, "test6"); + checkOffsetsFromPoint(Math.round(test6Rect.left + test6Rect.width - 30), + Math.round(test6Rect.top + (test6Rect.height / 2)), + 5, "test6"); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); +</script> +</head> +<body onload="doTesting();"> +<div id="a" contenteditable><span id="test1">abc, abc, abc</span><br> +<span id="test2" style="color: blue;">abc, abc, abc</span><br> +<textarea id="test3">abc</textarea><input id="test4" value="abcdef"><br><br> +<marquee>marquee</marquee> +</div> +<input id="test5" value="The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly down, so suddenly that Alice had not a moment to think about stopping herself before she found herself falling down a very deep well. Either the well was very deep, or she fell very slowly, for she had plenty of time as she went down to look about her and to wonder what was going to happen next. First, she tried to look down and make out what she was coming to, but it was too dark to see anything; then she looked at the sides of the well, and noticed that they were filled with cupboards and book-shelves; here and there she saw maps and pictures hung upon pegs. She took down a jar from one of the shelves as she passed; it was labelled `ORANGE MARMALADE', but to her great disappointment it was empty: she did not like to drop the jar for fear of killing somebody, so managed to put it into one of the cupboards as she fell past it." type="text"> +<input id="test6" type="number" style="width:150px; height:57px;" value="31415"><br> +</body> +</html> diff --git a/dom/base/test/test_change_policy.html b/dom/base/test/test_change_policy.html new file mode 100644 index 0000000000..76816f01fe --- /dev/null +++ b/dom/base/test/test_change_policy.html @@ -0,0 +1,129 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test policies for Bug 1101288</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<!-- +This checks if the right policies are applied from a given string when the policy is changed after the document has been loaded. +https://bugzilla.mozilla.org/show_bug.cgi?id=1101288 +--> +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * Listen for notifications from the child. + * These are sent in case of error, or when the loads we await have completed. + */ +window.addEventListener("message", function(event) { + if (event.data == "childLoadComplete") { + // all loads happen, continue the test. + advance(); + } +}); + +/** + * helper to perform an XHR. + */ +function doXHR(aUrl, onSuccess, onFail) { + var xhr = new XMLHttpRequest(); + xhr.responseType = "json"; + xhr.onload = function () { + onSuccess(xhr); + }; + xhr.onerror = function () { + onFail(xhr); + }; + xhr.open('GET', aUrl, true); + xhr.send(null); +} + +/** + * Grabs the results via XHR and passes to checker. + */ +function checkIndividualResults(aTestname, aExpectedReferrer, aName) { + doXHR('/tests/dom/base/test/referrer_change_server.sjs?action=get-test-results', + function(xhr) { + var results = xhr.response; + info(JSON.stringify(xhr.response)); + + for (i in aName) { + ok(aName[i] in results.tests, aName[i] + " tests have to be performed."); + is(results.tests[aName[i]].policy, aExpectedReferrer[i], aTestname + ' --- ' + results.tests[aName[i]].policy + ' (' + results.tests[aName[i]].referrer + ')'); + } + advance(); + }, + function(xhr) { + ok(false, "Can't get results from the counter server."); + SimpleTest.finish(); + }); +} + +function resetState() { + doXHR('/tests/dom/base/test/referrer_change_server.sjs?action=resetState', + advance, + function(xhr) { + ok(false, "error in reset state"); + SimpleTest.finish(); + }); +} + + +/** + * This is the main test routine -- serialized by use of a generator. + * It resets the counter, then performs two tests in sequence using + * the same iframe. + */ +var tests = (function() { + var iframe = document.getElementById("testframe"); + var sjs = "/tests/dom/base/test/referrer_change_server.sjs?action=generate-policy-test"; + + yield resetState(); + var name = "no-referrer-unsafe-url"; + yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name + "&newPolicy=" + escape('unsafe-url'); + yield checkIndividualResults("unsafe-url (changed) with no-referrer first", ["full"], [name+'unsafe-url']); + + yield resetState(); + var name = "origin-no-referrer"; + yield iframe.src = sjs + "&policy=" + escape('origin') + "&name=" + name + "&newPolicy=" + escape('no-referrer'); + yield checkIndividualResults("no-referrer (changed) with origin first", ["none"], [name+'no-referrer']); + + yield resetState(); + var name = "unsafe-url-no-referrer"; + yield iframe.src = sjs + "&policy=" + escape('unsafe-url') + "&name=" + name + "&newPolicy=" + escape('no-referrer'); + yield checkIndividualResults("no-referrer (changed) with unsafe-url first", ["none"], [name+'no-referrer']); + + sjs = "/tests/dom/base/test/referrer_change_server.sjs?action=generate-policy-test2"; + + yield resetState(); + var name = "no-referrer-unsafe-url"; + yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name + "&newPolicy=" + escape('unsafe-url'); + yield checkIndividualResults("unsafe-url (changed) with no-referrer first", ["full"], [name+'unsafe-url']); + + yield resetState(); + var name = "origin-no-referrer"; + yield iframe.src = sjs + "&policy=" + escape('origin') + "&name=" + name + "&newPolicy=" + escape('no-referrer'); + yield checkIndividualResults("no-referrer (changed) with origin first", ["none"], [name+'no-referrer']); + + yield resetState(); + var name = "unsafe-url-no-referrer"; + yield iframe.src = sjs + "&policy=" + escape('unsafe-url') + "&name=" + name + "&newPolicy=" + escape('no-referrer'); + yield checkIndividualResults("no-referrer (changed) with unsafe-url first", ["none"], [name+'no-referrer']); + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> + diff --git a/dom/base/test/test_classList.html b/dom/base/test/test_classList.html new file mode 100644 index 0000000000..2a108d7f55 --- /dev/null +++ b/dom/base/test/test_classList.html @@ -0,0 +1,426 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=501257 +--> +<head> + <title>Test for the classList element attribute</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="http://www.whatwg.org/specs/web-apps/current-work/#dom-classlist">classList DOM attribute</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 501257 **/ + +const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; +const SVG_NS = "http://www.w3.org/2000/svg"; +const XHTML_NS = "http://www.w3.org/1999/xhtml" +const MATHML_NS = "http://www.w3.org/1998/Math/MathML"; + +var gMutationEvents = []; + +function onAttrModified(event) { + is(event.attrName, "class", "mutation on unexpected attribute"); + + gMutationEvents.push({ + attrChange: event.attrChange, + prevValue: event.prevValue, + newValue: event.newValue, + }); +} + +function checkModification(e, funcName, args, expectedRes, before, after, expectedException) { + if (!Array.isArray(args)) { + args = [args]; + } + + var shouldThrow = typeof(expectedException) === "string"; + if (shouldThrow) { + // If an exception is thrown, the class attribute shouldn't change. + after = before; + } + if (before === null) + e.removeAttribute("class"); + else + e.setAttribute("class", before); + + var contextMsg = "(checkModification: funcName=" + funcName + ",args=" + + JSON.stringify(args) + ",expectedRes=" + expectedRes + + ",before=" + before + ",after=" + after + ")"; + + gMutationEvents = []; + e.addEventListener("DOMAttrModified", onAttrModified, false); + try { + var list = e.classList; + var res = list[funcName].apply(list, args); + if (shouldThrow) + ok(false, "classList modification didn't throw " + contextMsg); + } catch (e) { + if (!shouldThrow) + ok(false, "classList modification threw an exception " + contextMsg); + is(e.name, expectedException, "wrong exception thrown " + contextMsg); + } + e.removeEventListener("DOMAttrModified", onAttrModified, false); + if (expectedRes !== null) + is(res, expectedRes, "wrong return value from " + funcName + + " " + contextMsg); + + var expectedAfter = after; + // XUL returns an empty string when getting a nonexistent class attribute. + if (e.namespaceURI == XUL_NS && expectedAfter === null) + expectedAfter = ""; + + is(e.getAttribute("class"), expectedAfter, "wrong class after modification " + + contextMsg); + var expectedMutation = before != after; + is(gMutationEvents.length, expectedMutation ? 1 : 0, + "unexpected mutation event count " + contextMsg); + if (expectedMutation && gMutationEvents.length) { + is(gMutationEvents[0].attrChange, + before == null ? MutationEvent.ADDITION : MutationEvent.MODIFICATION, + "wrong type of attribute change " + contextMsg); + // If there wasn't any previous attribute, prevValue will return an empty + // string. + var expectedPrevValue = before === null ? "" : before; + is(gMutationEvents[0].prevValue, expectedPrevValue, + "wrong previous value " + contextMsg); + is(gMutationEvents[0].newValue, after, "wrong new value " + contextMsg); + } +} + +function assignToClassListStrict(e) { + "use strict"; + try { + e.classList = "foo"; + ok(true, "assigning to classList didn't throw"); + e.removeAttribute("class"); + } catch (e) { + ok(false, "assigning to classList threw"); + } +} + +function assignToClassList(e) { + try { + var expect = e.classList; + e.classList = "foo"; + ok(true, "assigning to classList didn't throw"); + is(e.classList, expect, "classList should be unchanged after assignment"); + e.removeAttribute("class"); + } catch (e) { + ok(false, "assigning to classList threw"); + } +} + +function testClassList(e) { + + // basic tests + + isnot(e.classList, undefined, "no classList attribute"); + is(typeof(e.classList.contains), "function", + "no classList.contains function"); + is(typeof(e.classList.add), "function", "no classList.add function"); + is(typeof(e.classList.remove), "function", "no classList.remove function"); + is(typeof(e.classList.toggle), "function", "no classList.toggle function"); + + assignToClassListStrict(e); + assignToClassList(e); + + // length attribute + + is(e.classList.length, 0, "wrong classList.length value"); + e.setAttribute("class", ""); + is(e.classList.length, 0, "wrong classList.length value"); + e.setAttribute("class", " \t \f"); + is(e.classList.length, 0, "wrong classList.length value"); + + e.setAttribute("class", "a"); + is(e.classList.length, 1, "wrong classList.length value"); + e.setAttribute("class", "a A"); + is(e.classList.length, 2, "wrong classList.length value"); + e.setAttribute("class", "\r\na\t\f"); + is(e.classList.length, 1, "wrong classList.length value"); + + e.setAttribute("class", "a a"); + is(e.classList.length, 2, "wrong classList.length value"); + + e.setAttribute("class", "a a a a a a"); + is(e.classList.length, 6, "wrong classList.length value"); + + e.setAttribute("class", "a a b b"); + is(e.classList.length, 4, "wrong classList.length value"); + + e.setAttribute("class", "a A B b"); + is(e.classList.length, 4, "wrong classList.length value"); + + e.setAttribute("class", "a b c c b a a b c c"); + is(e.classList.length, 10, "wrong classList.length value"); + + // [Stringifies] + + ok(DOMTokenList.prototype.hasOwnProperty("toString"), + "Should have own toString on DOMTokenList") + + e.removeAttribute("class"); + is(e.classList.toString(), "", "wrong classList.toString() value"); + is(e.classList + "", "", "wrong classList string conversion value"); + + e.setAttribute("class", "foo"); + is(e.classList.toString(), "foo", "wrong classList.toString() value"); + is(e.classList + "", "foo", "wrong classList string conversion value"); + + // item() method + + e.setAttribute("class", "a"); + is(e.classList.item(-1), null, "wrong classList.item() result"); + is(e.classList[-1], undefined, "wrong classList[] result"); + is(e.classList.item(0), "a", "wrong classList.item() result"); + is(e.classList[0], "a", "wrong classList[] result"); + is(e.classList.item(1), null, "wrong classList.item() result"); + is(e.classList[1], undefined, "wrong classList[] result"); + + e.setAttribute("class", "aa AA aa"); + is(e.classList.item(-1), null, "wrong classList.item() result"); + is(e.classList[-1], undefined, "wrong classList[] result"); + is(e.classList.item(0), "aa", "wrong classList.item() result"); + is(e.classList[0], "aa", "wrong classList[] result"); + is(e.classList.item(1), "AA", "wrong classList.item() result"); + is(e.classList[1], "AA", "wrong classList[] result"); + is(e.classList.item(2), "aa", "wrong classList.item() result"); + is(e.classList[2], "aa", "wrong classList[] result"); + is(e.classList.item(3), null, "wrong classList.item() result"); + is(e.classList[3], undefined, "wrong classList[] result"); + is(e.classList.item(0xffffffff), null, "wrong classList.item() result"); + is(e.classList[0xffffffff], undefined, "wrong classList[] result"); + is(e.classList.item(0xfffffffe), null, "wrong classList.item() result"); + is(e.classList[0xffffffe], undefined, "wrong classList[] result"); + + e.setAttribute("class", "a b"); + is(e.classList.item(-1), null, "wrong classList.item() result"); + is(e.classList[-1], undefined, "wrong classList[] result"); + is(e.classList.item(0), "a", "wrong classList.item() result"); + is(e.classList[0], "a", "wrong classList[] result"); + is(e.classList.item(1), "b", "wrong classList.item() result"); + is(e.classList[1], "b", "wrong classList[] result"); + is(e.classList.item(2), null, "wrong classList.item() result"); + is(e.classList[2], undefined, "wrong classList[] result"); + + // contains() method + + e.removeAttribute("class"); + is(e.classList.contains("a"), false, "wrong classList.contains() result"); + try { + e.classList.contains(""); + ok(true, "classList.contains(empty_string) didn't throw"); + } catch (e) { + ok(false, "classList.contains(empty_string) threw"); + } + try { + e.classList.contains(" "); + ok(true, "classList.contains(string_with_spaces) didn't throw"); + } catch (e) { + ok(false, "classList.contains(string_with_spaces) threw"); + } + try { + e.classList.contains("aa "); + ok(true, "classList.contains(string_with_spaces) didn't throw"); + } catch (e) { + ok(false, "classList.contains(string_with_spaces) threw"); + } + + e.setAttribute("class", ""); + is(e.classList.contains("a"), false, "wrong classList.contains() result"); + + e.setAttribute("class", "a"); + is(e.classList.contains("a"), true, "wrong classList.contains() result"); + is(e.classList.contains("aa"), false, "wrong classList.contains() result"); + is(e.classList.contains("b"), false, "wrong classList.contains() result"); + + e.setAttribute("class", "aa AA"); + is(e.classList.contains("aa"), true, "wrong classList.contains() result"); + is(e.classList.contains("AA"), true, "wrong classList.contains() result"); + is(e.classList.contains("aA"), false, "wrong classList.contains() result"); + + e.setAttribute("class", "a a a"); + is(e.classList.contains("a"), true, "wrong classList.contains() result"); + is(e.classList.contains("aa"), false, "wrong classList.contains() result"); + is(e.classList.contains("b"), false, "wrong classList.contains() result"); + + e.setAttribute("class", "a b c"); + is(e.classList.contains("a"), true, "wrong classList.contains() result"); + is(e.classList.contains("b"), true, "wrong classList.contains() result"); + + // Test for bug 530171 + e.setAttribute("class", "null undefined"); + is(e.classList.contains(null), true, "wrong classList.contains() result"); + is(e.classList.contains(undefined), true, "wrong classList.contains() result"); + + // add() method + + function checkAdd(before, argument, after, expectedException) { + checkModification(e, "add", argument, null, before, after, expectedException); + } + + checkAdd(null, "", null, "SyntaxError"); + checkAdd(null, ["a", ""], null, "SyntaxError"); + checkAdd(null, " ", null, "InvalidCharacterError"); + checkAdd(null, ["a", " "], null, "InvalidCharacterError"); + checkAdd(null, ["a", "aa "], null, "InvalidCharacterError"); + + checkAdd("a", "a", "a"); + checkAdd("aa", "AA", "aa AA"); + checkAdd("a b c", "a", "a b c"); + checkAdd("a a a b", "a", "a a a b"); + checkAdd(null, "a", "a"); + checkAdd("", "a", "a"); + checkAdd(" ", "a", " a"); + checkAdd(" \f", "a", " \fa"); + checkAdd("a", "b", "a b"); + checkAdd("a b c", "d", "a b c d"); + checkAdd("a b c ", "d", "a b c d"); + + // multiple add + checkAdd("a b c ", ["d", "e"], "a b c d e"); + checkAdd("a b c ", ["a", "a"], "a b c "); + checkAdd("a b c ", ["d", "d"], "a b c d"); + checkAdd("a b c ", [], "a b c "); + checkAdd(null, ["a", "b"], "a b"); + checkAdd("", ["a", "b"], "a b"); + + // Test for bug 530171 + checkAdd(null, null, "null"); + checkAdd(null, undefined, "undefined"); + + // remove() method + + function checkRemove(before, argument, after, expectedException) { + checkModification(e, "remove", argument, null, before, after, expectedException); + } + + checkRemove(null, "", null, "SyntaxError"); + checkRemove(null, " ", null, "InvalidCharacterError"); + checkRemove(null, "aa ", null, "InvalidCharacterError"); + + checkRemove(null, "a", null); + checkRemove("", "a", ""); + checkRemove("a b c", "d", "a b c"); + checkRemove("a b c", "A", "a b c"); + checkRemove(" a a a ", "a", ""); + checkRemove("a b", "a", "b"); + checkRemove("a b ", "a", "b"); + checkRemove("a a b", "a", "b"); + checkRemove("aa aa bb", "aa", "bb"); + checkRemove("a a b a a c a a", "a", "b c"); + + checkRemove("a b c", "b", "a c"); + checkRemove("aaa bbb ccc", "bbb", "aaa ccc"); + checkRemove(" a b c ", "b", "a c"); + checkRemove("a b b b c", "b", "a c"); + + checkRemove("a b c", "c", "a b"); + checkRemove(" a b c ", "c", "a b"); + checkRemove("a b c c c", "c", "a b"); + + checkRemove("a b a c a d a", "a", "b c d"); + checkRemove("AA BB aa CC AA dd aa", "AA", "BB aa CC dd aa"); + + checkRemove("\ra\na\ta\f", "a", ""); + + // multiple remove + checkRemove("a b c ", ["d", "e"], "a b c"); + checkRemove("a b c ", ["a", "b"], "c"); + checkRemove("a b c ", ["a", "c"], "b"); + checkRemove("a b c ", ["a", "a"], "b c"); + checkRemove("a b c ", ["d", "d"], "a b c"); + checkRemove("a b c ", [], "a b c"); + checkRemove(null, ["a", "b"], null); + checkRemove("", ["a", "b"], ""); + + // Test for bug 530171 + checkRemove("null", null, ""); + checkRemove("undefined", undefined, ""); + + // toggle() method + + function checkToggle(before, argument, expectedRes, after, expectedException) { + checkModification(e, "toggle", argument, expectedRes, before, after, expectedException); + } + + checkToggle(null, "", null, null, "SyntaxError"); + checkToggle(null, "aa ", null, null, "InvalidCharacterError"); + + checkToggle(null, "a", true, "a"); + checkToggle("", "a", true, "a"); + checkToggle(" ", "a", true, " a"); + checkToggle(" \f", "a", true, " \fa"); + checkToggle("a", "b", true, "a b"); + checkToggle("a", "A", true, "a A"); + checkToggle("a b c", "d", true, "a b c d"); + checkToggle("a b c", "d", true, "a b c d"); + + checkToggle("a", "a", false, ""); + checkToggle(" a a a ", "a", false, ""); + checkToggle(" A A A ", "a", true, " A A A a"); + checkToggle(" a b c ", "b", false, "a c"); + checkToggle(" a b c b b", "b", false, "a c"); + checkToggle(" a b c ", "c", false, "a b"); + checkToggle(" a b c ", "a", false, "b c"); + + // Test for bug 530171 + checkToggle("null", null, false, ""); + checkToggle("", null, true, "null"); + checkToggle("undefined", undefined, false, ""); + checkToggle("", undefined, true, "undefined"); + + + // tests for the force argument handling + + function checkForceToggle(before, argument, force, expectedRes, after, expectedException) { + checkModification(e, "toggle", [argument, force], expectedRes, before, after, expectedException); + } + + checkForceToggle("", "a", true, true, "a"); + checkForceToggle("a", "a", true, true, "a"); + checkForceToggle("a", "b", true, true, "a b"); + checkForceToggle("a b", "b", true, true, "a b"); + checkForceToggle("", "a", false, false, ""); + checkForceToggle("a", "a", false, false, ""); + checkForceToggle("a", "b", false, false, "a"); + checkForceToggle("a b", "b", false, false, "a"); +} + +var content = document.getElementById("content"); + +var htmlNode = document.createElement("div"); +content.appendChild(htmlNode); +testClassList(htmlNode); + +var xhtmlNode = document.createElementNS(XHTML_NS, "div"); +content.appendChild(xhtmlNode); +testClassList(xhtmlNode); + +var xulNode = document.createElementNS(XUL_NS, "box"); +content.appendChild(xulNode); +testClassList(xulNode); + +var mathMLNode = document.createElementNS(MATHML_NS, "math"); +content.appendChild(mathMLNode); +testClassList(mathMLNode); + +var xmlNode = document.createElementNS(null, "foo"); +content.appendChild(xmlNode); +testClassList(xmlNode); + +var fooNode = document.createElementNS("http://example.org/foo", "foo"); +content.appendChild(fooNode); +testClassList(fooNode); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_clearTimeoutIntervalNoArg.html b/dom/base/test/test_clearTimeoutIntervalNoArg.html new file mode 100644 index 0000000000..e1d60022fb --- /dev/null +++ b/dom/base/test/test_clearTimeoutIntervalNoArg.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for clearTimeout/clearInterval with no arguments not throwing</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> +test(function() { + clearTimeout(); +}, "clearTimeout with no args should not throw "); +test(function() { + clearInterval(); +}, "clearInterval with no args should not throw "); +</script> diff --git a/dom/base/test/test_constructor-assignment.html b/dom/base/test/test_constructor-assignment.html new file mode 100644 index 0000000000..f04a991dad --- /dev/null +++ b/dom/base/test/test_constructor-assignment.html @@ -0,0 +1,61 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE html> +<html> +<head> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script type="application/javascript"> +function testConstructor(name) +{ + window[name] = 17; // resolve through assignment + + + var desc = Object.getOwnPropertyDescriptor(window, name); + ok(typeof desc === "object" && desc !== null, name + ": property must exist"); + + is(desc.value, 17, name + ": overwrite didn't work correctly"); + is(desc.enumerable, false, + name + ": initial descriptor was non-enumerable, and [[Put]] changes " + + "the property value but not its enumerability"); + is(desc.configurable, true, + name + ": initial descriptor was configurable, and [[Put]] changes the " + + "property value but not its configurability"); + is(desc.writable, true, + name + ": initial descriptor was writable, and [[Put]] changes the " + + "property value but not its writability"); +} + +var ctors = + [ + "HTMLElement", + "HTMLDivElement", + "HTMLSpanElement", + "HTMLParagraphElement", + "HTMLOptionElement", + "HTMLHtmlElement", + "Element", + "Node", + "Document", + "Image", + "Audio", + "HTMLAudioElement", + "HTMLVideoElement", + "Window", + "XMLHttpRequest", + "Navigator", + "WebSocket", + "Event", + "IDBKeyRange", + "CSSPageRule", + "SVGPatternElement", + ]; + +ctors.forEach(testConstructor); +</script> +</body> +</html> diff --git a/dom/base/test/test_constructor.html b/dom/base/test/test_constructor.html new file mode 100644 index 0000000000..b987057e29 --- /dev/null +++ b/dom/base/test/test_constructor.html @@ -0,0 +1,61 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE html> +<html> +<head> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<script type="application/javascript"> +function testConstructor(name) +{ + window[name]; // resolve not through assignment + window[name] = 17; + + var desc = Object.getOwnPropertyDescriptor(window, name); + ok(typeof desc === "object" && desc !== null, name + ": property must exist"); + + is(desc.value, 17, name + ": overwrite didn't work correctly"); + is(desc.enumerable, false, + name + ": initial descriptor was non-enumerable, and [[Put]] changes " + + "the property value but not its enumerability"); + is(desc.configurable, true, + name + ": initial descriptor was configurable, and [[Put]] changes the " + + "property value but not its configurability"); + is(desc.writable, true, + name + ": initial descriptor was writable, and [[Put]] changes the " + + "property value but not its writability"); +} + +var ctors = + [ + "HTMLElement", + "HTMLDivElement", + "HTMLSpanElement", + "HTMLParagraphElement", + "HTMLOptionElement", + "HTMLHtmlElement", + "Element", + "Node", + "Document", + "Image", + "Audio", + "HTMLAudioElement", + "HTMLVideoElement", + "Window", + "XMLHttpRequest", + "Navigator", + "WebSocket", + "Event", + "IDBKeyRange", + "CSSPageRule", + "SVGPatternElement", + ]; + +ctors.forEach(testConstructor); +</script> +</body> +</html> diff --git a/dom/base/test/test_copyimage.html b/dom/base/test/test_copyimage.html new file mode 100644 index 0000000000..a2610e360f --- /dev/null +++ b/dom/base/test/test_copyimage.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=518249 +https://bugzilla.mozilla.org/show_bug.cgi?id=952456 +--> +<head> + <title>Test for copy image</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=518249">Mozilla Bug 518249</a> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=952456">Mozilla Bug 952456</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function testCopyImage () { + var Ci = SpecialPowers.Ci; + var Cc = SpecialPowers.Cc; + var clipboard = SpecialPowers.Services.clipboard; + + function getClipboardData(mime) { + var transferable = Cc['@mozilla.org/widget/transferable;1'] + .createInstance(Ci.nsITransferable); + var loadingContext = SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsILoadContext); + transferable.init(loadingContext); + transferable.addDataFlavor(mime); + clipboard.getData(transferable, 1); + var data = SpecialPowers.createBlankObject(); + transferable.getTransferData(mime, data, {}); + return data; + } + + function testClipboardValue(mime, expected) { + var data = SpecialPowers.wrap(getClipboardData(mime)); + var str = data.value == null ? data.value : + data.value.QueryInterface(Ci.nsISupportsString).data; + is(str, expected, "clipboard has correct [" + mime + "] content") + } + + //--------- Prepare data and copy it. + + // Select the node. + var node = document.getElementById('logo'); + + // Set node and copy image. + var webnav = SpecialPowers.wrap(window) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + var docShell = webnav.QueryInterface(Ci.nsIDocShell); + var documentViewer = docShell.contentViewer + .QueryInterface(Ci.nsIContentViewerEdit); + documentViewer.setCommandNode(node); + documentViewer.copyImage(documentViewer.COPY_IMAGE_ALL); + + //--------- Let's check the content of the clipboard now. + + // Does the clipboard contain text/unicode data ? + ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard), "clipboard contains unicode text"); + // Does the clipboard contain text/html data ? + ok(clipboard.hasDataMatchingFlavors(["text/html"], 1, clipboard.kGlobalClipboard), "clipboard contains html text"); + // Does the clipboard contain image data ? + ok(clipboard.hasDataMatchingFlavors(["image/png"], 1, clipboard.kGlobalClipboard), "clipboard contains image"); + + // Is the text/uncodie data correct ? + testClipboardValue('text/unicode', 'about:logo'); + // Is the text/html data correct ? + var expected = '<img id="logo" src="about:logo">'; + if (navigator.platform.indexOf("Win") >= 0) { + expected = "<html><body>\n<!--StartFragment-->" + expected + "<!--EndFragment-->\n</body>\n</html>"; + } + testClipboardValue('text/html', expected); + + SimpleTest.finish(); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + SpecialPowers.pushPrefEnv({"set": [["clipboard.plainTextOnly", false]]}, testCopyImage); +}); + +</script> +</pre> +<div> + <img id="logo" src="about:logo"> +</div> +</body> +</html> diff --git a/dom/base/test/test_copypaste.html b/dom/base/test/test_copypaste.html new file mode 100644 index 0000000000..db929270de --- /dev/null +++ b/dom/base/test/test_copypaste.html @@ -0,0 +1,119 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test for copy/paste</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <script type="text/javascript" src="copypaste.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=524975">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(() => testCopyPaste(false)); + +</script> +</pre> +<div> + + <div id="draggable" title="title to have a long HTML line">This is a <em>draggable</em> bit of text.</div> + <textarea id="input" cols="40" rows="10"></textarea> + + <div id="alist"> + bla + <ul> + <li>foo</li> + <li style="display: none;">baz</li> + <li>bar</li> + </ul> + </div> + + <div id="blist"> + mozilla + <ol> + <li>foo</li> + <li style="display: none;">baz</li> + <li>bar</li> + </ol> + </div> + + <div id="clist"> + mzla + <ul> + <li>foo<ul> + <li>bazzinga!</li> + </ul></li> + <li style="display: none;">baz</li> + <li>bar</li> + </ul> + </div> + +<div id="div4"> + T<textarea>t t t</textarea> +</div> + +<div id="div5"> + T<textarea> </textarea> +</div> + +<div>Copy1then Paste<ul id="ul1"><li>LI</li> +</ul></div> + +<div><ul id="ul2"> +<li>LI</li></ul>Copy2then Paste</div> + +<div><ul id="ul3"><li> +<li>LI</li></ul>Copy3then Paste</div> + +<div><div id="div1s"><div id="div1se1">before<div>inner</div></div>after</div></div> +<div><div id="div2s"><div id="div2se1">before<div>inner</div></div>after</div> +</div> + +<div id="contentEditable1" contenteditable spellcheck="false"></div> +<div id="contentEditable2" contenteditable spellcheck="false"></div> +<div id="contentEditable3" contenteditable spellcheck="false"></div> +<div id="contentEditable4" contenteditable spellcheck="false"></div> +<div id="contentEditable5" contenteditable spellcheck="false"></div> + +<div> +<span id="1127835crash1">1</span><div id="1127835crash2"><div> +</div></div><a href="http://www.mozilla.org/" id="1127835crash3">3</a> +</div> +<div id="contentEditable6" contenteditable spellcheck="false"></div> + +<div id="div6" style="display:none"></div> +<script> +var x = $("div6") +x.appendChild(document.createTextNode('di')) +x.appendChild(document.createTextNode('v6')) +</script> + +<div id="div7" style="display:none">div7</div> +<div id="div8" style="visibility:hidden">div8</div> +<div style="visibility:hidden"><div id="div9" style="visibility:visible">div9</div></div> +<div style="visibility:hidden"><div><div><div id="div10"></div></div></div></div> +<script> +var x = $("div10") +x.appendChild(document.createTextNode('div')) +x.appendChild(document.createTextNode('10')) +</script> + +<div id="div11" oncopy="modifySelection('X')"><span>div</span>11</div> +<div id="div12" oncopy="modifySelection('X<b style=\'display:none\'>Y</b>')"><span>div</span>12</div> + +<div id="div13">_<noscript>FAIL</noscript>_</div> + +<table><tr id=tr1><td>foo</td><td>bar</td></tr></table> +<table><tr id=tr2><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr><tr id=tr3><td>5</td><td>6</td></tr></table> + +</div> +</body> +</html> diff --git a/dom/base/test/test_copypaste.xhtml b/dom/base/test/test_copypaste.xhtml new file mode 100644 index 0000000000..9b06cb8b89 --- /dev/null +++ b/dom/base/test/test_copypaste.xhtml @@ -0,0 +1,108 @@ +<?xml version="1.0"?> +<!-- +This test is copied from test_copypaste.html, but it's XHTML instead of HTML. +XHTML is encoded differently from HTML when copied; see bugs 888839 and 723163. +This test is different from test_copypaste.html in two ways: + + 1. The text/html clipboard flavor isn't tested, since nsCopySupport doesn't + produce it for XHTML. + 2. The text/unicode flavor isn't tested when the selection is in hidden + elements, since nsCopySupport doesn't produce text/plain for hidden + elements, and unlike HTML, neither does it produce text/_moz_htmlcontext + and text/_moz_htmlinfo, which the clipboard converts to text/unicode. +--> +<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Test for copy/paste with XHTML</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="copypaste.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=888839">Mozilla Bug 888839</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +<![CDATA[ + +function modifySelectionDiv12() { + modifySelection("X<b style='display:none'>Y</b>"); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(() => testCopyPaste(true)); + +]]> +</script> +</pre> +<div> + + <div id="draggable" title="title to have a long HTML line">This is a <em>draggable</em> bit of text.</div> + <textarea id="input" cols="40" rows="10"></textarea> + + <div id="alist"> + bla + <ul> + <li>foo</li> + <li style="display: none;">baz</li> + <li>bar</li> + </ul> + </div> + + <div id="blist"> + mozilla + <ol> + <li>foo</li> + <li style="display: none;">baz</li> + <li>bar</li> + </ol> + </div> + + <div id="clist"> + mzla + <ul> + <li>foo<ul> + <li>bazzinga!</li> + </ul></li> + <li style="display: none;">baz</li> + <li>bar</li> + </ul> + </div> + +<div id="div4"> + T<textarea>t t t</textarea> +</div> + +<div id="div5"> + T<textarea> </textarea> +</div> + +<div id="div6" style="display:none"></div> +<script> +var x = $("div6") +x.appendChild(document.createTextNode('di')) +x.appendChild(document.createTextNode('v6')) +</script> + +<div id="div7" style="display:none">div7</div> +<div id="div8" style="visibility:hidden">div8</div> +<div style="visibility:hidden"><div id="div9" style="visibility:visible">div9</div></div> +<div style="visibility:hidden"><div><div><div id="div10"></div></div></div></div> +<script> +var x = $("div10") +x.appendChild(document.createTextNode('div')) +x.appendChild(document.createTextNode('10')) +</script> + +<div id="div11" oncopy="modifySelection('X')"><span>div</span>11</div> +<div id="div12" oncopy="modifySelectionDiv12()"><span>div</span>12</div> + +<div id="div13">_<noscript>FAIL</noscript>_</div> + +<table><tr id="tr1"><td>foo</td><td>bar</td></tr></table> + +</div> +</body> +</html> diff --git a/dom/base/test/test_copypaste.xul b/dom/base/test/test_copypaste.xul new file mode 100644 index 0000000000..6c14c73575 --- /dev/null +++ b/dom/base/test/test_copypaste.xul @@ -0,0 +1,64 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=888839 +--> +<window title="Mozilla Bug 888839" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <script type="application/javascript"><![CDATA[ + +var { classes: Cc, interfaces: Ci } = Components; + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); + +function runTest() { + let desc = document.querySelector("description"); + window.getSelection().selectAllChildren(desc); + + let webnav = window. + QueryInterface(Ci.nsIInterfaceRequestor). + getInterface(Ci.nsIWebNavigation); + + webnav. + QueryInterface(Ci.nsIDocShell). + contentViewer. + QueryInterface(Ci.nsIContentViewerEdit). + copySelection(); + + let mime = "text/unicode"; + let whichClipboard = Ci.nsIClipboard.kGlobalClipboard; + let clipboard = Cc["@mozilla.org/widget/clipboard;1"]. + getService(Ci.nsIClipboard); + ok(clipboard.hasDataMatchingFlavors([mime], 1, whichClipboard), + "Clipboard should have text/unicode"); + + let transferable = Cc["@mozilla.org/widget/transferable;1"]. + createInstance(Ci.nsITransferable); + transferable.init(webnav.QueryInterface(Ci.nsILoadContext)); + transferable.addDataFlavor(mime); + clipboard.getData(transferable, whichClipboard); + var data = {}; + transferable.getTransferData(mime, data, {}); + is(data.value.QueryInterface(Ci.nsISupportsString).data, + "\n hello\n world\n ", + "Paste is not HTML, so it should not be pretty printed"); + + SimpleTest.finish(); +} + + ]]></script> + + <description style="-moz-user-focus: normal; -moz-user-select: text;"><![CDATA[ + hello + world + ]]></description> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=888839" + target="_blank">Mozilla Bug 888839</a> + </body> +</window> diff --git a/dom/base/test/test_createHTMLDocument.html b/dom/base/test/test_createHTMLDocument.html new file mode 100644 index 0000000000..66b090d189 --- /dev/null +++ b/dom/base/test/test_createHTMLDocument.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<title>createHTMLDocument</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"> +<link rel="help" href="http://www.whatwg.org/html5/#creating-documents"> +<link rel="help" href="http://www.whatwg.org/html5/#document.title"> +<link rel="help" href="http://www.whatwg.org/html5/#dom-document-readystate"> +<body> +<script> +function isElement(element, localName) { + is(element.localName, localName); + is(element.namespaceURI, "http://www.w3.org/1999/xhtml"); + is(element.tagName, localName.toUpperCase()); + is(element.nodeName, localName.toUpperCase()); + is(element.prefix, null); +} +function checkDoc(title, expectedtitle, normalizedtitle) { + var doc = document.implementation.createHTMLDocument(title); + is(doc.readyState, "complete"); + is(doc.compatMode, "CSS1Compat"); + // Opera doesn't have a doctype: DSK-311092 + ok(doc.doctype, "Need a doctype"); + is(doc.doctype.name, "html"); + is(doc.doctype.publicId, ""); + is(doc.doctype.systemId, ""); + isElement(doc.documentElement, "html"); + isElement(doc.documentElement.firstChild, "head"); + if (title !== undefined) { + is(doc.documentElement.firstChild.childNodes.length, 1); + isElement(doc.documentElement.firstChild.firstChild, "title"); + // Doesn't always work out in WebKit. + ok(doc.documentElement.firstChild.firstChild.firstChild, "Need a text node."); + is(doc.documentElement.firstChild.firstChild.firstChild.data, expectedtitle); + } else { + is(doc.documentElement.firstChild.childNodes.length, 0); + } + isElement(doc.documentElement.lastChild, "body"); + is(doc.documentElement.lastChild.childNodes.length, 0); + is(doc.title, normalizedtitle); + doc.body.innerHTML = "foo"; + is(doc.body.innerHTML, "foo", "innerHTML should work in HTML data documents!"); +} +checkDoc("", "", ""); +checkDoc(null, "null", "null"); +checkDoc(undefined, "", ""); +checkDoc("foo bar baz", "foo bar baz", "foo bar baz"); +checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz"); +checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz"); +checkDoc("foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz"); +checkDoc("foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz"); +</script> diff --git a/dom/base/test/test_declare_stylesheet_obsolete.html b/dom/base/test/test_declare_stylesheet_obsolete.html new file mode 100644 index 0000000000..baceea2e97 --- /dev/null +++ b/dom/base/test/test_declare_stylesheet_obsolete.html @@ -0,0 +1,94 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=713564 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 713564</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- Load the variable stylesheet, which changes the color of #content. --> + <link rel="stylesheet" type="text/css" href="variable_style_sheet.sjs"/> + + <script type="application/javascript"> + + function insertLinkToVarSSAndRun(callback) { + var ss = document.createElement("link"); + ss.rel = "stylesheet"; + ss.type = "text/css"; + ss.href = "variable_style_sheet.sjs"; + document.getElementsByTagName("head")[0].appendChild(ss); + ss.addEventListener("load", callback); + } + + /** Test for Bug 713564 **/ + + // Then you link to that sheet, remove the link from the DOM, insert a new link to + // the same url and check that there was no new access, then call our new method, + // insert _another_ <link> to the same url, and check that this time we hit the + // server. + SimpleTest.waitForExplicitFinish(); + + function do_test() { + var var_sheet = document.getElementsByTagName("link")[1]; + var head = document.getElementsByTagName("head")[0]; + var content = document.getElementById("content"); + var var_sheet_url = var_sheet.href; + + var previousBgColor = window.getComputedStyle(content). + getPropertyValue("background-color"); + var_sheet.parentNode.removeChild(var_sheet); + insertLinkToVarSSAndRun(function() { + is(window.getComputedStyle(content).getPropertyValue("background-color"), + previousBgColor, + "Sheet should still be the same."); + + // Obsolete sheet + try { + SpecialPowers.wrap(document).obsoleteSheet(var_sheet_url); + } catch (e) { + ok(false, "obsoleteSheet should not raise an error on valid URL."); + } + insertLinkToVarSSAndRun(function() { + isnot(window.getComputedStyle(content).getPropertyValue("background-color"), + previousBgColor, + "Sheet should change after obsoleted and reinserted."); + SimpleTest.finish(); + }); + }); + // obsoleteSheet should throw with invalid input: + try { + SpecialPowers.wrap(document).obsoleteSheet(""); + ok(false, "obsoleteSheet should throw with empty string."); + } catch (e) { + ok(true, "obsoleteSheet throws with empty string."); + } + try { + SpecialPowers.wrap(document).obsoleteSheet("foo"); + ok(false, "obsoleteSheet should throw with invalid URL."); + } catch (e) { + ok(true, "obsoleteSheet throws with invalid URL."); + } + try { + SpecialPowers.wrap(document).obsoleteSheet("http://www.mozilla.org"); + ok(true, "obsoleteSheet should not throw with valid URL."); + } catch (e) { + ok(false, "obsoleteSheet throws with valid URL."); + } + } + + </script> +</head> +<body onload="do_test();"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=713564">Mozilla Bug 713564</a> +<p id="display"></p> +<div id="content"> + <br> + <br> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_dialogArguments.html b/dom/base/test/test_dialogArguments.html new file mode 100644 index 0000000000..70a091d000 --- /dev/null +++ b/dom/base/test/test_dialogArguments.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test for Bug 1019761</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <meta http-equiv="content-type" content="text/html; charset=utf-8"> +</head> +<body> +<script type="application/javascript"> + +/* + Tests whether Firefox crashes when accessing the dialogArguments property + of a modal window that has been closed. +*/ +SimpleTest.waitForExplicitFinish(); + +function openModal() { + showModalDialog("javascript:opener.winRef = window; \ + window.opener.setTimeout(\'winRef.dialogArguments;\', 0);\ + window.close();"); + + ok(true, "dialogArguments did not cause a crash."); + SimpleTest.finish(); +} + +window.onload = openModal; +</script> +</body> +</html> diff --git a/dom/base/test/test_document.all_iteration.html b/dom/base/test/test_document.all_iteration.html new file mode 100644 index 0000000000..a5140d9df1 --- /dev/null +++ b/dom/base/test/test_document.all_iteration.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for document.all iteration behavior</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> +test(function() { + assert_array_equals([...document.all], document.getElementsByTagName("*")); +}, "document.all should be iterable"); +</script> diff --git a/dom/base/test/test_document.all_unqualified.html b/dom/base/test/test_document.all_unqualified.html new file mode 100644 index 0000000000..763ba9898f --- /dev/null +++ b/dom/base/test/test_document.all_unqualified.html @@ -0,0 +1,35 @@ +<html> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 823283</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=823283">Mozilla Bug 823283</a> +<p id="display"></p> +<div id="content" style="display: none"> +<form id="f" onreset="window.valueOfAll = all; SimpleTest.executeSoon(finishTest); return false;"> +</form> +</div> +<pre id="test"> +<script> +SimpleTest.waitForExplicitFinish(); + +var all = 17; +var valueOfAll = "initial value"; + +function finishTest() +{ + is(valueOfAll, document.all, + "wrong value for |all| in event handler attribute; note that the wrong " + + "value may be |document.forms.f.all| in browsers with an 'all' property " + + "on elements"); + SimpleTest.finish(); +} + +window.addEventListener("load", function() { document.getElementById("f").reset(); }, false); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_document_constructor.html b/dom/base/test/test_document_constructor.html new file mode 100644 index 0000000000..8311200506 --- /dev/null +++ b/dom/base/test/test_document_constructor.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1017932 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1017932</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1017932 **/ + var doc = new Document; + ok(doc instanceof Document, "Should have a document"); + ok(!(doc instanceof XMLDocument), "Should not be an XMLDocument"); + ok(!("load" in doc), "Should not have a load() method"); + is(Object.getPrototypeOf(doc), Document.prototype, + "Should have the right proto"); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1017932">Mozilla Bug 1017932</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_document_importNode_document.html b/dom/base/test/test_document_importNode_document.html new file mode 100644 index 0000000000..e33575e844 --- /dev/null +++ b/dom/base/test/test_document_importNode_document.html @@ -0,0 +1,32 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1177914 +--> +<head> + <title>Test for Bug 1177914</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1177914">Mozilla Bug 1177914</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +var thrownException = false; + +try { + document.importNode(document); +} catch(err) { + thrownException = err; +} + +ok(thrownException !== false, "An exception should've been thrown"); +is(thrownException.name, "NotSupportedError", "A NotSupportedError exception should've been thrown"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_document_register.html b/dom/base/test/test_document_register.html new file mode 100644 index 0000000000..6cf15a52f2 --- /dev/null +++ b/dom/base/test/test_document_register.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<html> + <head> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + </head> + <body onload="startTests()"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=783129" target="_blank">Mozilla Bug 783129</a> + <iframe id="fooframe" src="/"></iframe> + <script type="application/javascript"> + + /** Test for Bug 783129 **/ + SimpleTest.waitForExplicitFinish(); + + function startTests() { + var c = document.getElementById("fooframe").contentDocument.registerElement("x-foo"); + var elem = new c(); + is(elem.tagName, "X-FOO", "Constructor should create an x-foo element."); + + var anotherElem = $("fooframe").contentDocument.createElement("x-foo"); + is(anotherElem.tagName, "X-FOO", "createElement should create an x-foo element."); + SimpleTest.finish(); + } + + </script> + </body> +</html> diff --git a/dom/base/test/test_domcursor.html b/dom/base/test/test_domcursor.html new file mode 100644 index 0000000000..d33581f124 --- /dev/null +++ b/dom/base/test/test_domcursor.html @@ -0,0 +1,140 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for DOMCursor</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.7"> +"use strict"; + +SimpleTest.waitForExplicitFinish(); + +var reqserv = SpecialPowers.getDOMRequestService(); +ok("createRequest" in reqserv, "appears to be a service"); + +var req; +var lastContinue = false; + +var index = 0; + +function next() { + if (index < tests.length) { + ok(true, "Begin test"); + tests[index++](); + } else { + ok(true, "All done"); + SimpleTest.finish(); + } +} + +var tests = [ + function() { + // create a cursor, test its interface and its initial state + req = reqserv.createCursor(window, function() { + if (lastContinue) { + reqserv.fireDone(req); + } else { + reqserv.fireSuccess(req, "next result") + } + }); + ok("result" in req, "cursor has result"); + ok("error" in req, "cursor has error"); + ok("onsuccess" in req, "cursor has onsuccess"); + ok("onerror" in req, "cursor has onerror"); + ok("readyState" in req, "cursor has readyState"); + ok("done" in req, "cursor has finished"); + ok("continue" in req, "cursor has continue"); + ok(!("then" in req), "cursor should not have a then method"); + + is(req.readyState, "pending", "readyState is pending"); + is(req.result, undefined, "result is undefined"); + is(req.onsuccess, null, "onsuccess is null"); + is(req.onerror, null, "onerror is null"); + next(); + }, + function() { + // fire success + req.onsuccess = function(e) { + ok(e, "got success event"); + is(e.type, "success", "correct type during success"); + is(e.target, req, "correct target during success"); + is(req.readyState, "done", "correct readyState after success"); + is(req.error, null, "correct error after success"); + is(req.result, "my result", "correct result after success"); + is(req.done, false, "cursor is not done after continue") + next(); + } + reqserv.fireSuccess(req, "my result"); + }, + function() { + // continue + req.onsuccess = function(e) { + ok(e, "got success event after continue"); + is(e.type, "success", "correct type during continue"); + is(e.target, req, "correct target during continue"); + is(req.readyState, "done", "correct readyState after continue"); + is(req.error, null, "correct error after continue"); + is(req.result, "next result", "correct result after continue"); + is(req.done, false, "cursor is not done after continue") + next(); + } + req.continue(); + }, + function() { + // FireDone + req.onsuccess = function(e) { + ok(e, "got success event after continue"); + is(e.type, "success", "correct type during continue"); + is(e.target, req, "correct target during continue"); + is(req.readyState, "done", "correct readyState after continue"); + is(req.error, null, "correct error after continue"); + is(req.result, undefined, "no result after last continue"); + is(req.done, true, "cursor is done after last continue") + try { + req.continue(); + ok(false, "continue when cursor is done should fail"); + } catch (e) { + ok(true, "continue when cursor is done should fail"); + } + + next(); + } + lastContinue = true; + req.continue(); + }, + function() { + // fire error + req = reqserv.createCursor(window, function(){}); + req.onerror = function(e) { + ok(e, "got success event"); + is(e.type, "error", "correct type during error"); + is(e.target, req, "correct target during error"); + is(req.readyState, "done", "correct readyState after error"); + is(req.error.name, "error msg", "correct error after error"); + is(req.result, undefined, "correct result after error"); + try { + req.continue(); + ok(false, "continue while in an error state should fail"); + } catch (e) { + ok(true, "continue while in an error state should fail"); + } + + next(); + } + reqserv.fireError(req, "error msg"); + } +]; + +next(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_domparser_null_char.html b/dom/base/test/test_domparser_null_char.html new file mode 100644 index 0000000000..2bc19c717c --- /dev/null +++ b/dom/base/test/test_domparser_null_char.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=817469 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 817469</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=817469">Mozilla Bug 817469</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 817469 **/ + var doc = new DOMParser().parseFromString("\x00<div id='myElement'>", "text/html"); + isnot(doc.getElementById("myElement"), null, "Should not stop at null"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_domparsing.html b/dom/base/test/test_domparsing.html new file mode 100644 index 0000000000..b45187d668 --- /dev/null +++ b/dom/base/test/test_domparsing.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset=utf-8> + <title>Test for the DOM Parsing and Serialization Standard</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=816410">Mozilla Bug 816410</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript;version=1.7"> +"use strict"; +/** Test for Bug 816410 **/ + +function throws(fn, type, message) { + try { + fn(); + ok(false, message); + } catch (e) { + if (type) { + is(e.name, type, message); + } else { + ok(true, message); + } + } +} + +let parser = new DOMParser(); +is(typeof parser.parseFromString, "function", "parseFromString should exist"); +is(typeof parser.parseFromBuffer, "undefined", "parseFromBuffer should NOT be visible from unprivileged callers"); +is(typeof parser.parseFromStream, "undefined", "parseFromStream should NOT be visible from unprivileged callers"); +is(typeof parser.init, "undefined", "init should NOT be visible from unprivileged callers"); + +// The three-arguments constructor should not be visible from +// unprivileged callers for interoperability with other browsers. +// But we have no way to do that right now. +try { + new DOMParser(undefined); + new DOMParser(null); + new DOMParser(false); + new DOMParser(0); + new DOMParser(""); + new DOMParser({}); +} catch (e) { + todo(false, "DOMParser constructor should not throw for extra arguments"); +} + +let serializer = new XMLSerializer(); +is(typeof serializer.serializeToString, "function", "serializeToString should exist"); +is(typeof serializer.serializeToStream, "undefined", "serializeToStream should NOT be visible from unprivileged callers"); + +// XMLSerializer constructor should not throw for extra arguments +new XMLSerializer(undefined); +new XMLSerializer(null); +new XMLSerializer(false); +new XMLSerializer(0); +new XMLSerializer(""); +new XMLSerializer({}); + +let tests = [ + {input: "<html></html>", type: "text/html", + expected: '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body></body></html>'}, + {input: "<xml></xml>", type: "text/xml", expected: "<xml/>"}, + {input: "<xml></xml>", type: "application/xml", expected: "<xml/>"}, + {input: "<html></html>", type: "application/xhtml+xml", expected: "<html/>"}, + {input: "<svg></svg>", type: "image/svg+xml", expected: "<svg/>"}, +]; +for (let t of tests) { + is(serializer.serializeToString(parser.parseFromString(t.input, t.type)), t.expected, + "parseFromString test for " + t.type); +} + +throws(function() { + parser.parseFromString("<xml></xml>", "foo/bar"); +}, "TypeError", "parseFromString should throw for the unknown type"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_domrequest.html b/dom/base/test/test_domrequest.html new file mode 100644 index 0000000000..85636ba529 --- /dev/null +++ b/dom/base/test/test_domrequest.html @@ -0,0 +1,229 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for DOMRequest</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.7"> +"use strict"; + +var reqserv = SpecialPowers.getDOMRequestService(); +ok("createRequest" in reqserv, "appears to be a service"); + +function testBasics() { + // create a request + var req = reqserv.createRequest(window); + ok("result" in req, "request has result"); + ok("error" in req, "request has error"); + ok("onsuccess" in req, "request has onsuccess"); + ok("onerror" in req, "request has onerror"); + ok("readyState" in req, "request has readyState"); + ok("then" in req, "request has then"); + + is(req.readyState, "pending", "readyState is pending"); + is(req.result, undefined, "result is undefined"); + is(req.onsuccess, null, "onsuccess is null"); + is(req.onerror, null, "onerror is null"); + + runTest(); +} + +function testSuccess() { + // fire success + var req = reqserv.createRequest(window); + var ev = null; + req.onsuccess = function(e) { + ev = e; + } + var result = null; + var promise = req.then(function(r) { + is(r, "my result", "correct result when resolving the promise"); + result = r; + runTest(); + }, function(e) { + ok(false, "promise should not be rejected"); + runTest(); + }); + ok(promise instanceof Promise, "then() should return a Promise"); + reqserv.fireSuccess(req, "my result"); + ok(ev, "got success event"); + is(ev.type, "success", "correct type during success"); + is(ev.target, req, "correct target during success"); + is(req.readyState, "done", "correct readyState after success"); + is(req.error, null, "correct error after success"); + is(req.result, "my result", "correct result after success"); + is(result, null, "Promise should not be resolved synchronously"); +} + +function testError() { + // fire error + var req = reqserv.createRequest(window); + var ev = null; + req.onerror = function(e) { + ev = e; + } + var error = null; + var promise = req.then(function(r) { + ok(false, "promise should not be resolved"); + runTest(); + }, function(e) { + ok(e instanceof DOMError, "got error rejection"); + ok(e === req.error, "got correct error when rejecting the promise"); + error = e; + runTest(); + }); + ok(promise instanceof Promise, "then() should return a Promise"); + reqserv.fireError(req, "OhMyError"); + ok(ev, "got error event"); + is(ev.type, "error", "correct type during error"); + is(ev.target, req, "correct target during error"); + is(req.readyState, "done", "correct readyState after error"); + is(req.error.name, "OhMyError", "correct error after error"); + is(req.result, undefined, "correct result after error"); + is(error, null, "Promise should not be rejected synchronously"); +} + +function testDetailedError() { + // fire detailed error + var req = reqserv.createRequest(window); + var ev = null; + req.onerror = function(e) { + ev = e; + }; + var error = null; + var promise = req.then(function(r) { + ok(false, "promise should not be resolved"); + runTest(); + }, function(e) { + ok(e instanceof DOMError, "got error rejection"); + ok(e === req.error, "got correct error when rejecting the promise"); + error = e; + runTest(); + }); + ok(promise instanceof Promise, "then() should return a Promise"); + reqserv.fireDetailedError(req, new DOMError("detailedError")); + ok(ev, "got error event"); + is(ev.type, "error", "correct type during error"); + is(ev.target, req, "correct target during error"); + is(req.readyState, "done", "correct readyState after error"); + is(req.error.name, "detailedError", "correct error after error"); + is(req.result, undefined, "correct result after error"); + is(error, null, "Promise should not be rejected synchronously"); +} + +function testThenAfterSuccess() { + // fire success + var req = reqserv.createRequest(window); + var ev = null; + req.onsuccess = function(e) { + ev = e; + } + reqserv.fireSuccess(req, "my result"); + ok(ev, "got success event"); + is(ev.type, "success", "correct type during success"); + is(ev.target, req, "correct target during success"); + is(req.readyState, "done", "correct readyState after success"); + is(req.error, null, "correct error after success"); + is(req.result, "my result", "correct result after success"); + var result = null; + var promise = req.then(function(r) { + is(r, "my result", "correct result when resolving the promise"); + result = r; + runTest(); + }, function(e) { + ok(false, "promise should not be rejected"); + runTest(); + }); + ok(promise instanceof Promise, "then() should return a Promise"); + is(result, null, "Promise should not be resolved synchronously"); +} + +function testThenAfterError() { + // fire error + var req = reqserv.createRequest(window); + var ev = null; + req.onerror = function(e) { + ev = e; + } + reqserv.fireError(req, "OhMyError"); + ok(ev, "got error event"); + is(ev.type, "error", "correct type during error"); + is(ev.target, req, "correct target during error"); + is(req.readyState, "done", "correct readyState after error"); + is(req.error.name, "OhMyError", "correct error after error"); + is(req.result, undefined, "correct result after error"); + var error = null; + var promise = req.then(function(r) { + ok(false, "promise should not be resolved"); + runTest(); + }, function(e) { + ok(e instanceof DOMError, "got error rejection"); + ok(e === req.error, "got correct error when rejecting the promise"); + error = e; + runTest(); + }); + ok(promise instanceof Promise, "then() should return a Promise"); + is(error, null, "Promise should not be rejected synchronously"); +} + +function testDetailedError() { + // fire detailed error + var req = reqserv.createRequest(window); + var ev = null; + req.onerror = function(e) { + ev = e; + }; + var error = null; + var promise = req.then(function(r) { + ok(false, "promise should not be resolved"); + runTest(); + }, function(e) { + ok(e instanceof DOMError, "got error rejection"); + ok(e === req.error, "got correct error when rejecting the promise"); + error = e; + runTest(); + }); + ok(promise instanceof Promise, "then() should return a Promise"); + reqserv.fireDetailedError(req, new DOMError("detailedError")); + ok(ev, "got error event"); + is(ev.type, "error", "correct type during error"); + is(ev.target, req, "correct target during error"); + is(req.readyState, "done", "correct readyState after error"); + is(req.error.name, "detailedError", "correct error after error"); + is(req.result, undefined, "correct result after error"); + is(error, null, "Promise should not be rejected synchronously"); +} + +var tests = [ + testBasics, + testSuccess, + testError, + testDetailedError, + testThenAfterSuccess, + testThenAfterError, +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +SimpleTest.waitForExplicitFinish(); +runTest(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_domrequesthelper.xul b/dom/base/test/test_domrequesthelper.xul new file mode 100644 index 0000000000..4365e4f0e9 --- /dev/null +++ b/dom/base/test/test_domrequesthelper.xul @@ -0,0 +1,552 @@ +<?xml version="1.0"?> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<?xml-stylesheet href="chrome://global/skin" type="text/css"?> +<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?> + +<window title="DOMRequestHelper Test" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + onload="start();"> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <script type="application/javascript"> + <![CDATA[ + const Cc = Components.classes; + const Cu = Components.utils; + const Ci = Components.interfaces; + Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); + let obs = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); + let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]. + getService(Ci.nsIMessageBroadcaster); + + function DummyHelperSubclass() { + this.onuninit = null; + } + DummyHelperSubclass.prototype = { + __proto__: DOMRequestIpcHelper.prototype, + uninit: function() { + if (typeof this.onuninit === "function") { + this.onuninit(); + } + this.onuninit = null; + } + }; + + var dummy = new DummyHelperSubclass(); + var isDOMRequestHelperDestroyed = false; + + /** + * Init & destroy. + */ + function initDOMRequestHelperTest(aMessages) { + // If we haven't initialized the DOMRequestHelper object, its private + // properties will be undefined, but once destroyDOMRequestHelper is + // called, they're set to null. + var expectedPrivatePropertyValues = + isDOMRequestHelperDestroyed ? null : undefined; + + is(dummy._requests, expectedPrivatePropertyValues, "Request is expected"); + is(dummy._messages, undefined, "Messages is undefined"); + is(dummy._window, expectedPrivatePropertyValues, "Window is expected"); + + dummy.initDOMRequestHelper(window, aMessages); + + ok(dummy._window, "Window exists"); + is(dummy._window, window, "Correct window"); + if (aMessages) { + is(typeof dummy._listeners, "object", "Listeners is an object"); + } + } + + function destroyDOMRequestHelperTest() { + dummy.destroyDOMRequestHelper(); + isDOMRequestHelperDestroyed = true; + + is(dummy._requests, null, "Request is null"); + is(dummy._messages, undefined, "Messages is undefined"); + is(dummy._window, null, "Window is null"); + } + + /** + * Message listeners. + */ + function checkMessageListeners(aExpectedListeners, aCount) { + info("Checking message listeners\n" + "Expected listeners " + + JSON.stringify(aExpectedListeners) + " \nExpected count " + aCount); + let count = 0; + Object.keys(dummy._listeners).forEach(function(name) { + count++; + is(aExpectedListeners[name].weakRef, dummy._listeners[name].weakRef, + "Message found " + name + " - Same weakRef"); + is(aExpectedListeners[name].count, dummy._listeners[name].count, + "Message found " + name + " - Same count"); + }); + is(aCount, count, "Correct number of listeners"); + } + + function addMessageListenersTest(aMessages, aExpectedListeners, aCount) { + dummy.addMessageListeners(aMessages); + info(JSON.stringify(dummy._listeners)); + checkMessageListeners(aExpectedListeners, aCount); + } + + function removeMessageListenersTest(aMessages, aExpectedListeners, aCount) { + dummy.removeMessageListeners(aMessages); + checkMessageListeners(aExpectedListeners, aCount); + } + + /** + * Utility function to test window destruction behavior. In general this + * function does the following: + * + * 1) Create a new iframe + * 2) Create a new DOMRequestHelper + * 3) initDOMRequestHelper(), optionally with weak or strong listeners + * 4) Optionally force a garbage collection to reap weak references + * 5) Destroy the iframe triggering an inner-window-destroyed event + * 6) Callback with a boolean indicating if DOMRequestHelper.uninit() was + * called. + * + * Example usage: + * + * checkWindowDestruction({ messages: ["foo"], gc: true }, + * function(uninitCalled) { + * // expect uninitCalled === false since GC with only weak refs + * }); + */ + const TOPIC = "inner-window-destroyed"; + function checkWindowDestruction(aOptions, aCallback) { + aOptions = aOptions || {}; + aOptions.messages = aOptions.messages || []; + aOptions.gc = !!aOptions.gc; + + if (typeof aCallback !== "function") { + aCallback = function() { }; + } + + let uninitCalled = false; + + // Use a secondary observer so we know when to expect the uninit(). We + // can then reasonably expect uninitCalled to be set properly on the + // next tick. + let observer = { + observe: function(aSubject, aTopic, aData) { + if (aTopic !== TOPIC) { + return; + } + obs.removeObserver(observer, TOPIC); + setTimeout(function() { + aCallback(uninitCalled); + }); + } + }; + + let frame = document.createElement("iframe"); + frame.onload = function() { + obs.addObserver(observer, TOPIC, false); + // Create dummy DOMRequestHelper specific to checkWindowDestruction() + let cwdDummy = new DummyHelperSubclass(); + cwdDummy.onuninit = function() { + uninitCalled = true; + + if (!aOptions.messages || !aOptions.messages.length) { + return; + } + + // If all message listeners are removed, cwdDummy.receiveMessage + // should never be called. + ppmm.broadcastAsyncMessage(aOptions.messages[0].name); + }; + + // Test if we still receive messages from ppmm. + cwdDummy.receiveMessage = function(aMessage) { + ok(false, "cwdDummy.receiveMessage should NOT be called: " + aMessage.name); + }; + + cwdDummy.initDOMRequestHelper(frame.contentWindow, aOptions.messages); + // Make sure to clear our strong ref here so that we can test our + // weak reference listeners and observer. + cwdDummy = null; + if (aOptions.gc) { + Cu.schedulePreciseGC(function() { + SpecialPowers.DOMWindowUtils.cycleCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + SpecialPowers.DOMWindowUtils.garbageCollect(); + document.documentElement.removeChild(frame); + }); + return; + } + document.documentElement.removeChild(frame); + }; + document.documentElement.appendChild(frame); + } + + /** + * Test steps. + */ + var tests = [ + function() { + info("== InitDOMRequestHelper no messages"); + initDOMRequestHelperTest(null); + next(); + }, + function() { + info("== DestroyDOMRequestHelper"); + destroyDOMRequestHelperTest(); + next(); + }, + function() { + info("== InitDOMRequestHelper empty array"); + initDOMRequestHelperTest([]); + checkMessageListeners({}, 0); + next(); + }, + function() { + info("== DestroyDOMRequestHelper"); + destroyDOMRequestHelperTest(); + next(); + }, + function() { + info("== InitDOMRequestHelper with strings array"); + initDOMRequestHelperTest(["name1", "nameN"]); + checkMessageListeners({"name1": {weakRef: false, count: 1}, + "nameN": {weakRef: false, count: 1}}, 2); + next(); + }, + function() { + info("== DestroyDOMRequestHelper"); + destroyDOMRequestHelperTest(); + next(); + }, + function() { + info("== InitDOMRequestHelper with objects array"); + initDOMRequestHelperTest([{ + name: "name1", + weakRef: false + }, { + name: "nameN", + weakRef: true + }]); + checkMessageListeners({ + "name1": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 2); + next(); + }, + function() { + info("== AddMessageListeners empty array"); + addMessageListenersTest([], { + "name1": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 2); + next(); + }, + function() { + info("== AddMessageListeners null"); + addMessageListenersTest(null, { + "name1": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 2); + next(); + }, + function() { + info("== AddMessageListeners new listener, string only"); + addMessageListenersTest("name2", { + "name1": {weakRef: false, count: 1}, + "name2": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 3); + next(); + }, + function() { + info("== AddMessageListeners new listeners, strings array"); + addMessageListenersTest(["name3", "name4"], { + "name1": {weakRef: false, count: 1}, + "name2": {weakRef: false, count: 1}, + "name3": {weakRef: false, count: 1}, + "name4": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 5); + next(); + }, + function() { + info("== AddMessageListeners new listeners, objects array"); + addMessageListenersTest([{ + name: "name5", + weakRef: true + }, { + name: "name6", + weakRef: false + }], { + "name1": {weakRef: false, count: 1}, + "name2": {weakRef: false, count: 1}, + "name3": {weakRef: false, count: 1}, + "name4": {weakRef: false, count: 1}, + "name5": {weakRef: true, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 7); + next(); + }, + function() { + info("== RemoveMessageListeners, null"); + removeMessageListenersTest(null, { + "name1": {weakRef: false, count: 1}, + "name2": {weakRef: false, count: 1}, + "name3": {weakRef: false, count: 1}, + "name4": {weakRef: false, count: 1}, + "name5": {weakRef: true, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 7); + next(); + }, + function() { + info("== RemoveMessageListeners, one message"); + removeMessageListenersTest("name1", { + "name2": {weakRef: false, count: 1}, + "name3": {weakRef: false, count: 1}, + "name4": {weakRef: false, count: 1}, + "name5": {weakRef: true, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 6); + next(); + }, + function() { + info("== RemoveMessageListeners, array of messages"); + removeMessageListenersTest(["name2", "name3"], { + "name4": {weakRef: false, count: 1}, + "name5": {weakRef: true, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 4); + next(); + }, + function() { + info("== RemoveMessageListeners, unknown message"); + removeMessageListenersTest("unknown", { + "name4": {weakRef: false, count: 1}, + "name5": {weakRef: true, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 4); + next(); + }, + function() { + try { + info("== AddMessageListeners, same message, same kind"); + addMessageListenersTest("name4", { + "name4": {weakRef: false, count: 2}, + "name5": {weakRef: true, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 4); + next(); + } catch (ex) { + ok(false, "Unexpected exception " + ex); + } + }, + function() { + info("== AddMessageListeners, same message, different kind"); + try { + addMessageListenersTest({name: "name4", weakRef: true}, { + "name4": {weakRef: false, count: 2}, + "name5": {weakRef: true, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 4); + ok(false, "Should have thrown an exception"); + } catch (ex) { + ok(true, "Expected exception"); + next(); + } + }, + function() { + info("== RemoveMessageListeners, message with two listeners"); + try { + removeMessageListenersTest(["name4", "name5"], { + "name4": {weakRef: false, count: 1}, + "name6": {weakRef: false, count: 1}, + "nameN": {weakRef: true, count: 1} + }, 3); + next(); + } catch (ex) { + ok(false, "Unexpected exception " + ex); + } + }, + function() { + info("== Test createRequest()"); + ok(DOMRequest, "DOMRequest object exists"); + var req = dummy.createRequest(); + ok(req instanceof DOMRequest, "Returned a DOMRequest"); + next(); + }, + function() { + info("== Test getRequestId(), removeRequest() and getRequest()"); + var req = dummy.createRequest(); + var id = dummy.getRequestId(req); + is(typeof id, "string", "id is a string"); + var req_ = dummy.getRequest(id); + is(req, req_, "Got correct request"); + dummy.removeRequest(id); + req = dummy.getRequest(id); + is(req, undefined, "No request"); + next(); + }, + function() { + info("== Test createPromise()"); + ok(Promise, "Promise object exists"); + var promise = dummy.createPromise(function(resolve, reject) { + resolve(true); + }); + ok(promise instanceof Promise, "Returned a Promise"); + promise.then(next); + }, + function() { + info("== Test createPromiseWithId()"); + var _resolverId; + var promise = dummy.createPromiseWithId(function(resolverId) { + _resolverId = resolverId; + }); + var resolver = dummy.getPromiseResolver(_resolverId); + ok(promise instanceof Promise, "Returned a Promise"); + ok(typeof _resolverId === "string", "resolverId is a string"); + ok(resolver != null, "resolverId is a valid id"); + next(); + }, + function() { + info("== Test getResolver()"); + var id; + var resolver; + var promise = dummy.createPromise(function(resolve, reject) { + var r = { resolve: resolve, reject: reject }; + id = dummy.getPromiseResolverId(r); + resolver = r; + ok(typeof id === "string", "id is a string"); + r.resolve(true); + }).then(function(unused) { + var r = dummy.getPromiseResolver(id); + ok(resolver === r, "Get succeeded"); + next(); + }); + }, + function() { + info("== Test removeResolver"); + var id; + var promise = dummy.createPromise(function(resolve, reject) { + var r = { resolve: resolve, reject: reject }; + id = dummy.getPromiseResolverId(r); + ok(typeof id === "string", "id is a string"); + + var resolver = dummy.getPromiseResolver(id); + info("Got resolver " + JSON.stringify(resolver)); + ok(resolver === r, "Resolver get succeeded"); + + r.resolve(true); + }).then(function(unused) { + dummy.removePromiseResolver(id); + var resolver = dummy.getPromiseResolver(id); + ok(resolver === undefined, "removeResolver: get failed"); + next(); + }); + }, + function() { + info("== Test takeResolver"); + var id; + var resolver; + var promise = dummy.createPromise(function(resolve, reject) { + var r = { resolve: resolve, reject: reject }; + id = dummy.getPromiseResolverId(r); + resolver = r; + ok(typeof id === "string", "id is a string"); + + var gotR = dummy.getPromiseResolver(id); + ok(gotR === r, "resolver get succeeded"); + + r.resolve(true); + }).then(function(unused) { + var r = dummy.takePromiseResolver(id); + ok(resolver === r, "take should succeed"); + + r = dummy.getPromiseResolver(id); + ok(r === undefined, "takeResolver: get failed"); + next(); + }); + }, + function() { + info("== Test window destroyed without messages and without GC"); + checkWindowDestruction({ gc: false }, function(uninitCalled) { + ok(uninitCalled, "uninit() should have been called"); + next(); + }); + }, + function() { + info("== Test window destroyed without messages and with GC"); + checkWindowDestruction({ gc: true }, function(uninitCalled) { + ok(!uninitCalled, "uninit() should NOT have been called"); + next(); + }); + }, + function() { + info("== Test window destroyed with weak messages and without GC"); + checkWindowDestruction({ messages: [{ name: "foo", weakRef: true }], + gc: false }, function(uninitCalled) { + ok(uninitCalled, "uninit() should have been called"); + next(); + }); + }, + function() { + info("== Test window destroyed with weak messages and with GC"); + checkWindowDestruction({ messages: [{ name: "foo", weakRef: true }], + gc: true }, function(uninitCalled) { + ok(!uninitCalled, "uninit() should NOT have been called"); + next(); + }); + }, + function() { + info("== Test window destroyed with strong messages and without GC"); + checkWindowDestruction({ messages: [{ name: "foo", weakRef: false }], + gc: false }, function(uninitCalled) { + ok(uninitCalled, "uninit() should have been called"); + next(); + }); + }, + function() { + info("== Test window destroyed with strong messages and with GC"); + checkWindowDestruction({ messages: [{ name: "foo", weakRef: false }], + gc: true }, function(uninitCalled) { + ok(uninitCalled, "uninit() should have been called"); + next(); + }); + } + ]; + + function next() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); + } + + function start() { + SimpleTest.waitForExplicitFinish(); + next(); + } + ]]> + </script> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <p id="display"></p> + <div id="content" style="display: none"></div> + <pre id="test"></pre> + </body> +</window> diff --git a/dom/base/test/test_domwindowutils.html b/dom/base/test/test_domwindowutils.html new file mode 100644 index 0000000000..218f510ffa --- /dev/null +++ b/dom/base/test/test_domwindowutils.html @@ -0,0 +1,85 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Test for DOMWindowUtils</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<div id="content" style="display: none"></div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +var utils = SpecialPowers.getDOMWindowUtils(window); +function test_sendMouseEventDefaults() { + var x = 1, y = 2, button = 1, clickCount = 2, + modifiers = SpecialPowers.Ci.nsIDOMNSEvent.SHIFT_MASK; + + window.addEventListener("mousedown", function listener(evt) { + window.removeEventListener("mousedown", listener); + // Mandatory args + // coordinates may change slightly due to rounding + ok((evt.clientX <= x+2) && (evt.clientX >= x-2), "check x"); + ok((evt.clientY <= y+2) && (evt.clientY >= y-2), "check y"); + is(evt.button, button, "check button"); + is(evt.detail, clickCount, "check click count"); + is(evt.getModifierState("Shift"), true, "check modifiers"); + + // Default value for optionals + is(evt.mozPressure, 0, "check pressure"); + is(evt.mozInputSource, SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE, "check input source"); + is(evt.isSynthesized, undefined, "check isSynthesized is undefined in content"); + is(SpecialPowers.wrap(evt).isSynthesized, true, "check isSynthesized is true from chrome"); + SimpleTest.executeSoon(next); + }); + + // Only pass mandatory arguments and check default values + utils.sendMouseEvent("mousedown", x, y, button, clickCount, modifiers); +} + +function test_sendMouseEventOptionals() { + var x = 1, y = 2, button = 1, clickCount = 3, + modifiers = SpecialPowers.Ci.nsIDOMNSEvent.SHIFT_MASK, + pressure = 0.5, + source = SpecialPowers.Ci.nsIDOMMouseEvent.MOZ_SOURCE_KEYBOARD; + + window.addEventListener("mouseup", function listener(evt) { + window.removeEventListener("mouseup", listener); + is(evt.mozInputSource, source, "explicit input source is valid"); + is(SpecialPowers.wrap(evt).isSynthesized, false, "we can dispatch event that don't look synthesized"); + SimpleTest.executeSoon(next); + }); + + // Check explicit value for optional args + utils.sendMouseEvent("mouseup", x, y, button, clickCount, modifiers, + false, pressure, source, false); +} + +var tests = [ + test_sendMouseEventDefaults, + test_sendMouseEventOptionals +]; + +function next() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +function start() { + SimpleTest.waitForExplicitFinish(); + SimpleTest.executeSoon(next); +} + +window.addEventListener("load", start); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_e4x_for_each.html b/dom/base/test/test_e4x_for_each.html new file mode 100644 index 0000000000..3d1ffa57a7 --- /dev/null +++ b/dom/base/test/test_e4x_for_each.html @@ -0,0 +1,55 @@ +<!DOCTYPE html> +<html> +<head><meta charset=utf-8> + <title>Test for E4X "for each" syntax</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="template" style="display: none"> +function runTest(i) { + var t = tests[i]; + count++; + try { + Function("for each (var a in []) {}"); + ok(t.enabled, "JavaScript" + ("version" in t ? " " + t.version : "") + " supports for-each-in"); + } catch (e) { + ok(!t.enabled, "JavaScript" + ("version" in t ? " " + t.version : "") + " does NOT support for-each-in"); + } +} +</div> +<pre id="test"> +<script class="testbody"> + +var tests = [ + {enabled: false}, + {version: "1.0", enabled: false}, + {version: "1.1", enabled: false}, + {version: "1.2", enabled: false}, + {version: "1.3", enabled: false}, + {version: "1.4", enabled: false}, + {version: "1.5", enabled: false}, + {version: "1.6", enabled: true}, + {version: "1.7", enabled: true}, + {version: "1.8", enabled: true}, +]; + +var count = 0; +for (var i = 0; i < tests.length; i++) { + var t = tests[i]; + var script = document.createElement("script"); + script.type = "application/javascript" + ("version" in t ? ";version=" + t.version : ""); + script.textContent = document.getElementById("template").textContent + "\n" + "runTest(" + i + ");"; + document.body.appendChild(script); +} +script = document.createElement("script"); +script.textContent = 'is(count, tests.length, "runTest() call count");'; +document.body.appendChild(script); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_element.matches.html b/dom/base/test/test_element.matches.html new file mode 100644 index 0000000000..9b360b16fb --- /dev/null +++ b/dom/base/test/test_element.matches.html @@ -0,0 +1,28 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=886308 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 886308</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 886308 **/ + ok(document.head.matches("head"), "head should match 'head'"); + ok(document.querySelector("link").matches("html *"), "link is a descendant of 'html'"); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=886308">Mozilla Bug 886308</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_elementTraversal.html b/dom/base/test/test_elementTraversal.html new file mode 100644 index 0000000000..3ff4db0e75 --- /dev/null +++ b/dom/base/test/test_elementTraversal.html @@ -0,0 +1,111 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=444722 +--> +<head> + <title>Test for the ElementTraversal spec</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="http://dev.w3.org/2006/webapi/ElementTraversal/publish/ElementTraversal.html">ElementTraversal</a> +<div id="content" style="display: none"> +<span>span</span><div>div</div> +<!--comment goes here--> +<p id="p1">p1</p> +text here +<p id="p2">p2</p> +<span>a<span>b</span>c<span>d</span>e</span> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var c = document.getElementById('content'); +var cc = c.children; + +var contents = ["span", "div", "p1", "p2", "abcde"]; +function testContent() { + for(i = 0, e = c.firstElementChild; e; e = e.nextElementSibling, i++) { + is(e.textContent, contents[i], "wrong element contents"); + is(e, c.children[i], "wrong element"); + is(e, c.children.item(i), "wrong element"); + } + is(i, contents.length, "wrong number of element siblings"); + is(i, c.childElementCount, "wrong number of child elements"); + is(i, c.children.length, "wrong number of child elements"); + + // Nuke all elements to retest the child list. + c.innerHTML = c.innerHTML; + + for(i--, e = c.lastElementChild; e; e = e.previousElementSibling, i--) { + is(e.textContent, contents[i], "g element contents"); + is(e, c.children[i], "wrong element"); + is(e, c.children.item(i), "wrong element"); + } + is(i, -1, "wrong number of element siblings"); +} + +testContent(); + +is(cc.length, 5, "wrong number of child elements"); +is(c.childElementCount, 5, "wrong number of child elements"); + +var p1 = document.getElementById('p1'); +var p2 = document.getElementById('p2'); +is(p1.nextElementSibling, p2, "wrong sibling"); +is(p2.previousElementSibling, p1, "wrong sibling"); + +u = document.createElement('u'); +u.textContent = 'u'; +c.insertBefore(u, p2); +is(cc.length, 6, "wrong number of child elements"); +is(c.childElementCount, 6, "wrong number of child elements"); +is(p1.nextElementSibling, u, "wrong sibling"); +is(p2.previousElementSibling, u, "wrong sibling"); + +contents.splice(3, 0, "u"); +testContent(); + +var p1 = document.getElementById('p1'); +var p2 = document.getElementById('p2'); +c.removeChild(p1); +c.removeChild(p2); +is(cc.length, 4, "wrong number of child elements"); +is(c.childElementCount, 4, "wrong number of child elements"); + +contents.splice(2, 1); +contents.splice(3, 1); +testContent(); + +tw = document.createTreeWalker(document.documentElement, + NodeFilter.SHOW_ELEMENT, + null); +e = document.documentElement; + +elemsTested = 0; +done = false; +while(!done) { + is(tw.currentNode, e, "wrong element:" + tw.currentNode + " != " + e); + elemsTested++; + + if(tw.firstChild()) { + e = e.firstElementChild; + } + else { + while (!tw.nextSibling()) { + if (!tw.parentNode()) { + done = true; + break; + } + e = e.parentNode; + } + e = e.nextElementSibling; + } +} +is(elemsTested, document.getElementsByTagName("*").length, + "wrong number of elements"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_element_closest.html b/dom/base/test/test_element_closest.html new file mode 100644 index 0000000000..adede6b8b2 --- /dev/null +++ b/dom/base/test/test_element_closest.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1055533 +--> +<head> + <title>Test for Bug 1055533</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body id="body"> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1055533">Mozilla Bug 1055533</a> + <div id="test8" class="div3"> + <div id="test7" class="div2"> + <div id="test6" class="div1"> + <form id="test10" class="form2"></form> + <form id="test5" class="form1" name="form-a"> + <input id="test1" class="input1" required> + <fieldset class="fieldset2" id="test2"> + <select id="test3" class="select1" required> + <option default id="test4" value="">Test4</option> + <option selected id="test11">Test11</option> + <option id="test12">Test12</option> + <option id="test13">Test13</option> + </select> + <input id="test9" type="text" required> + </fieldset> + </form> + </div> + </div> + </div> +<script class="testbody" type="text/javascript"> + test("select" , "test12", "test3"); + test("fieldset" , "test13", "test2"); + test("div" , "test13", "test6"); + test("body" , "test3" , "body"); + + test("[default]" , "test4" , "test4"); + test("[selected]" , "test4" , ""); + test("[selected]" , "test11", "test11"); + test('[name="form-a"]' , "test12", "test5"); + test('form[name="form-a"]' , "test13", "test5"); + test("input[required]" , "test9" , "test9"); + test("select[required]" , "test9" , ""); + + test("div:not(.div1)" , "test13", "test7"); + test("div.div3" , "test6" , "test8"); + test("div#test7" , "test1" , "test7"); + + test(".div3 > .div2" , "test12", "test7"); + test(".div3 > .div1" , "test12", ""); + test("form > input[required]" , "test9" , ""); + test("fieldset > select[required]", "test12", "test3"); + + test("input + fieldset" , "test6" , ""); + test("form + form" , "test3" , "test5"); + test("form + form" , "test5" , "test5"); + + test(":empty" , "test10", "test10"); + test(":last-child" , "test11", "test2"); + test(":first-child" , "test12", "test3"); + test(":invalid" , "test11", "test2"); + + test(":scope" , "test4", "test4"); + test("select > :scope" , "test4", "test4"); + test("div > :scope" , "test4", ""); + try { + test(":has(> :scope)" , "test4", "test3"); + } catch(e) { + todo(false, ":has(> :scope) [:has is not implemented yet]"); + } +function test(aSelector, aElementId, aTargetId) { + var el = document.getElementById(aElementId).closest(aSelector); + if (el === null) { + is("", aTargetId, aSelector); + } else { + is(el.id, aTargetId, aSelector); + } +} +</script> +</body> +</html> diff --git a/dom/base/test/test_encodeToStringWithMaxLength.html b/dom/base/test/test_encodeToStringWithMaxLength.html new file mode 100644 index 0000000000..587aff77b5 --- /dev/null +++ b/dom/base/test/test_encodeToStringWithMaxLength.html @@ -0,0 +1,64 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=995321 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 995321 - encodeToStringWithMaxLength</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + function getEncoder() { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + const Cc = SpecialPowers.Cc; + + // Create a plaintext encoder without flags. + var encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/plain"] + .createInstance(de); + encoder.init(document, "text/plain", 0); + return encoder; + } + + function testPlaintextSerializerWithMaxLength() { + var string = getEncoder().encodeToString(); + + var shorterString = getEncoder().encodeToStringWithMaxLength(1); + ok(shorterString.length < 1 + 72, + "test length is in the expected range after limiting the length to 1"); + ok(string.startsWith(shorterString.trimRight()), + "the shorter string has the expected content"); + + shorterString = getEncoder().encodeToStringWithMaxLength(300); + ok(shorterString.length < 300 + 72, + "test length is in the expected range after limiting the length to 300"); + ok(string.startsWith(shorterString.trimRight()), + "the shorter string has the expected content"); + + is(getEncoder().encodeToStringWithMaxLength(0), string, + "limiting the length to 0 should be ignored"); + + is(getEncoder().encodeToStringWithMaxLength(10000), string, + "limiting the length to a huge value should return the whole page"); + + SimpleTest.finish(); + } + + addLoadEvent(testPlaintextSerializerWithMaxLength); + SimpleTest.waitForExplicitFinish(); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=995321">Mozilla Bug 995321</a> +<p id="display"></p> +<div id="content" style="display: none"> +The <em>Mozilla</em> project is a global community of <strong>people</strong> who believe that openness, innovation, and opportunity are key to the continued health of the Internet. We have worked together since 1998 to ensure that the Internet is developed in a way that benefits everyone. We are best known for creating the Mozilla Firefox web browser. + +The Mozilla project uses a community-based approach to create world-class open source software and to develop new types of collaborative activities. We create communities of people involved in making the Internet experience better for all of us. + +As a result of these efforts, we have distilled a set of principles that we believe are critical for the Internet to continue to benefit the public good as well as commercial aspects of life. We set out these principles below. +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_error.html b/dom/base/test/test_error.html new file mode 100644 index 0000000000..c06d82526c --- /dev/null +++ b/dom/base/test/test_error.html @@ -0,0 +1,44 @@ + +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=869013 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 869013</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=869013">Mozilla Bug 869013</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe name="x" id="x"></iframe> + <iframe name="y" id="y"></iframe> +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + /** Test for Bug 869013 **/ + var a = new DOMError('name'); + ok(a, "DOMError created with name: " + a.name + " and message: " + a.message); + is(a.name, "name", "Name is correct"); + is(a.message, "", "Message is correct"); + + a = new DOMError('name1', 'message1'); + ok(a, "DOMError created with name: " + a.name + " and message: " + a.message); + is(a.name, "name1", "Name is correct"); + is(a.message, "message1", "Message is correct"); + + try { + a = new DOMError(); + ok(false, "DOMError should throw if there are not params"); + } catch(e) { + ok(true, "DOMError should throw if there are not params"); + } + + </script> +</body> +</html> diff --git a/dom/base/test/test_explicit_user_agent.html b/dom/base/test/test_explicit_user_agent.html new file mode 100644 index 0000000000..9cac4c9338 --- /dev/null +++ b/dom/base/test/test_explicit_user_agent.html @@ -0,0 +1,65 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for XMLHttpRequest.GetResponseHeader(foo) byte-inflates the output</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <meta charset="utf-8"> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.7"> + "use strict"; + + add_task(function*() { + yield new Promise((r) => { + let xhr = new XMLHttpRequest(); + xhr.open('GET', 'file_explicit_user_agent.sjs', true); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + is(xhr.getResponseHeader("Result-User-Agent"), navigator.userAgent, + "The resulting user-agent is the navigator's UA"); + r(); + } + } + xhr.send(null); + }); + + yield new Promise((r) => { + let xhr = new XMLHttpRequest(); + xhr.open('GET', 'file_explicit_user_agent.sjs', true); + xhr.setRequestHeader('User-Agent', 'custom-ua/10.0'); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + is(xhr.getResponseHeader("Result-User-Agent"), 'custom-ua/10.0', + "The resulting user-agent is the custom UA"); + r(); + } + } + xhr.send(null); + }); + + var response = yield fetch('file_explicit_user_agent.sjs', { + method: 'GET' + }); + is(response.headers.get("Result-User-Agent"), navigator.userAgent, + "The user-agent is the navigator's UA"); + + var headers = new Headers(); + headers.set('User-Agent', 'custom-ua/20.0'); + var response2 = yield fetch('file_explicit_user_agent.sjs', { + method: 'GET', + headers: headers, + }); + is(response2.headers.get("Result-User-Agent"), 'custom-ua/20.0', + "The user-agent is the custom UA"); + }); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_file_from_blob.html b/dom/base/test/test_file_from_blob.html new file mode 100644 index 0000000000..d596d1dca9 --- /dev/null +++ b/dom/base/test/test_file_from_blob.html @@ -0,0 +1,111 @@ +<!doctype html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=819900 +--> + <head> +<title>Test for crash caused by unloading and reloading srcdoc iframes</title> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=819900">Mozilla Bug 819900</a> + +<pre id="test"> +<script> + + var b = new Blob(['1234567890']); + ok(b, 'Blob created'); + is(b.size, 10, 'Blob has the right size'); + + var status = false; + try { + f = new File(b); + } catch(e) { + status = true; + } + ok(status, "File throws if the second argument is missing"); + + status = false; + try { + f = new File(42, 'foobar.txt'); + } catch(e) { + status = true; + } + ok(status, "File throws if the argument is not an array"); + + status = false; + try { + f = new File({}, 'foobar.txt'); + } catch(e) { + status = true; + } + ok(status, "File throws if the argument is not an array"); + + status = false; + try { + f = new File("hello world", 'foobar.txt'); + } catch(e) { + status = true; + } + ok(status, "File throws if the argument is not an array"); + + f = new File(['1234567890'], ''); + ok(f, 'File created'); + is(f.size, 10, 'File has the right size'); + is(f.name, ''); + is(f.type, ''); + + f = new File(['1234567890'], 42); + ok(f, 'File created'); + is(f.size, 10, 'File has the right size'); + is(f.name, '42'); + is(f.type, ''); + + f = new File(['1234567890'], 'text.txt'); + ok(f, 'File created'); + is(f.size, 10, 'File has the right size'); + is(f.name, 'text.txt'); + is(f.type, ''); + + f = new File(['1234567890'], 'text.txt', { type: 'plain/text' }); + ok(f, 'File created'); + is(f.size, 10, 'File has the right size'); + is(f.name, 'text.txt'); + is(f.type, 'plain/text'); + + f = new File([b], 'text.txt'); + ok(f, 'File created'); + is(f.name, 'text.txt'); + is(f.type, ''); + is(f.size, b.size); + + f = new File([b], 'test.txt', { type: 'plain/text' }); + ok(f, 'File created'); + is(f.name, 'test.txt'); + is(f.type, 'plain/text'); + is(f.size, b.size); + + f = new File([b, b], 'test.txt', { type: 'plain/text' }); + ok(f, 'File created'); + is(f.name, 'test.txt'); + is(f.type, 'plain/text'); + is(f.size, b.size * 2); + + var f2 = new File([f, f], 'test.txt', { type: 'plain/text' }); + ok(f2, 'File created'); + is(f2.name, 'test.txt'); + is(f2.type, 'plain/text'); + is(f2.size, f.size * 2); + + var f2 = new File([f, f], 'test.txt', b); + ok(f2, 'File created'); + is(f2.name, 'test.txt'); + is(f2.type, b.type); + is(f2.size, f.size * 2); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_file_negative_date.html b/dom/base/test/test_file_negative_date.html new file mode 100644 index 0000000000..ebfa9bd0d9 --- /dev/null +++ b/dom/base/test/test_file_negative_date.html @@ -0,0 +1,39 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1158437 +--> +<head> + <title>Test for negative date in File (Bug 1158437)</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="fileutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1158437">Mozilla Bug 1158437</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript;version=1.7"> +"use strict"; + +var blob = new Blob(['hello world']); +var f1 = new File([blob], 'f1.txt', { lastModified: 0 }); +var f2 = new File([blob], 'f2.txt', { lastModified: -1 }); +var f3 = new File([blob], 'f3.txt', { lastModified: -1000 }); + +is(f1.lastModified, 0, "lastModified == 0 is supported"); +ok(f1.lastModifiedDate.toString(), (new Date(0)).toString(), "Correct f1.lastModifiedDate value"); +is(f2.lastModified, -1, "lastModified == -1 is supported"); +ok(f2.lastModifiedDate.toString(), (new Date(-1)).toString(), "Correct f2.lastModifiedDate value"); +is(f3.lastModified, -1000, "lastModified == -1000 is supported"); +ok(f3.lastModifiedDate.toString(), (new Date(-1000)).toString(), "Correct f3.lastModifiedDate value"); + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_fileapi.html b/dom/base/test/test_fileapi.html new file mode 100644 index 0000000000..fc33c7ae6c --- /dev/null +++ b/dom/base/test/test_fileapi.html @@ -0,0 +1,479 @@ +<!DOCTYPE HTML> +<html> +<head> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=414796 +--> + <title>Test for Bug 414796</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=414796">Mozilla Bug 414796</a> +<p id="display"> +</p> +<div id="content" style="display: none"> +</div> + +<pre id="test"> +<script class="testbody" type="text/javascript;version=1.7"> + +// File constructors should not work from non-chrome code +try { + var file = File("/etc/passwd"); + ok(false, "Did not throw on unprivileged attempt to construct a File"); +} catch (e) { + ok(true, "Threw on an unprivileged attempt to construct a File"); +} + +const minFileSize = 20000; +var testRanCounter = 0; +var expectedTestCount = 0; +var testSetupFinished = false; +SimpleTest.waitForExplicitFinish(); + +is(FileReader.EMPTY, 0, "correct EMPTY value"); +is(FileReader.LOADING, 1, "correct LOADING value"); +is(FileReader.DONE, 2, "correct DONE value"); + +// Create strings containing data we'll test with. We'll want long +// strings to ensure they span multiple buffers while loading +var testTextData = "asd b\tlah\u1234w\u00a0r"; +while (testTextData.length < minFileSize) { + testTextData = testTextData + testTextData; +} + +var testASCIIData = "abcdef 123456\n"; +while (testASCIIData.length < minFileSize) { + testASCIIData = testASCIIData + testASCIIData; +} + +var testBinaryData = ""; +for (var i = 0; i < 256; i++) { + testBinaryData += String.fromCharCode(i); +} +while (testBinaryData.length < minFileSize) { + testBinaryData = testBinaryData + testBinaryData; +} + +var dataurldata0 = testBinaryData.substr(0, testBinaryData.length - + testBinaryData.length % 3); +var dataurldata1 = testBinaryData.substr(0, testBinaryData.length - 2 - + testBinaryData.length % 3); +var dataurldata2 = testBinaryData.substr(0, testBinaryData.length - 1 - + testBinaryData.length % 3); + + +//Set up files for testing +var openerURL = SimpleTest.getTestFileURL("fileapi_chromeScript.js"); +var opener = SpecialPowers.loadChromeScript(openerURL); +opener.addMessageListener("files.opened", onFilesOpened); +opener.sendAsyncMessage("files.open", [ + testASCIIData, + testBinaryData, + null, + convertToUTF8(testTextData), + convertToUTF16(testTextData), + "", + dataurldata0, + dataurldata1, + dataurldata2, +]); + +function onFilesOpened(message) { + let [ + asciiFile, + binaryFile, + nonExistingFile, + utf8TextFile, + utf16TextFile, + emptyFile, + dataUrlFile0, + dataUrlFile1, + dataUrlFile2, + ] = message; + + // Test that plain reading works and fires events as expected, both + // for text and binary reading + + var onloadHasRunText = false; + var onloadStartHasRunText = false; + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, "correct initial text readyState"); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "plain reading"); + r.addEventListener("load", function() { onloadHasRunText = true }, false); + r.addEventListener("loadstart", function() { onloadStartHasRunText = true }, false); + r.readAsText(asciiFile); + is(r.readyState, FileReader.LOADING, "correct loading text readyState"); + is(onloadHasRunText, false, "text loading must be async"); + is(onloadStartHasRunText, true, "text loadstart should fire sync"); + expectedTestCount++; + + var onloadHasRunBinary = false; + var onloadStartHasRunBinary = false; + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, "correct initial binary readyState"); + r.addEventListener("load", function() { onloadHasRunBinary = true }, false); + r.addEventListener("loadstart", function() { onloadStartHasRunBinary = true }, false); + r.readAsBinaryString(binaryFile); + r.onload = getLoadHandler(testBinaryData, testBinaryData.length, "binary reading"); + is(r.readyState, FileReader.LOADING, "correct loading binary readyState"); + is(onloadHasRunBinary, false, "binary loading must be async"); + is(onloadStartHasRunBinary, true, "binary loadstart should fire sync"); + expectedTestCount++; + + var onloadHasRunArrayBuffer = false; + var onloadStartHasRunArrayBuffer = false; + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, "correct initial arrayBuffer readyState"); + r.addEventListener("load", function() { onloadHasRunArrayBuffer = true }, false); + r.addEventListener("loadstart", function() { onloadStartHasRunArrayBuffer = true }, false); + r.readAsArrayBuffer(binaryFile); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, testBinaryData.length, "array buffer reading"); + is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState"); + is(onloadHasRunArrayBuffer, false, "arrayBuffer loading must be async"); + is(onloadStartHasRunArrayBuffer, true, "arrayBuffer loadstart should fire sync"); + expectedTestCount++; + + // Test a variety of encodings, and make sure they work properly + r = new FileReader(); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "no encoding reading"); + r.readAsText(asciiFile, ""); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "iso8859 reading"); + r.readAsText(asciiFile, "iso-8859-1"); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler(testTextData, + convertToUTF8(testTextData).length, + "utf8 reading"); + r.readAsText(utf8TextFile, "utf8"); + expectedTestCount++; + + r = new FileReader(); + r.readAsText(utf16TextFile, "utf-16"); + r.onload = getLoadHandler(testTextData, + convertToUTF16(testTextData).length, + "utf16 reading"); + expectedTestCount++; + + // Test get result without reading + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, + "readyState in test reader get result without reading"); + is(r.error, null, + "no error in test reader get result without reading"); + is(r.result, null, + "result in test reader get result without reading"); + + // Test loading an empty file works (and doesn't crash!) + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty no encoding reading"); + r.readAsText(emptyFile, ""); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty utf8 reading"); + r.readAsText(emptyFile, "utf8"); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty utf16 reading"); + r.readAsText(emptyFile, "utf-16"); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty binary string reading"); + r.readAsBinaryString(emptyFile); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandlerForArrayBuffer("", 0, "empty array buffer reading"); + r.readAsArrayBuffer(emptyFile); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading"); + r.readAsDataURL(emptyFile); + expectedTestCount++; + + // Test reusing a FileReader to read multiple times + r = new FileReader(); + r.onload = getLoadHandler(testASCIIData, + testASCIIData.length, + "to-be-reused reading text") + var makeAnotherReadListener = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener, false); + r.onload = getLoadHandler(testASCIIData, + testASCIIData.length, + "reused reading text"); + r.readAsText(asciiFile); + }; + r.addEventListener("load", makeAnotherReadListener, false); + r.readAsText(asciiFile); + expectedTestCount += 2; + + r = new FileReader(); + r.onload = getLoadHandler(testBinaryData, + testBinaryData.length, + "to-be-reused reading binary") + var makeAnotherReadListener2 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener2, false); + r.onload = getLoadHandler(testBinaryData, + testBinaryData.length, + "reused reading binary"); + r.readAsBinaryString(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener2, false); + r.readAsBinaryString(binaryFile); + expectedTestCount += 2; + + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(testBinaryData), + testBinaryData.length, + "to-be-reused reading data url") + var makeAnotherReadListener3 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener3, false); + r.onload = getLoadHandler(convertToDataURL(testBinaryData), + testBinaryData.length, + "reused reading data url"); + r.readAsDataURL(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener3, false); + r.readAsDataURL(binaryFile); + expectedTestCount += 2; + + r = new FileReader(); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, + testBinaryData.length, + "to-be-reused reading arrayBuffer") + var makeAnotherReadListener4 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener4, false); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, + testBinaryData.length, + "reused reading arrayBuffer"); + r.readAsArrayBuffer(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener4, false); + r.readAsArrayBuffer(binaryFile); + expectedTestCount += 2; + + // Test first reading as ArrayBuffer then read as something else + // (BinaryString) and doesn't crash + r = new FileReader(); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, + testBinaryData.length, + "to-be-reused reading arrayBuffer") + var makeAnotherReadListener5 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener5, false); + r.onload = getLoadHandler(testBinaryData, + testBinaryData.length, + "reused reading binary string"); + r.readAsBinaryString(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener5, false); + r.readAsArrayBuffer(binaryFile); + expectedTestCount += 2; + + //Test data-URI encoding on differing file sizes + is(dataurldata0.length % 3, 0, "Want to test data with length % 3 == 0"); + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(dataurldata0), + dataurldata0.length, + "dataurl reading, %3 = 0"); + r.readAsDataURL(dataUrlFile0); + expectedTestCount++; + + is(dataurldata1.length % 3, 1, "Want to test data with length % 3 == 1"); + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(dataurldata1), + dataurldata1.length, + "dataurl reading, %3 = 1"); + r.readAsDataURL(dataUrlFile1); + expectedTestCount++; + + is(dataurldata2.length % 3, 2, "Want to test data with length % 3 == 2"); + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(dataurldata2), + dataurldata2.length, + "dataurl reading, %3 = 2"); + r.readAsDataURL(dataUrlFile2), + expectedTestCount++; + + + // Test abort() + var abortHasRun = false; + var loadEndHasRun = false; + r = new FileReader(); + r.onabort = function (event) { + is(abortHasRun, false, "abort should only fire once"); + is(loadEndHasRun, false, "loadend shouldn't have fired yet"); + abortHasRun = true; + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); + is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); + is(event.target.result, null, "file data should be null on aborted reads"); + } + r.onloadend = function (event) { + is(abortHasRun, true, "abort should fire before loadend"); + is(loadEndHasRun, false, "loadend should only fire once"); + loadEndHasRun = true; + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); + is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); + is(event.target.result, null, "file data should be null on aborted reads"); + } + r.onload = function() { ok(false, "load should not fire for aborted reads") }; + r.onerror = function() { ok(false, "error should not fire for aborted reads") }; + r.onprogress = function() { ok(false, "progress should not fire for aborted reads") }; + var abortThrew = false; + try { + r.abort(); + } catch(e) { + abortThrew = true; + } + is(abortThrew, true, "abort() must throw if not loading"); + is(abortHasRun, false, "abort() is a no-op unless loading"); + r.readAsText(asciiFile); + r.abort(); + is(abortHasRun, true, "abort should fire sync"); + is(loadEndHasRun, true, "loadend should fire sync"); + + // Test calling readAsX to cause abort() + var reuseAbortHasRun = false; + r = new FileReader(); + r.onabort = function (event) { + is(reuseAbortHasRun, false, "abort should only fire once"); + reuseAbortHasRun = true; + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); + is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); + is(event.target.result, null, "file data should be null on aborted reads"); + } + r.onload = function() { ok(false, "load should not fire for aborted reads") }; + var abortThrew = false; + try { + r.abort(); + } catch(e) { + abortThrew = true; + } + is(abortThrew, true, "abort() must throw if not loading"); + is(reuseAbortHasRun, false, "abort() is a no-op unless loading"); + r.readAsText(asciiFile); + r.readAsText(asciiFile); + is(reuseAbortHasRun, true, "abort should fire sync"); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "reuse-as-abort reading"); + expectedTestCount++; + + + // Test reading from nonexistent files + r = new FileReader(); + var didThrow = false; + r.onerror = function (event) { + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onerror"); + is(event.target.error.name, "NotFoundError", "error set to NotFoundError for nonexistent files"); + is(event.target.result, null, "file data should be null on aborted reads"); + testHasRun(); + }; + r.onload = function (event) { + is(false, "nonexistent file shouldn't load! (FIXME: bug 1122788)"); + testHasRun(); + }; + try { + r.readAsDataURL(nonExistingFile); + expectedTestCount++; + } catch(ex) { + didThrow = true; + } + // Once this test passes, we should test that onerror gets called and + // that the FileReader object is in the right state during that call. + is(didThrow, false, "shouldn't throw when opening nonexistent file, should fire error instead"); + + + function getLoadHandler(expectedResult, expectedLength, testName) { + return function (event) { + is(event.target.readyState, FileReader.DONE, + "readyState in test " + testName); + is(event.target.error, null, + "no error in test " + testName); + is(event.target.result, expectedResult, + "result in test " + testName); + is(event.lengthComputable, true, + "lengthComputable in test " + testName); + is(event.loaded, expectedLength, + "loaded in test " + testName); + is(event.total, expectedLength, + "total in test " + testName); + testHasRun(); + } + } + + function getLoadHandlerForArrayBuffer(expectedResult, expectedLength, testName) { + return function (event) { + is(event.target.readyState, FileReader.DONE, + "readyState in test " + testName); + is(event.target.error, null, + "no error in test " + testName); + is(event.lengthComputable, true, + "lengthComputable in test " + testName); + is(event.loaded, expectedLength, + "loaded in test " + testName); + is(event.total, expectedLength, + "total in test " + testName); + is(event.target.result.byteLength, expectedLength, + "array buffer size in test " + testName); + var u8v = new Uint8Array(event.target.result); + is(String.fromCharCode.apply(String, u8v), expectedResult, + "array buffer contents in test " + testName); + u8v = null; + SpecialPowers.gc(); + is(event.target.result.byteLength, expectedLength, + "array buffer size after gc in test " + testName); + u8v = new Uint8Array(event.target.result); + is(String.fromCharCode.apply(String, u8v), expectedResult, + "array buffer contents after gc in test " + testName); + testHasRun(); + } + } + + function testHasRun() { + //alert(testRanCounter); + ++testRanCounter; + if (testRanCounter == expectedTestCount) { + is(testSetupFinished, true, "test setup should have finished; check for exceptions"); + is(onloadHasRunText, true, "onload text should have fired by now"); + is(onloadHasRunBinary, true, "onload binary should have fired by now"); + opener.destroy(); + SimpleTest.finish(); + } + } + + testSetupFinished = true; +} + +function convertToUTF16(s) { + res = ""; + for (var i = 0; i < s.length; ++i) { + c = s.charCodeAt(i); + res += String.fromCharCode(c & 255, c >>> 8); + } + return res; +} + +function convertToUTF8(s) { + return unescape(encodeURIComponent(s)); +} + +function convertToDataURL(s) { + return "data:application/octet-stream;base64," + btoa(s); +} + +</script> +</pre> +</body> </html> diff --git a/dom/base/test/test_fileapi_slice.html b/dom/base/test/test_fileapi_slice.html new file mode 100644 index 0000000000..efe4aa2592 --- /dev/null +++ b/dom/base/test/test_fileapi_slice.html @@ -0,0 +1,167 @@ +<!DOCTYPE HTML> +<html> +<head> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=575946 +--> + <title>Test for Bug 575946</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="fileutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=575946">Mozilla Bug 575946</a> +<p id="display"> + <canvas id=canvas width=1100 height=1100 hidden moz-opaque></canvas> + <canvas id=testcanvas hidden moz-opaque></canvas> + <input id="fileList" type="file"></input> +</p> +<div id="content" style="display: none"> +</div> + +<pre id="test"> +<script class="testbody" type="text/javascript"> +var fileNum = 1; +SimpleTest.waitForExplicitFinish(); + +// Create files containing data we'll test with. We'll want long +// strings to ensure they span multiple buffers while loading + +// Create a decent-sized image +cx = $("canvas").getContext('2d'); +var s = cx.canvas.width; +var grad = cx.createLinearGradient(0, 0, s-1, s-1); +for (i = 0; i < 0.95; i += .1) { + grad.addColorStop(i, "white"); + grad.addColorStop(i + .05, "black"); +} +grad.addColorStop(1, "white"); +cx.fillStyle = grad; +cx.fillRect(0, 0, s-1, s-1); +cx.fillStyle = "rgba(200, 0, 0, 0.9)"; +cx.fillRect(.1 * s, .1 * s, .7 * s, .7 * s); +cx.strokeStyle = "rgba(0, 0, 130, 0.5)"; +cx.lineWidth = .14 * s; +cx.beginPath(); +cx.arc(.6 * s, .6 * s, .3 * s, 0, Math.PI*2, true); +cx.stroke(); +cx.closePath(); +cx.fillStyle = "rgb(0, 255, 0)"; +cx.beginPath(); +cx.arc(.1 * s, .8 * s, .1 * s, 0, Math.PI*2, true); +cx.fill(); +cx.closePath(); + + +function imageLoadHandler(event) { + var origcanvas = $("canvas"); + var testcanvas = $("testcanvas"); + var image = event.target; + is(image.naturalWidth, origcanvas.width, "width correct"); + is(image.naturalHeight, origcanvas.height, "height correct"); + + testcanvas.width = origcanvas.width; + testcanvas.height = origcanvas.height; + testcanvas.getContext("2d").drawImage(image, 0, 0); + // Do not use |is(testcanvas.toDataURL("image/png"), origcanvas.toDataURL("image/png"), "...");| that results in a _very_ long line. + var origDataURL = origcanvas.toDataURL("image/png"); + var testDataURL = testcanvas.toDataURL("image/png"); + is(testDataURL.length, origDataURL.length, + "Length of correct image data"); + ok(testDataURL == origDataURL, + "Content of correct image data"); + + testHasRun(); +} + +var fileData = + atob(cx.canvas.toDataURL("image/png").substring("data:text/png;base64,".length + 1)); +var size = fileData.length; +var testBinaryData = ""; + +// This might fail if we dramatically improve the png encoder. If that happens +// please increase the complexity or size of the image generated above to ensure +// that we're testing with files that are large enough. +ok(size > 65536, "test data sufficiently large"); + +SpecialPowers.createFiles([{name: "basicTestFile", data: fileData}], + basicTest); + +function basicTest(files) { + var fileFile = files[0]; + + // Test that basic properties work + var memFile = cx.canvas.mozGetAsFile("image/png"); + testSlice(memFile, size, "image/png", fileData, "memFile"); + testSlice(fileFile, size, "", fileData, "fileFile"); + + // Try loading directly from slice into an image + for (var i = 0; i < 256; i++) { + testBinaryData += String.fromCharCode(i); + } + while (testBinaryData.length < 20000) { + testBinaryData += testBinaryData; + } + + // image in the middle + SpecialPowers.createFiles([{name: "middleTestFile", + data: testBinaryData + fileData + testBinaryData}], + imageMiddleTest); +} + +function imageMiddleTest(files) { + var imgfile = files[0]; + is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)"); + var img = new Image; + img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size)); + img.onload = imageLoadHandler; + expectedTestCount++; + + // image at start + SpecialPowers.createFiles([{name: "startTestFile", + data: fileData + testBinaryData}], + imageStartTest); +} + +function imageStartTest(files) { + var imgfile = files[0]; + is(imgfile.size, size + testBinaryData.length, "correct file size (start)"); + var img = new Image; + img.src = URL.createObjectURL(imgfile.slice(0, size)); + img.onload = imageLoadHandler; + expectedTestCount++; + + // image at end + SpecialPowers.createFiles([{name: "endTestFile", + data: testBinaryData + fileData}], + imageEndTest); +} + +function imageEndTest(files) { + var imgfile = files[0]; + is(imgfile.size, size + testBinaryData.length, "correct file size (end)"); + var img = new Image; + img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size)); + img.onload = imageLoadHandler; + expectedTestCount++; + + // image past end + SpecialPowers.createFiles([{name: "pastEndTestFile", + data: testBinaryData + fileData}], + imagePastEndTest); +} + +function imagePastEndTest(files) { + var imgfile = files[0]; + is(imgfile.size, size + testBinaryData.length, "correct file size (past end)"); + var img = new Image; + img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size + 1000)); + img.onload = imageLoadHandler; + expectedTestCount++; +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_getAttribute_after_createAttribute.html b/dom/base/test/test_getAttribute_after_createAttribute.html new file mode 100644 index 0000000000..5e2f4ec306 --- /dev/null +++ b/dom/base/test/test_getAttribute_after_createAttribute.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for ...</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> +test(function() { + var div = document.createElement("div"); + var attr = document.createAttribute("FOO"); + attr.value = "bar"; + div.setAttributeNode(attr); + assert_equals(div.getAttribute("FOO"), "bar"); +}, "getAttribute should be able to get an attribute created via createAttribute"); +</script> diff --git a/dom/base/test/test_getElementById.html b/dom/base/test/test_getElementById.html new file mode 100644 index 0000000000..b0c2b01dbf --- /dev/null +++ b/dom/base/test/test_getElementById.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=933193 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 933193</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=933193">Mozilla Bug 933193</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + /** Test for Bug 933193 **/ + var kid = document.createElement("span"); + kid.id = "test"; + var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + svg.appendChild(kid); + is(svg.getElementById("test"), kid, + "Should find the right node when not in the DOM"); + + var newKid = document.createElement("span"); + newKid.id = "test"; + var newKidParent = document.createElement("span"); + newKidParent.appendChild(newKid); + svg.insertBefore(newKidParent, kid); + is(svg.getElementById("test"), newKid, + "Should find the first right node when not in the DOM"); + newKid.remove(); + is(svg.getElementById("test"), kid, + "Should find the right node again when not in the DOM"); + + document.body.appendChild(svg); + is(svg.getElementById("test"), kid, + "Should find the right node when in the DOM"); + + is(document.getElementById("test").localName, "pre", + "document.getElementById should find the first element in the " + + "document with that id"); + + var frag = document.createDocumentFragment(); + is(frag.getElementById("test"), null, "Shouldn't find what does not exist"); + frag.appendChild(kid); + is(frag.getElementById("test"), kid, + "Should find the right node in the document fragment"); + is(svg.getElementById("test"), null, + "Shouldn't find the kid since it's gone now"); + </script> +</body> +</html> diff --git a/dom/base/test/test_getTranslationNodes.html b/dom/base/test/test_getTranslationNodes.html new file mode 100644 index 0000000000..e19a0cea71 --- /dev/null +++ b/dom/base/test/test_getTranslationNodes.html @@ -0,0 +1,227 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for nsIDOMWindowUtils.getTranslationNodes</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<script type="application/javascript"> + var utils = SpecialPowers.wrap(window). + QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor). + getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); + + + function testTranslationRoot(rootNode) { + var translationNodes = utils.getTranslationNodes(rootNode); + + var expectedResult = rootNode.getAttribute("expected"); + var expectedLength = expectedResult.split(" ").length; + + is(translationNodes.length, expectedLength, + "Correct number of translation nodes for testcase " + rootNode.id); + + var resultList = []; + for (var i = 0; i < translationNodes.length; i++) { + var node = translationNodes.item(i).localName; + if (translationNodes.isTranslationRootAtIndex(i)) { + node += "[root]" + } + resultList.push(node); + } + + is(resultList.length, translationNodes.length, + "Correct number of translation nodes for testcase " + rootNode.id); + + is(resultList.join(" "), expectedResult, + "Correct list of translation nodes for testcase " + rootNode.id); + } + + function runTest() { + isnot(utils, null, "nsIDOMWindowUtils"); + + var testcases = document.querySelectorAll("div[expected]"); + for (var testcase of testcases) { + testTranslationRoot(testcase); + } + + var testiframe = document.getElementById("testiframe"); + var iframediv = testiframe.contentDocument.querySelector("div"); + try { + var foo = utils.getTranslationNodes(iframediv); + ok(false, "Cannot use a node from a different document"); + } catch (e) { + is(e.name, "WrongDocumentError", "Cannot use a node from a different document"); + } + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); +</script> + +<!-- Test that an inline element inside a root is not a root --> +<div id="testcase1" + expected="div[root] span"> + <div> + lorem ipsum <span>dolor</span> sit amet + </div> +</div> + +<!-- Test that a usually inline element becomes a root if it is + displayed as a block --> +<div id="testcase2" + expected="div[root] span[root]"> + <div> + lorem ipsum <span style="display: block;">dolor</span> sit amet + </div> +</div> + +<!-- Test that the content-less <div> is ignored and only the + <p> with content is returned --> +<div id="testcase3" + expected="p[root]"> + <div> + <p>lorem ipsum</p> + </div> +</div> + +<!-- Test that an inline element which the parent is not a root + becomes a root --> +<div id="testcase4" + expected="span[root]"> + <div> + <span>lorem ipsum</span> + </div> +</div> + +<!-- Test siblings --> +<div id="testcase5" + expected="li[root] li[root]"> + <ul> + <li>lorem</li> + <li>ipsum</li> + </ul> +</div> + +<!-- Test <ul> with content outside li --> +<div id="testcase6" + expected="ul[root] li[root] li[root]"> + <ul>Lorem + <li>lorem</li> + <li>ipsum</li> + </ul> +</div> + +<!-- Test inline siblings --> +<div id="testcase7" + expected="ul[root] li li"> + <ul>Lorem + <li style="display: inline">lorem</li> + <li style="display: inline">ipsum</li> + </ul> +</div> + +<!-- Test inline siblings becoming roots --> +<div id="testcase8" + expected="li[root] li[root]"> + <ul> + <li style="display: inline">lorem</li> + <li style="display: inline">ipsum</li> + </ul> +</div> + +<!-- Test that nodes with only punctuation, whitespace + or numbers are ignored --> +<div id="testcase9" + expected="li[root] li[root]"> + <ul> + <li>lorem</li> + <li>ipsum</li> + <li>-.,;'/!@#$%^*()</li> + <li>0123456789</li> + <li> + </li> + </ul> +</div> + +<!-- Test paragraphs --> +<div id="testcase10" + expected="p[root] a b p[root] a b"> + <p>Lorem ipsum <a href="a.htm">dolor</a> sit <b>amet</b>, consetetur</p> + <p>Lorem ipsum <a href="a.htm">dolor</a> sit <b>amet</b>, consetetur</p> +</div> + +<!-- Test that a display:none element is not ignored --> +<div id="testcase11" + expected="p[root] a b"> + <p>Lorem ipsum <a href="a.htm">dolor</a> sit <b style="display:none">amet</b>, consetetur</p> +</div> + +<!-- Test that deep nesting does not cause useless content to be returned --> +<div id="testcase12" + expected="p[root]"> + <div> + <div> + <div> + <p>Lorem ipsum</p> + </div> + </div> + </div> +</div> + +<!-- Test that deep nesting does not cause useless content to be returned --> +<div id="testcase13" + expected="div[root] p[root]"> + <div>Lorem ipsum + <div> + <div> + <p>Lorem ipsum</p> + </div> + </div> + </div> +</div> + +<!-- Test that non-html elements and elements that usually have non-translatable + content are ignored --> +<div id="testcase14" + expected="div[root]"> + <div> + Lorem Ipsum + <noscript>Lorem Ipsum</noscript> + <style>.dummyClass { color: blue; }</style> + <script> /* script tag */ </script> + <code> code </code> + <iframe id="testiframe" + src="data:text/html,<div>Lorem ipsum</div>"> + </iframe> + <svg>lorem</svg> + <math>ipsum</math> + </div> +</div> + +<!-- Test that nesting of inline elements won't produce roots as long as + the parents are in the list of translation nodes --> +<div id="testcase15" + expected="p[root] a b span em"> + <p>Lorem <a>ipsum <b>dolor <span>sit</span> amet</b></a>, <em>consetetur</em></p> +</div> + +<!-- Test that comment nodes are not considered for translation --> +<div id="testcase16" + expected="p[root] p[root]"> + <p>Lorem ipsum</p> + <div> <!-- Comment --> </div> + <p>Lorem ipsum</p> +</div> + +<!-- Test that comment nodes are not considered for translation --> +<div id="testcase17" + expected="p[root]"> + <div> + <!-- Comment --> + <p>Lorem Ipsum</p> + </div> +</div> +</body> +</html> diff --git a/dom/base/test/test_getTranslationNodes_limit.html b/dom/base/test/test_getTranslationNodes_limit.html new file mode 100644 index 0000000000..8a815f49fb --- /dev/null +++ b/dom/base/test/test_getTranslationNodes_limit.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for nsIDOMWindowUtils.getTranslationNodes</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<script type="application/javascript"> + var utils = SpecialPowers.wrap(window). + QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor). + getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); + + function runTest() { + isnot(utils, null, "nsIDOMWindowUtils"); + + for (var i = 0; i < 16000; i++) { + var text = document.createTextNode("a"); + var node = document.createElement("b"); + node.appendChild(text); + document.body.appendChild(node); + } + + var translationRoots = utils.getTranslationNodes(document.body); + is (translationRoots.length, 15000, "Translation nodes were limited to 15000 nodes."); + + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); +</script> +</body> +</html> diff --git a/dom/base/test/test_gsp-qualified.html b/dom/base/test/test_gsp-qualified.html new file mode 100644 index 0000000000..3d670b92d1 --- /dev/null +++ b/dom/base/test/test_gsp-qualified.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=799875 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 799875</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=799875">Mozilla Bug 799875</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe src="data:text/html,<div id='test2'>"></iframe> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 799875 **/ +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(function() { + is(window.test, document.getElementById("test"), + "Global scope polluter should map ids even when qualified") + isnot(document.getElementById("test"), null, + "Should have element"); + is(window[0].test2, window[0].document.getElementById("test2"), + "Global scope polluter should map ids across globals"); + isnot(window[0].document.getElementById("test2"), null, + "Should have element in subframe"); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_gsp-quirks.html b/dom/base/test/test_gsp-quirks.html new file mode 100644 index 0000000000..a315fe03e2 --- /dev/null +++ b/dom/base/test/test_gsp-quirks.html @@ -0,0 +1,27 @@ +<!-- Purposefully in quirks mode --> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=622491 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 622491</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622491">Mozilla Bug 622491</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 622491 **/ +is(test, document.getElementById("test"), "Global scope polluter should map ids") + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_gsp-standards.html b/dom/base/test/test_gsp-standards.html new file mode 100644 index 0000000000..d5349829a5 --- /dev/null +++ b/dom/base/test/test_gsp-standards.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=622491 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 622491</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622491">Mozilla Bug 622491</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 622491 **/ +is(test, document.getElementById("test"), "Global scope polluter should map ids") + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_history_document_open.html b/dom/base/test/test_history_document_open.html new file mode 100644 index 0000000000..ae4f46b948 --- /dev/null +++ b/dom/base/test/test_history_document_open.html @@ -0,0 +1,37 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=943418 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 943418</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 943418 **/ + SimpleTest.waitForExplicitFinish(); + + function continueTest(f) { + // Make sure we're the entry script so errors get reported here + setTimeout(finishTest, 0, f); + } + + function finishTest(f) { + f(); + ok(true, "Got here"); + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=943418">Mozilla Bug 943418</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe src="data:text/html,<script>function f() { history.length; } window.onload = function() { var f = window.f; document.open(); document.close(); parent.continueTest(f); }</script>" </script> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_history_state_null.html b/dom/base/test/test_history_state_null.html new file mode 100644 index 0000000000..6eeaf52cf0 --- /dev/null +++ b/dom/base/test/test_history_state_null.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=949471 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 949471</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + /** Test for Bug 949471 **/ + is(history.state, null, "history.state should be null by default"); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=949471">Mozilla Bug 949471</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_html_colors_quirks.html b/dom/base/test/test_html_colors_quirks.html new file mode 100644 index 0000000000..68c8620dbb --- /dev/null +++ b/dom/base/test/test_html_colors_quirks.html @@ -0,0 +1,711 @@ +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=121738 +--> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 121738</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=121738">Mozilla Bug 121738</a> +<table id="table0"></table> +<table id="table1"></table> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 121738 **/ + +String.prototype.toAsciiLowerCase = function () { + var output = ""; + for (var i = 0, len = this.length; i < len; ++i) { + if (this.charCodeAt(i) >= 0x41 && this.charCodeAt(i) <= 0x5A) { + output += String.fromCharCode(this.charCodeAt(i) + 0x20) + } else { + output += this.charAt(i); + } + } + return output; +} + +var tests = [ +"#135", +" #135", +"#135 ", +" #135 ", +"# 135", +"# 135", +"#123456", +" #123456", +"#123456 ", +" #123456 ", +"# 123456", +"# 123456", +"aliceblue", +"ALICEBLUE", +"alıceblue", +"alİceblue", +" aliceblue", +"aliceblue ", +" aliceblue ", +"antiquewhite", +"aqua", +"aquamarine", +"azure", +"beige", +"bisque", +"black", +"blanchedalmond", +"blue", +"blueviolet", +"brown", +"burlywood", +"cadetblue", +"chartreuse", +"chocolate", +"coral", +"cornflowerblue", +"cornsilk", +"crimson", +"cyan", +"darkblue", +"darkcyan", +"darkgoldenrod", +"darkgray", +"darkgreen", +"darkgrey", +"darkkhaki", +"darkmagenta", +"darkolivegreen", +"darkorange", +"darkorchid", +"darkred", +"darksalmon", +"darkseagreen", +"darkslateblue", +"darkslategray", +"darkslategrey", +"darkturquoise", +"darkviolet", +"deeppink", +"deepskyblue", +"dimgray", +"dimgrey", +"dodgerblue", +"firebrick", +"floralwhite", +"forestgreen", +"fuchsia", +"gainsboro", +"ghostwhite", +"gold", +"goldenrod", +"gray", +"green", +"greenyellow", +"grey", +"honeydew", +"hotpink", +"indianred", +"indigo", +"ivory", +"khaki", +"lavender", +"lavenderblush", +"lawngreen", +"lemonchiffon", +"lightblue", +"lightcoral", +"lightcyan", +"lightgoldenrodyellow", +"lightgray", +"lightgreen", +"lightgrey", +"lightpink", +"lightsalmon", +"lightseagreen", +"lightskyblue", +"lightslategray", +"lightslategrey", +"lightsteelblue", +"lightyellow", +"lime", +"limegreen", +"linen", +"magenta", +"maroon", +"mediumaquamarine", +"mediumblue", +"mediumorchid", +"mediumpurple", +"mediumseagreen", +"mediumslateblue", +"mediumspringgreen", +"mediumturquoise", +"mediumvioletred", +"midnightblue", +"mintcream", +"mistyrose", +"moccasin", +"navajowhite", +"navy", +"oldlace", +"olive", +"olivedrab", +"orange", +"orangered", +"orchid", +"palegoldenrod", +"palegreen", +"paleturquoise", +"palevioletred", +"papayawhip", +"peachpuff", +"peru", +"pink", +"plum", +"powderblue", +"purple", +"red", +"rosybrown", +"royalblue", +"saddlebrown", +"salmon", +"sandybrown", +"seagreen", +"seashell", +"sienna", +"silver", +"skyblue", +"slateblue", +"slategray", +"slategrey", +"snow", +"springgreen", +"steelblue", +"tan", +"teal", +"thistle", +"tomato", +"turquoise", +"violet", +"wheat", +"white", +"whitesmoke", +"yellow", +"yellowgreen", +"transparent", +"TRANSPARENT", +"", +"inherit", +"INHERIT", +"KQ@m?-ldxNK{zH+(FL_owz>YNH^]", +"aj9c)r+J&3)0E,- Lzv6K6nT@6?I}BY^\\g", +"Cf}qJN|3D>m:^[7B*fhu>lC[B3\"T_-F", +"h<s1pMd-8H[,\\caWH1oW3%M", +"z{y]VZj)%)ZV<OTbO9\\Nbc|YL}4BI<DlUBk$EV`EbN}x/@SDN0(", +"PSX2Ol8@", +"d+gYXKUM'&D'S]o<9T\\:hj_i!|l!)e6R4Bo)-(965rlK\"K01C68pgkJ] fx?kjT.O&sY4", +"[4\"tk)a/v17?0W!F`AyI[='2~;:DF6I>_<O$ he213u", +"F|r9T&N69MWq3Jrj6", +"dYR7}n&:Rq[J", +"M;Z]r@(R([6aT`<sN?uO'2Kb~3U\\\\tQUDxLN1f/D(,Q0w|K;,t`,tQ~[W/c!uQg)d|:D\\U33!DK&d*C`Zc'U#", +"kV)DKUb~h{SQCM;T*g2!Rj?>Sl=jY;3W9M{Fliu!=>tDY]5", +"y>X\\kKN|~=J+7Pqp|%9R!nZ,@>mUW9<o;|02LV<fxihsBSKVaTdcae", +"Q>jc|/:#qwzHL`lL%e~DbhQ+d^tpf9sx%o)jC1Nm}`G;rT2jo+M$=$?BC'|O^]hW^BBo_J->bWG1", +"OIxA\\5HB7g3Rv;PD)z?jGe?<x`4~9&D9dSDP=ilUauI'qb", +"aND[Al/^#;n'|V\"Vl$bh5\\G#{%y4#\\W0:ZgXe73ZuXrWcL4gr|B7,ijZZi{p)M+R9{C/&249G", +"7xK-d6Tx]BU|T,DY.qCwusmV%Ksset", +"I=UwM''S", +"w|_;Qw(R:>Clf[#3JFr_+?'1D&}WaY_xaRyTpwio>C;Pjf/kIW{]KK:R&ARiP=_g_UqRVvFKG(OQo6y'wF]Fc", +"G:", +"+XZ%s7L3FmGFn]Y!J;.vpAUoGU,&WY8eQeGWW?Jq7ANeM}[?gsV) H\\@{8z_t$oS(_jSq]|9?W*sG%' (d%", +"*P\"?'?NHA \\!{.S=+LD8Ltr^'=,$4uQ=tVL/T_b6m!PJ8*s*v`;6kp(+8i.}T!9p6{", +"_@(w<\\DjMk c8/\"/ifJNT_2R>V'}{&72C2+7otvd,$M@Yqc)L=O.muEp28m&AY", +"J!M#$z|n:+:6@7n*v)UCbkVp0;\"1#}o:i4B9oh=%'I", +"0", +"Krq?xAul2cRe&`*Fg2)bV/r>oJ`Z(ae,z%+`E@VkWH&`-jMZ<UW~jxDek;^j2\\Uq;C,Ss", +"#b\\l~=y5H=#Jy(6FwH5]jU;6D", +"YO|tw;`E_'G<d~juVPCla%K]q x\"oA-aW|Y@P$_$", +"}rI\\5x724b29MEauSSX&!AT[J1ce?,rtLAA8X", +"hlo8jd$D-dI=I#Be:BATkZPR~%Vfe0g_Xw^+wwhHQhC1;sn+P<b&J:~HfxVBX}9b/#HHPS", +"+#[?UFGUVFn0Zn7yE#TEo{FV\\{6*+s+a=fR", +"lhv.f!ENs~)?5)z:1^i@BQ|ol}9Cnkw&yV.PPx |y]@,?IL]0L_# b1'wl-]", +"&DhZ!g%v.sF}4NoP~4<vKpaM0[12!2K!ziYC3`505I*D*J6k\\skbXJ}44J#4y2", +"oK][N&iIV\"AEs3rIT-::L3&J^Sn42_J2yL= 2xI4o!b\"#2JiAt=", +"^c;C^{0wD%|y~Z1X'z\\o^gI8L=@2^p3g/L6G?]Nuif;Zf15dF`IPt8", +"62t-!*`U\\l%BFxi5B~[^~G!}h]DtXrd}y}af3", +"?N5d9ydHPi?IhwU=41'", +"GSZeLtA3YahI@oLy/6vT_[B`[PRZ1^.(n8`,8TyqVoCzMd!=9 e", +"Yck5`_#NgS", +"K9?z&o", +"Isl2>%RB8T+,9?B{~A2{fEb[%", +"&fV(`<ha/(T7J&X\\{YHt+5 =>%SaJ&W0_j]]\"", +">!sQ/IYU\"Ikc\\ei;HlCcVJ\":G2/m]h1,GvOmxFOOvTUHjHu:LWE\"QU=) ", +"7Fyx#>\"(\"N", +"MO6\"Hd2H]r8BJ}z)%J18b<VZ5lrhI", +"BGQ|tqdwj4};#x@?%ka[`DwgFWg*J+q/}]-\\\\-y#T", +"zZ=JrTPxh}.(%frt58Cy=C4(*,4]:Gnz5(~iv4@u4re~6yp:zbU0(o.S+qd9eB]A5", +"n]V3}^{9O<0cO\"rtglDO4Wc)_7Nu_JnK2EBbzRMV3b.Mj\"$9#,+-T\"N=7iPdD F<9_YWw3ZN*V;??*8VN8z?^MXi", +"fGRSl*i>^*uy|c;5B}tKXu>5hZX:>CB{oWIrxE8@B/f{:u9]:bLO0/ZWeHoNfCc|kSh{/fXs9Y:UKaJ95vFFtB2Y", +".&-4UOcxR\"Tbgc--@& hoUavCcQW^^fT}:I(d%o}J2t*BRA1{YGXB9>AYu^Bv#rEu`pN65_-r.IQD.?Cc/B({YtK[2KMmVOC3*2J", +"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/", +"8\\5tFz:sod", +"ILUc5c!'K.7.P&=S,pSYB{", +"%\\(6.jC\"C4\\2{TYdx,Ln^", +"tL3HnWq q!'k!#R@2bkvIAI]hk)64-i?uk]oK(nQiKg$`m6tx|#l>m1bEK^&.X[o'b\"\\',A16n>9ZAPI9>", +"{#Mn0,S~a\"!gw", +"dv+6'7Dd)fz", +"9o1*Q:{6#3f uHx\"_", +".43_zr}X+BtruMV!H!xw 8!9I_}zlBT3W52)rh,9ngeu0o[V_s*z'8x9*yjF!", +"y3Nm`>P:seF'V'?+<={oU5QQ", +".#Os_jv,\"@-zsY8j'POOYnY?0ONn?i#d4tqp?~.OF#VC.=<t<+feuf{#@O7lXC@+#t_uKGue%Dk9z", +"0Ep=zwydU-V<)9<9\\`[4,d^B&Gbo#'HTSEC;qU&1| ocNd69#{nbmYJMlj6Mfs3`w&pc(poie *ZOJIp7%}cVnfml", +"746}e(rye4lT7#B.Or8j1->Xs@o8f0}/e>uvvkNS[3UC2F]#[>^f74jxoo&9{^ED#,CV\"k'0|xI", +".D1{.:9gHW}]36RlUQ?!-\"0dn:+(/e@b)|'B", +"!Nh9xY2y?5ku5f}%]JWw~OfeYdcgI#It` T)3VzYl5gChve[I'rEqyJ \"@(z.Y%fEJ:9k(", +"J^$^L8:qI=yrerd0kxJBEwby6[>9[) NpqN%)h", +"l&\\K{s9]aL(,dX?B\"1g1*@9BY~=UO+AWvVRI;ar4p8Tsy~Qk-=x(yp38:j|g'5H~e4", +"(]Pe,1fTS_P%[xY96#,rwQz=P?z", +")PC#?b'&|maJBt.6Izz%vV5e!9Sy|G!*Q", +"pzAG^@/J&)Dc}GP*xO]ezW:*PV|Dt^fF<8GgF_1i=A\"@>nt?yOa|zS<8`/;uY~^ozjvX!K#%us!>2IYITh]Zy<^dq?&\"nqV]ZdZ", +"T<xz*/H&}36<(4E^/Z1m<#_G0R:=qX?1`*6Y&r'SIO]9OR;m5-Zq?PU^jvLKPLW2wPf", +")CLhmCI%TwB+t:h.@Vp-#({d0W/R_(^f34LC=V)A", +"yCT_hl%fUL<T&e;ePsT.pJG@|jO,[pN]]Q<Yu=Lp6X6&$Ka#", +" $4X", +"rp", +"t^(*U<Qdi$!vyg5D\"yQZd<K6<Qptsvzi~D}.Uf?P$E>}t8VP^;3Tamv2Z$1<", +",", +"EGCXZ_{eqIwfG-o7o\\\"!ZWTPLd,U-k$Cz]%:vNWdo}vDh!ONtM>mMP{/Cg+2<.J\"a*n#Rtnha", +"LQ3sIr7Q_ wSD7Zzv$-vxr|3P`pas0#Ze/---{PSwJ3{!a*[k'nFgC\"W+@4URi?qJk&Tt@`abNms40#A^XcAt}", +"^i356'hX\"hKaZGfTZ|C@#}b3LGz1\">qcH{L8{Fs?O5%:EqQWuro_lc=]gWLVR\\~!J\"[>,H", +"i{*q<O{Dt^n|FY3,FG>WIRqPH.os$9^P=|yA9?P;MOw;VBwZ^>K=\"%J9SBlv%0+o5k73rW!`l_", +"-PCM&!G~o#Za^s&)qJELr\\P^\\={_xTFp:%@JF.PeRX\\7b8K", +"V_sFicB+wx5", +"\"X^\\d}b9.W.2\"O!yAL21\"Ny5:)=Q3*D|TAzzr^0Yflzjdc!p*.yW,B", +"kZ`wCP>9Bq5S!r!Vi|Uy/C&H[kz/f^{(Z[OGw'S0\"", +"Jn%1^rUnNB|%=q%^v*bN|I40}#Htn{G!#~CNAN0KvZcB>Ita(,n", +"-PlhE[^J55Ui", +"z`h`uQJ{J", +"eV\\q5Q4o@Y*,IRMcnpqj5>Id\\yBe?pKH3uF&c<c}:E9[uaH$ 8dXCmI+!C'q@PkE<NVRq~GRW<tfyt/i@%dwI&rL", +"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA", +"&joOSw7XZVvSt4ZCT*:aq:3ns!v|r);~7gN8'_D", +"Y<q|Mhn5Nrcb+dR=10pQF5]r@/*7P`79w/htSm2,C~1&sUW{N@v:t9d;HPG&xrI\"YD;V9Y$'g,W'J=GV3,YK", +"Gx&#{;]l/?[{SyX`kTeo", +"30PU7@<'58.hRWsJTa9L.hVQ8}7=$}ih4|$Y*9z3[aooT!]}+>b{1JH^.jjEU{,dAXSCbtEh6", +"%2~x8=A!RW@8N/`hQz`)gl}1DOU9{>Ie'L> 4e]m;kt =isEQ(\\TeI7hWgK-K! p^K'\":3;dxTLO", +"\\ ):{Woay[4", +"\\{Ih&}*8^x6@`V@DZB`rSuhYm4i@TW^t9Hx[^`IVumjXc1vA\"~wt8^Jf:US6Z\\xaS&", +"lo $6<EP|=gAEpd\\M6YDg\"*0m", +/* +"ActiveBorder", +"ActiveCaption", +"AppWorkspace", +"Background", +"ButtonFace", +"ButtonHighlight", +"ButtonShadow", +"ButtonText", +"CaptionText", +"GrayText", +"Highlight", +"HighlightText", +"InactiveBorder", +"InactiveCaption", +"InactiveCaptionText", +"InfoBackground", +"InfoText", +"Menu", +"MenuText", +"Scrollbar", +"ThreeDDarkShadow", +"ThreeDFace", +"ThreeDHighlight", +"ThreeDLightShadow", +"ThreeDShadow", +"Window", +"WindowFrame", +"WindowText", +*/ +"currentColor", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"#000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"#0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"#", +"#1", +"#12", +"#123", +"#1234", +"#12x", +"abc", +"123", +"#0ab0cd0ef", +"#0ab0cd0e", +"#0ab0cd0", +"#0ab0cdaef", +"#0ab0cdae", +"#0ab0cda" +]; + +var references = [ +"#113355", +"#001350", +"#135000", +"#001350", +"#013500", +"#000135", +"#123456", +"#002356", +"#124500", +"#002356", +"#013460", +"#001245", +"#f0f8ff", +"#f0f8ff", +"#a0ce00", +"#a0ce00", +"#0ace0e", +"#a0ebe0", +"#00cee0", +"#faebd7", +"#00ffff", +"#7fffd4", +"#f0ffff", +"#f5f5dc", +"#ffe4c4", +"#000000", +"#ffebcd", +"#0000ff", +"#8a2be2", +"#a52a2a", +"#deb887", +"#5f9ea0", +"#7fff00", +"#d2691e", +"#ff7f50", +"#6495ed", +"#fff8dc", +"#dc143c", +"#00ffff", +"#00008b", +"#008b8b", +"#b8860b", +"#a9a9a9", +"#006400", +"#a9a9a9", +"#bdb76b", +"#8b008b", +"#556b2f", +"#ff8c00", +"#9932cc", +"#8b0000", +"#e9967a", +"#8fbc8f", +"#483d8b", +"#2f4f4f", +"#2f4f4f", +"#00ced1", +"#9400d3", +"#ff1493", +"#00bfff", +"#696969", +"#696969", +"#1e90ff", +"#b22222", +"#fffaf0", +"#228b22", +"#ff00ff", +"#dcdcdc", +"#f8f8ff", +"#ffd700", +"#daa520", +"#808080", +"#008000", +"#adff2f", +"#808080", +"#f0fff0", +"#ff69b4", +"#cd5c5c", +"#4b0082", +"#fffff0", +"#f0e68c", +"#e6e6fa", +"#fff0f5", +"#7cfc00", +"#fffacd", +"#add8e6", +"#f08080", +"#e0ffff", +"#fafad2", +"#d3d3d3", +"#90ee90", +"#d3d3d3", +"#ffb6c1", +"#ffa07a", +"#20b2aa", +"#87cefa", +"#778899", +"#778899", +"#b0c4de", +"#ffffe0", +"#00ff00", +"#32cd32", +"#faf0e6", +"#ff00ff", +"#800000", +"#66cdaa", +"#0000cd", +"#ba55d3", +"#9370db", +"#3cb371", +"#7b68ee", +"#00fa9a", +"#48d1cc", +"#c71585", +"#191970", +"#f5fffa", +"#ffe4e1", +"#ffe4b5", +"#ffdead", +"#000080", +"#fdf5e6", +"#808000", +"#6b8e23", +"#ffa500", +"#ff4500", +"#da70d6", +"#eee8aa", +"#98fb98", +"#afeeee", +"#db7093", +"#ffefd5", +"#ffdab9", +"#cd853f", +"#ffc0cb", +"#dda0dd", +"#b0e0e6", +"#800080", +"#ff0000", +"#bc8f8f", +"#4169e1", +"#8b4513", +"#fa8072", +"#f4a460", +"#2e8b57", +"#fff5ee", +"#a0522d", +"#c0c0c0", +"#87ceeb", +"#6a5acd", +"#708090", +"#708090", +"#fffafa", +"#00ff7f", +"#4682b4", +"#d2b48c", +"#008080", +"#d8bfd8", +"#ff6347", +"#40e0d0", +"#ee82ee", +"#f5deb3", +"#ffffff", +"#f5f5f5", +"#ffff00", +"#9acd32", +"transparent", +"transparent", +"transparent", +"#00e000", +"#00e000", +"#0df000", +"#0000b0", +"#007b30", +"#008001", +"#004b00", +"#002080", +"#099600", +"#0120e2", +"#f00630", +"#d00000", +"#200000", +"#0c00d0", +"#07900a", +"#db020b", +"#7000a0", +"#b00c02", +"#d6d000", +"#000000", +"#1d00f0", +"#000000", +"#a00000", +"#00b600", +"#007028", +"#00b0b9", +"#000000", +"#f00000", +"#b00005", +"#0ea000", +"#72000a", +"#ba0c00", +"#0fe000", +"#50000b", +"#000c44", +"#ae4202", +"#00005d", +"#0000af", +"#5d0041", +"#a00000", +"#c00000", +"#090000", +"#0209fe", +"#a00500", +"#c0100e", +"#7f0000", +"#600000", +"#d00d00", +"#0004d9", +"#c00000", +"#0500ff", +"#0000c3", +"#200000", +"#80f00d", +"#0c7000", +"#00c4d0", +"#a000a0", +"#00a000", +"#d0070f", +"#900600", +"#002090", +"#30ef00", +"#0000e0", +"#b000c0", +"#80c200", +"#0900e0", +"#0005e0", +"#800b00", +"#b0a000", +"#e00000", +"#000690", +"#d00000", +"#010020", +"#0000c0", +"#000060", +"#004000", +"#000000", +"#000da0", +"#000000", +"#00d000", +"#000fa0", +"#0c5000", +"#000030", +"#a0007b", +"#00cb05", +"#023000", +"#9bc000", +"#b000b0", +"#00e055", +"#000000", +"#0dc0d0", +"#20600a", +"#70a070", +"#f50000", +"#0000e0", +"#a900cb", +"#0000d0", +"#000a40", +"#d00060", +"#000ad0", +/* +"ActiveBorder", +"ActiveCaption", +"AppWorkspace", +"Background", +"ButtonFace", +"ButtonHighlight", +"ButtonShadow", +"ButtonText", +"CaptionText", +"GrayText", +"Highlight", +"HighlightText", +"InactiveBorder", +"InactiveCaption", +"InactiveCaptionText", +"InfoBackground", +"InfoText", +"Menu", +"MenuText", +"Scrollbar", +"ThreeDDarkShadow", +"ThreeDFace", +"ThreeDHighlight", +"ThreeDLightShadow", +"ThreeDShadow", +"Window", +"WindowFrame", +"WindowText", +*/ +"#c0e000", +"#0000f0", +"#000000", +"#0000f0", +"#000000", +"#000000", +"#010000", +"#010200", +"#112233", +"#123400", +"#010200", +"#0a0b0c", +"#010203", +"#abcdef", +"#abcde0", +"#abcd00", +"#0a0cae", +"#0a0cae", +"#0a0ca0" +]; + +var todos = { +" #135": true, +"#135 ": true, +" #135 ": true, +"# 135": true, +" #123456": true, +"#123456 ": true, +" #123456 ": true, +"# 123456": true, +" aliceblue": true, +"aliceblue ": true, +" aliceblue ": true, +"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/": true, +" $4X": true, +"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA": true +}; + +var table0 = document.getElementById("table0"); +var table1 = document.getElementById("table1"); +var cs0 = document.defaultView.getComputedStyle(table0, ""); +var cs1 = document.defaultView.getComputedStyle(table1, ""); +var result; +var reference; +var log = ""; +var len = tests.length; +is(tests.length, references.length, "array length mismatch"); +for (var i = 0; i < len; ++i) { + table0.setAttribute("bgColor", tests[i]); + table1.style.backgroundColor = references[i]; + ((tests[i] in todos) ? todo_is : is)( + cs0.getPropertyValue("background-color"), + cs1.getPropertyValue("background-color"), + "html color '" + tests[i] + "' should match '" + references[i] + "'"); +} +</script> + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_html_colors_standards.html b/dom/base/test/test_html_colors_standards.html new file mode 100644 index 0000000000..a466bd765f --- /dev/null +++ b/dom/base/test/test_html_colors_standards.html @@ -0,0 +1,712 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=121738 +--> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 121738</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=121738">Mozilla Bug 121738</a> +<table id="table0"></table> +<table id="table1"></table> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 121738 **/ + +String.prototype.toAsciiLowerCase = function () { + var output = ""; + for (var i = 0, len = this.length; i < len; ++i) { + if (this.charCodeAt(i) >= 0x41 && this.charCodeAt(i) <= 0x5A) { + output += String.fromCharCode(this.charCodeAt(i) + 0x20) + } else { + output += this.charAt(i); + } + } + return output; +} + +var tests = [ +"#135", +" #135", +"#135 ", +" #135 ", +"# 135", +"# 135", +"#123456", +" #123456", +"#123456 ", +" #123456 ", +"# 123456", +"# 123456", +"aliceblue", +"ALICEBLUE", +"alıceblue", +"alİceblue", +" aliceblue", +"aliceblue ", +" aliceblue ", +"antiquewhite", +"aqua", +"aquamarine", +"azure", +"beige", +"bisque", +"black", +"blanchedalmond", +"blue", +"blueviolet", +"brown", +"burlywood", +"cadetblue", +"chartreuse", +"chocolate", +"coral", +"cornflowerblue", +"cornsilk", +"crimson", +"cyan", +"darkblue", +"darkcyan", +"darkgoldenrod", +"darkgray", +"darkgreen", +"darkgrey", +"darkkhaki", +"darkmagenta", +"darkolivegreen", +"darkorange", +"darkorchid", +"darkred", +"darksalmon", +"darkseagreen", +"darkslateblue", +"darkslategray", +"darkslategrey", +"darkturquoise", +"darkviolet", +"deeppink", +"deepskyblue", +"dimgray", +"dimgrey", +"dodgerblue", +"firebrick", +"floralwhite", +"forestgreen", +"fuchsia", +"gainsboro", +"ghostwhite", +"gold", +"goldenrod", +"gray", +"green", +"greenyellow", +"grey", +"honeydew", +"hotpink", +"indianred", +"indigo", +"ivory", +"khaki", +"lavender", +"lavenderblush", +"lawngreen", +"lemonchiffon", +"lightblue", +"lightcoral", +"lightcyan", +"lightgoldenrodyellow", +"lightgray", +"lightgreen", +"lightgrey", +"lightpink", +"lightsalmon", +"lightseagreen", +"lightskyblue", +"lightslategray", +"lightslategrey", +"lightsteelblue", +"lightyellow", +"lime", +"limegreen", +"linen", +"magenta", +"maroon", +"mediumaquamarine", +"mediumblue", +"mediumorchid", +"mediumpurple", +"mediumseagreen", +"mediumslateblue", +"mediumspringgreen", +"mediumturquoise", +"mediumvioletred", +"midnightblue", +"mintcream", +"mistyrose", +"moccasin", +"navajowhite", +"navy", +"oldlace", +"olive", +"olivedrab", +"orange", +"orangered", +"orchid", +"palegoldenrod", +"palegreen", +"paleturquoise", +"palevioletred", +"papayawhip", +"peachpuff", +"peru", +"pink", +"plum", +"powderblue", +"purple", +"red", +"rosybrown", +"royalblue", +"saddlebrown", +"salmon", +"sandybrown", +"seagreen", +"seashell", +"sienna", +"silver", +"skyblue", +"slateblue", +"slategray", +"slategrey", +"snow", +"springgreen", +"steelblue", +"tan", +"teal", +"thistle", +"tomato", +"turquoise", +"violet", +"wheat", +"white", +"whitesmoke", +"yellow", +"yellowgreen", +"transparent", +"TRANSPARENT", +"", +"inherit", +"INHERIT", +"KQ@m?-ldxNK{zH+(FL_owz>YNH^]", +"aj9c)r+J&3)0E,- Lzv6K6nT@6?I}BY^\\g", +"Cf}qJN|3D>m:^[7B*fhu>lC[B3\"T_-F", +"h<s1pMd-8H[,\\caWH1oW3%M", +"z{y]VZj)%)ZV<OTbO9\\Nbc|YL}4BI<DlUBk$EV`EbN}x/@SDN0(", +"PSX2Ol8@", +"d+gYXKUM'&D'S]o<9T\\:hj_i!|l!)e6R4Bo)-(965rlK\"K01C68pgkJ] fx?kjT.O&sY4", +"[4\"tk)a/v17?0W!F`AyI[='2~;:DF6I>_<O$ he213u", +"F|r9T&N69MWq3Jrj6", +"dYR7}n&:Rq[J", +"M;Z]r@(R([6aT`<sN?uO'2Kb~3U\\\\tQUDxLN1f/D(,Q0w|K;,t`,tQ~[W/c!uQg)d|:D\\U33!DK&d*C`Zc'U#", +"kV)DKUb~h{SQCM;T*g2!Rj?>Sl=jY;3W9M{Fliu!=>tDY]5", +"y>X\\kKN|~=J+7Pqp|%9R!nZ,@>mUW9<o;|02LV<fxihsBSKVaTdcae", +"Q>jc|/:#qwzHL`lL%e~DbhQ+d^tpf9sx%o)jC1Nm}`G;rT2jo+M$=$?BC'|O^]hW^BBo_J->bWG1", +"OIxA\\5HB7g3Rv;PD)z?jGe?<x`4~9&D9dSDP=ilUauI'qb", +"aND[Al/^#;n'|V\"Vl$bh5\\G#{%y4#\\W0:ZgXe73ZuXrWcL4gr|B7,ijZZi{p)M+R9{C/&249G", +"7xK-d6Tx]BU|T,DY.qCwusmV%Ksset", +"I=UwM''S", +"w|_;Qw(R:>Clf[#3JFr_+?'1D&}WaY_xaRyTpwio>C;Pjf/kIW{]KK:R&ARiP=_g_UqRVvFKG(OQo6y'wF]Fc", +"G:", +"+XZ%s7L3FmGFn]Y!J;.vpAUoGU,&WY8eQeGWW?Jq7ANeM}[?gsV) H\\@{8z_t$oS(_jSq]|9?W*sG%' (d%", +"*P\"?'?NHA \\!{.S=+LD8Ltr^'=,$4uQ=tVL/T_b6m!PJ8*s*v`;6kp(+8i.}T!9p6{", +"_@(w<\\DjMk c8/\"/ifJNT_2R>V'}{&72C2+7otvd,$M@Yqc)L=O.muEp28m&AY", +"J!M#$z|n:+:6@7n*v)UCbkVp0;\"1#}o:i4B9oh=%'I", +"0", +"Krq?xAul2cRe&`*Fg2)bV/r>oJ`Z(ae,z%+`E@VkWH&`-jMZ<UW~jxDek;^j2\\Uq;C,Ss", +"#b\\l~=y5H=#Jy(6FwH5]jU;6D", +"YO|tw;`E_'G<d~juVPCla%K]q x\"oA-aW|Y@P$_$", +"}rI\\5x724b29MEauSSX&!AT[J1ce?,rtLAA8X", +"hlo8jd$D-dI=I#Be:BATkZPR~%Vfe0g_Xw^+wwhHQhC1;sn+P<b&J:~HfxVBX}9b/#HHPS", +"+#[?UFGUVFn0Zn7yE#TEo{FV\\{6*+s+a=fR", +"lhv.f!ENs~)?5)z:1^i@BQ|ol}9Cnkw&yV.PPx |y]@,?IL]0L_# b1'wl-]", +"&DhZ!g%v.sF}4NoP~4<vKpaM0[12!2K!ziYC3`505I*D*J6k\\skbXJ}44J#4y2", +"oK][N&iIV\"AEs3rIT-::L3&J^Sn42_J2yL= 2xI4o!b\"#2JiAt=", +"^c;C^{0wD%|y~Z1X'z\\o^gI8L=@2^p3g/L6G?]Nuif;Zf15dF`IPt8", +"62t-!*`U\\l%BFxi5B~[^~G!}h]DtXrd}y}af3", +"?N5d9ydHPi?IhwU=41'", +"GSZeLtA3YahI@oLy/6vT_[B`[PRZ1^.(n8`,8TyqVoCzMd!=9 e", +"Yck5`_#NgS", +"K9?z&o", +"Isl2>%RB8T+,9?B{~A2{fEb[%", +"&fV(`<ha/(T7J&X\\{YHt+5 =>%SaJ&W0_j]]\"", +">!sQ/IYU\"Ikc\\ei;HlCcVJ\":G2/m]h1,GvOmxFOOvTUHjHu:LWE\"QU=) ", +"7Fyx#>\"(\"N", +"MO6\"Hd2H]r8BJ}z)%J18b<VZ5lrhI", +"BGQ|tqdwj4};#x@?%ka[`DwgFWg*J+q/}]-\\\\-y#T", +"zZ=JrTPxh}.(%frt58Cy=C4(*,4]:Gnz5(~iv4@u4re~6yp:zbU0(o.S+qd9eB]A5", +"n]V3}^{9O<0cO\"rtglDO4Wc)_7Nu_JnK2EBbzRMV3b.Mj\"$9#,+-T\"N=7iPdD F<9_YWw3ZN*V;??*8VN8z?^MXi", +"fGRSl*i>^*uy|c;5B}tKXu>5hZX:>CB{oWIrxE8@B/f{:u9]:bLO0/ZWeHoNfCc|kSh{/fXs9Y:UKaJ95vFFtB2Y", +".&-4UOcxR\"Tbgc--@& hoUavCcQW^^fT}:I(d%o}J2t*BRA1{YGXB9>AYu^Bv#rEu`pN65_-r.IQD.?Cc/B({YtK[2KMmVOC3*2J", +"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/", +"8\\5tFz:sod", +"ILUc5c!'K.7.P&=S,pSYB{", +"%\\(6.jC\"C4\\2{TYdx,Ln^", +"tL3HnWq q!'k!#R@2bkvIAI]hk)64-i?uk]oK(nQiKg$`m6tx|#l>m1bEK^&.X[o'b\"\\',A16n>9ZAPI9>", +"{#Mn0,S~a\"!gw", +"dv+6'7Dd)fz", +"9o1*Q:{6#3f uHx\"_", +".43_zr}X+BtruMV!H!xw 8!9I_}zlBT3W52)rh,9ngeu0o[V_s*z'8x9*yjF!", +"y3Nm`>P:seF'V'?+<={oU5QQ", +".#Os_jv,\"@-zsY8j'POOYnY?0ONn?i#d4tqp?~.OF#VC.=<t<+feuf{#@O7lXC@+#t_uKGue%Dk9z", +"0Ep=zwydU-V<)9<9\\`[4,d^B&Gbo#'HTSEC;qU&1| ocNd69#{nbmYJMlj6Mfs3`w&pc(poie *ZOJIp7%}cVnfml", +"746}e(rye4lT7#B.Or8j1->Xs@o8f0}/e>uvvkNS[3UC2F]#[>^f74jxoo&9{^ED#,CV\"k'0|xI", +".D1{.:9gHW}]36RlUQ?!-\"0dn:+(/e@b)|'B", +"!Nh9xY2y?5ku5f}%]JWw~OfeYdcgI#It` T)3VzYl5gChve[I'rEqyJ \"@(z.Y%fEJ:9k(", +"J^$^L8:qI=yrerd0kxJBEwby6[>9[) NpqN%)h", +"l&\\K{s9]aL(,dX?B\"1g1*@9BY~=UO+AWvVRI;ar4p8Tsy~Qk-=x(yp38:j|g'5H~e4", +"(]Pe,1fTS_P%[xY96#,rwQz=P?z", +")PC#?b'&|maJBt.6Izz%vV5e!9Sy|G!*Q", +"pzAG^@/J&)Dc}GP*xO]ezW:*PV|Dt^fF<8GgF_1i=A\"@>nt?yOa|zS<8`/;uY~^ozjvX!K#%us!>2IYITh]Zy<^dq?&\"nqV]ZdZ", +"T<xz*/H&}36<(4E^/Z1m<#_G0R:=qX?1`*6Y&r'SIO]9OR;m5-Zq?PU^jvLKPLW2wPf", +")CLhmCI%TwB+t:h.@Vp-#({d0W/R_(^f34LC=V)A", +"yCT_hl%fUL<T&e;ePsT.pJG@|jO,[pN]]Q<Yu=Lp6X6&$Ka#", +" $4X", +"rp", +"t^(*U<Qdi$!vyg5D\"yQZd<K6<Qptsvzi~D}.Uf?P$E>}t8VP^;3Tamv2Z$1<", +",", +"EGCXZ_{eqIwfG-o7o\\\"!ZWTPLd,U-k$Cz]%:vNWdo}vDh!ONtM>mMP{/Cg+2<.J\"a*n#Rtnha", +"LQ3sIr7Q_ wSD7Zzv$-vxr|3P`pas0#Ze/---{PSwJ3{!a*[k'nFgC\"W+@4URi?qJk&Tt@`abNms40#A^XcAt}", +"^i356'hX\"hKaZGfTZ|C@#}b3LGz1\">qcH{L8{Fs?O5%:EqQWuro_lc=]gWLVR\\~!J\"[>,H", +"i{*q<O{Dt^n|FY3,FG>WIRqPH.os$9^P=|yA9?P;MOw;VBwZ^>K=\"%J9SBlv%0+o5k73rW!`l_", +"-PCM&!G~o#Za^s&)qJELr\\P^\\={_xTFp:%@JF.PeRX\\7b8K", +"V_sFicB+wx5", +"\"X^\\d}b9.W.2\"O!yAL21\"Ny5:)=Q3*D|TAzzr^0Yflzjdc!p*.yW,B", +"kZ`wCP>9Bq5S!r!Vi|Uy/C&H[kz/f^{(Z[OGw'S0\"", +"Jn%1^rUnNB|%=q%^v*bN|I40}#Htn{G!#~CNAN0KvZcB>Ita(,n", +"-PlhE[^J55Ui", +"z`h`uQJ{J", +"eV\\q5Q4o@Y*,IRMcnpqj5>Id\\yBe?pKH3uF&c<c}:E9[uaH$ 8dXCmI+!C'q@PkE<NVRq~GRW<tfyt/i@%dwI&rL", +"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA", +"&joOSw7XZVvSt4ZCT*:aq:3ns!v|r);~7gN8'_D", +"Y<q|Mhn5Nrcb+dR=10pQF5]r@/*7P`79w/htSm2,C~1&sUW{N@v:t9d;HPG&xrI\"YD;V9Y$'g,W'J=GV3,YK", +"Gx&#{;]l/?[{SyX`kTeo", +"30PU7@<'58.hRWsJTa9L.hVQ8}7=$}ih4|$Y*9z3[aooT!]}+>b{1JH^.jjEU{,dAXSCbtEh6", +"%2~x8=A!RW@8N/`hQz`)gl}1DOU9{>Ie'L> 4e]m;kt =isEQ(\\TeI7hWgK-K! p^K'\":3;dxTLO", +"\\ ):{Woay[4", +"\\{Ih&}*8^x6@`V@DZB`rSuhYm4i@TW^t9Hx[^`IVumjXc1vA\"~wt8^Jf:US6Z\\xaS&", +"lo $6<EP|=gAEpd\\M6YDg\"*0m", +/* +"ActiveBorder", +"ActiveCaption", +"AppWorkspace", +"Background", +"ButtonFace", +"ButtonHighlight", +"ButtonShadow", +"ButtonText", +"CaptionText", +"GrayText", +"Highlight", +"HighlightText", +"InactiveBorder", +"InactiveCaption", +"InactiveCaptionText", +"InfoBackground", +"InfoText", +"Menu", +"MenuText", +"Scrollbar", +"ThreeDDarkShadow", +"ThreeDFace", +"ThreeDHighlight", +"ThreeDLightShadow", +"ThreeDShadow", +"Window", +"WindowFrame", +"WindowText", +*/ +"currentColor", +"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"#000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"#0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f", +"#", +"#1", +"#12", +"#123", +"#1234", +"#12x", +"abc", +"123", +"#0ab0cd0ef", +"#0ab0cd0e", +"#0ab0cd0", +"#0ab0cdaef", +"#0ab0cdae", +"#0ab0cda" +]; + +var references = [ +"#113355", +"#001350", +"#135000", +"#001350", +"#013500", +"#000135", +"#123456", +"#002356", +"#124500", +"#002356", +"#013460", +"#001245", +"#f0f8ff", +"#f0f8ff", +"#a0ce00", +"#a0ce00", +"#0ace0e", +"#a0ebe0", +"#00cee0", +"#faebd7", +"#00ffff", +"#7fffd4", +"#f0ffff", +"#f5f5dc", +"#ffe4c4", +"#000000", +"#ffebcd", +"#0000ff", +"#8a2be2", +"#a52a2a", +"#deb887", +"#5f9ea0", +"#7fff00", +"#d2691e", +"#ff7f50", +"#6495ed", +"#fff8dc", +"#dc143c", +"#00ffff", +"#00008b", +"#008b8b", +"#b8860b", +"#a9a9a9", +"#006400", +"#a9a9a9", +"#bdb76b", +"#8b008b", +"#556b2f", +"#ff8c00", +"#9932cc", +"#8b0000", +"#e9967a", +"#8fbc8f", +"#483d8b", +"#2f4f4f", +"#2f4f4f", +"#00ced1", +"#9400d3", +"#ff1493", +"#00bfff", +"#696969", +"#696969", +"#1e90ff", +"#b22222", +"#fffaf0", +"#228b22", +"#ff00ff", +"#dcdcdc", +"#f8f8ff", +"#ffd700", +"#daa520", +"#808080", +"#008000", +"#adff2f", +"#808080", +"#f0fff0", +"#ff69b4", +"#cd5c5c", +"#4b0082", +"#fffff0", +"#f0e68c", +"#e6e6fa", +"#fff0f5", +"#7cfc00", +"#fffacd", +"#add8e6", +"#f08080", +"#e0ffff", +"#fafad2", +"#d3d3d3", +"#90ee90", +"#d3d3d3", +"#ffb6c1", +"#ffa07a", +"#20b2aa", +"#87cefa", +"#778899", +"#778899", +"#b0c4de", +"#ffffe0", +"#00ff00", +"#32cd32", +"#faf0e6", +"#ff00ff", +"#800000", +"#66cdaa", +"#0000cd", +"#ba55d3", +"#9370db", +"#3cb371", +"#7b68ee", +"#00fa9a", +"#48d1cc", +"#c71585", +"#191970", +"#f5fffa", +"#ffe4e1", +"#ffe4b5", +"#ffdead", +"#000080", +"#fdf5e6", +"#808000", +"#6b8e23", +"#ffa500", +"#ff4500", +"#da70d6", +"#eee8aa", +"#98fb98", +"#afeeee", +"#db7093", +"#ffefd5", +"#ffdab9", +"#cd853f", +"#ffc0cb", +"#dda0dd", +"#b0e0e6", +"#800080", +"#ff0000", +"#bc8f8f", +"#4169e1", +"#8b4513", +"#fa8072", +"#f4a460", +"#2e8b57", +"#fff5ee", +"#a0522d", +"#c0c0c0", +"#87ceeb", +"#6a5acd", +"#708090", +"#708090", +"#fffafa", +"#00ff7f", +"#4682b4", +"#d2b48c", +"#008080", +"#d8bfd8", +"#ff6347", +"#40e0d0", +"#ee82ee", +"#f5deb3", +"#ffffff", +"#f5f5f5", +"#ffff00", +"#9acd32", +"transparent", +"transparent", +"transparent", +"#00e000", +"#00e000", +"#0df000", +"#0000b0", +"#007b30", +"#008001", +"#004b00", +"#002080", +"#099600", +"#0120e2", +"#f00630", +"#d00000", +"#200000", +"#0c00d0", +"#07900a", +"#db020b", +"#7000a0", +"#b00c02", +"#d6d000", +"#000000", +"#1d00f0", +"#000000", +"#a00000", +"#00b600", +"#007028", +"#00b0b9", +"#000000", +"#f00000", +"#b00005", +"#0ea000", +"#72000a", +"#ba0c00", +"#0fe000", +"#50000b", +"#000c44", +"#ae4202", +"#00005d", +"#0000af", +"#5d0041", +"#a00000", +"#c00000", +"#090000", +"#0209fe", +"#a00500", +"#c0100e", +"#7f0000", +"#600000", +"#d00d00", +"#0004d9", +"#c00000", +"#0500ff", +"#0000c3", +"#200000", +"#80f00d", +"#0c7000", +"#00c4d0", +"#a000a0", +"#00a000", +"#d0070f", +"#900600", +"#002090", +"#30ef00", +"#0000e0", +"#b000c0", +"#80c200", +"#0900e0", +"#0005e0", +"#800b00", +"#b0a000", +"#e00000", +"#000690", +"#d00000", +"#010020", +"#0000c0", +"#000060", +"#004000", +"#000000", +"#000da0", +"#000000", +"#00d000", +"#000fa0", +"#0c5000", +"#000030", +"#a0007b", +"#00cb05", +"#023000", +"#9bc000", +"#b000b0", +"#00e055", +"#000000", +"#0dc0d0", +"#20600a", +"#70a070", +"#f50000", +"#0000e0", +"#a900cb", +"#0000d0", +"#000a40", +"#d00060", +"#000ad0", +/* +"ActiveBorder", +"ActiveCaption", +"AppWorkspace", +"Background", +"ButtonFace", +"ButtonHighlight", +"ButtonShadow", +"ButtonText", +"CaptionText", +"GrayText", +"Highlight", +"HighlightText", +"InactiveBorder", +"InactiveCaption", +"InactiveCaptionText", +"InfoBackground", +"InfoText", +"Menu", +"MenuText", +"Scrollbar", +"ThreeDDarkShadow", +"ThreeDFace", +"ThreeDHighlight", +"ThreeDLightShadow", +"ThreeDShadow", +"Window", +"WindowFrame", +"WindowText", +*/ +"#c0e000", +"#0000f0", +"#000000", +"#0000f0", +"#000000", +"#000000", +"#010000", +"#010200", +"#112233", +"#123400", +"#010200", +"#0a0b0c", +"#010203", +"#abcdef", +"#abcde0", +"#abcd00", +"#0a0cae", +"#0a0cae", +"#0a0ca0" +]; + +var todos = { +" #135": true, +"#135 ": true, +" #135 ": true, +"# 135": true, +" #123456": true, +"#123456 ": true, +" #123456 ": true, +"# 123456": true, +" aliceblue": true, +"aliceblue ": true, +" aliceblue ": true, +"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/": true, +" $4X": true, +"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA": true +}; + +var table0 = document.getElementById("table0"); +var table1 = document.getElementById("table1"); +var cs0 = document.defaultView.getComputedStyle(table0, ""); +var cs1 = document.defaultView.getComputedStyle(table1, ""); +var result; +var reference; +var log = ""; +var len = tests.length; +is(tests.length, references.length, "array length mismatch"); +for (var i = 0; i < len; ++i) { + table0.setAttribute("bgColor", tests[i]); + table1.style.backgroundColor = references[i]; + ((tests[i] in todos) ? todo_is : is)( + cs0.getPropertyValue("background-color"), + cs1.getPropertyValue("background-color"), + "html color '" + tests[i] + "' should match '" + references[i] + "'"); +} +</script> + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_htmlcopyencoder.html b/dom/base/test/test_htmlcopyencoder.html new file mode 100644 index 0000000000..dbd87471ff --- /dev/null +++ b/dom/base/test/test_htmlcopyencoder.html @@ -0,0 +1,196 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Test on the html copy encoder</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422403">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function testHtmlCopyEncoder () { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + var out, expected; + + var node = document.getElementById('draggable'); + + + // in the following tests, we must use the OutputLFLineBreak flag, to avoid + // to have the default line break of the platform in the result, so the test + // can pass on all platform + + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = 'This is a <em>draggable</em> bit of text.'; + is(out, expected, "test container node "); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>"; + is(out, expected, "test node"); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = "<div style=\"display: none\">\n\n<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>\n\n</div>"; + is(out, expected, "test selection"); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputAbsoluteLinks | de.OutputEncodeHTMLEntities | de.OutputSelectionOnly | de.OutputRaw); + encoder.setSelection(select); + var outContext = {value:''}, outInfo = {value:''}; + out = encoder.encodeToStringWithContext(outContext, outInfo); + expected = "<div style=\"display: none\">\n\n<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>\n\n</div>"; + is(out, expected, "test encodeToStringWithContext with selection "); + + node.nextSibling.data="\nfoo bar\n"; + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = "<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> bit of text.</div>"; + is(out, expected, "test selection with additional data"); + + node = document.getElementById('aList'); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id=\"aList\">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection"); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = '\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n'; + is(out, expected, "test list container node"); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<ol id=\"aList\">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>"; + is(out, expected, "test list node"); + + var liList = node.getElementsByTagName("li"); + var range = document.createRange(); + + // selection start at the first child of the ol, and end after the element ol + range.setStart(node, 1); + range.setEnd(node.parentNode, 2); + select.removeAllRanges(); + select.addRange(range); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id="aList">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the first child of the ol, and end after the element ol"); + + // selection start at the third child of the ol, and end after the element ol + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id="aList"><li value=\"2\">sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol"); + + + // selection start at the third child of the ol, and end after the element ol + ol start at the value 5 + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + node.setAttribute("start","5"); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id=\"aList\" start=\"5\"><li value=\"6\">sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol + ol start at the value 5"); + + // selection contains only some child of the ol + node.removeAttribute("start"); + range.setStart(node, 3); + range.setEnd(node, 5); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + is(out, expected, "test list selection with range: selection contains only some child of the ol"); + + // selection contains only some child of the ol + ol start at the value 5 + node.setAttribute("start","5"); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + is(out, expected, "test list selection with range: selection contains only some child of the ol + ol start at the value 5"); + + // selection contains only some child of the ol + a value is set on the first li + node.removeAttribute("start"); + liList[0].setAttribute("value","8"); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + is(out, expected, "test list selection with range: selection contains only some child of the ol + ol start at the value 5"); + + select.selectAllChildren(node); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id=\"aList\">\n <li value=\"8\">Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + is(out, expected, "test list selection with a value on a LI"); + + //test Bug 436703 + node = document.getElementById('aContentEditable'); + select.selectAllChildren(node); + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<p>one</p><p>two</p>'; + is(out, expected, "select all children in an contentEditable div should not select the div itself"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlCopyEncoder); + +</script> +</pre> +<div style="display: none"> + +<div id="draggable" ondragstart="doDragStartSelection(event)">This is a <em>draggable</em> bit of text.</div> + +</div> +<div style="display: none"> + +<ol id="aList"> + <li>Lorem ipsum dolor</li> + <li>sit amet, <strong>consectetuer</strong> </li> + <li>adipiscing elit</li> + <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li> + <li>aptent taciti</li> +</ol> +foo bar +</div> + +<div id="aContentEditable" contentEditable="true"><p>one</p><p>two</p></div> +</body> +</html> diff --git a/dom/base/test/test_htmlcopyencoder.xhtml b/dom/base/test/test_htmlcopyencoder.xhtml new file mode 100644 index 0000000000..57559fc005 --- /dev/null +++ b/dom/base/test/test_htmlcopyencoder.xhtml @@ -0,0 +1,180 @@ +<!DOCTYPE HTML> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- +--> +<head> + <title>Test the html copy encoder with XHTML</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=422403">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +//<![CDATA[ +function testHtmlCopyEncoder () { + const de = SpecialPowers.Ci.nsIDocumentEncoder; + var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"] + .createInstance(SpecialPowers.Ci.nsIDocumentEncoder); + var out, expected; + + var node = document.getElementById('draggable'); + + + // in the following tests, we must use the OutputLFLineBreak flag, to avoid + // to have the default line break of the platform in the result, so the test + // can pass on all platform + + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = 'This is a <em>draggable</em> <br>bit of text.'; + is(out, expected, "test container node "); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> <br>bit of text.</div>"; + is(out, expected, "test node"); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = "<div style=\"display: none;\">\n\n<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em> <br>bit of text.</div>\n\n</div>"; + todo_is(out, expected, "test selection"); + + node.nextSibling.data="\nfoo bar\n"; + encoder.init(document, "text/html", de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = "<div id=\"draggable\" ondragstart=\"doDragStartSelection(event)\">This is a <em>draggable</em>\n <br>bit of text.</div>"; + todo_is(out, expected, "test selection with additional data"); + + node = document.getElementById('aList'); + + var select = window.getSelection(); + select.selectAllChildren(node); + + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id=\"aList\">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus \naliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + todo_is(out, expected, "test list selection"); + + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setContainerNode(node); + out = encoder.encodeToString(); + expected = '\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n'; + is(out, expected, "test list container node"); + + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setNode(node); + out = encoder.encodeToString(); + expected = "<ol id=\"aList\">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>"; + is(out, expected, "test list node"); + + var liList = node.getElementsByTagName("li"); + var range = document.createRange(); + + // selection start at the first child of the ol, and end after the element ol + range.setStart(node, 1); + range.setEnd(node.parentNode, 2); + select.removeAllRanges(); + select.addRange(range); + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id="aList">\n <li>Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + todo_is(out, expected, "test list selection with range: selection start at the first child of the ol, and end after the element ol"); + + // selection start at the third child of the ol, and end after the element ol + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id="aList"><li value=\"2\">sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + todo_is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol"); + + + // selection start at the third child of the ol, and end after the element ol + ol start at the value 5 + range.setStart(node, 3); + range.setEnd(node.parentNode, 2); + node.setAttribute("start","5"); + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol start=\"5\" id=\"aList\"><li value=\"6\">sit amet, <strong>consectetuer</strong>\n </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + todo_is(out, expected, "test list selection with range: selection start at the third child of the ol, and end after the element ol + ol start at the value 5"); + + + // selection contains only some child of the ol + node.removeAttribute("start"); + range.setStart(node, 3); + range.setEnd(node, 5); + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + todo_is(out, expected, "test list selection with range: selection contains only some child of the ol"); + + // selection contains only some child of the ol + ol start at the value 5 + node.setAttribute("start","5"); + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + todo_is(out, expected, "test list selection with range: selection contains only some child of the ol + ol start at the value 5"); + + + // selection contains only some child of the ol + a value is set on the first li + node.removeAttribute("start"); + liList[0].setAttribute("value","8"); + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<li>sit amet, <strong>consectetuer</strong> </li>\n '; + todo_is(out, expected, "test list selection: contains only some child of the ol + a value is set on the first li"); + + select.selectAllChildren(node); + encoder.init(document, "text/html",de.OutputLFLineBreak | de.OutputSelectionOnly); + encoder.setSelection(select); + out = encoder.encodeToString(); + expected = '<ol id=\"aList\">\n <li value=\"8\">Lorem ipsum dolor</li>\n <li>sit amet, <strong>consectetuer</strong> </li>\n <li>adipiscing elit</li>\n <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus \naliquet lectus. Nunc vitae eros. Class</li>\n <li>aptent taciti</li>\n</ol>'; + todo_is(out, expected, "test list selection with a value on a LI"); + + SimpleTest.finish(); +} + + +SimpleTest.waitForExplicitFinish(); + +addLoadEvent(testHtmlCopyEncoder); +//]]> +</script> +</pre> +<div style="display: none"> + +<div id="draggable" ondragstart="doDragStartSelection(event)">This is a <em>draggable</em> <br/>bit of text.</div> + +</div> +<div style="display: none"> + +<ol id="aList"> + <li>Lorem ipsum dolor</li> + <li>sit amet, <strong>consectetuer</strong> </li> + <li>adipiscing elit</li> + <li>Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class</li> + <li>aptent taciti</li> +</ol> +foo bar +</div> +</body> +</html> diff --git a/dom/base/test/test_iframe_referrer.html b/dom/base/test/test_iframe_referrer.html new file mode 100644 index 0000000000..3c46096b9f --- /dev/null +++ b/dom/base/test/test_iframe_referrer.html @@ -0,0 +1,107 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test iframe referrer policy attribute for Bug 1175736</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that iframe referrer attribute is honoured correctly + * regular loads + * regression tests that meta referrer is still working even if attribute referrers are enabled + https://bugzilla.mozilla.org/show_bug.cgi?id=1175736 + --> + + <script type="application/javascript;version=1.7"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "SCHEME_FROM", "SCHEME_TO"]; + + const testCases = [ + {ACTION: ["generate-iframe-policy-test"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "unsafe-url (iframe) with origin in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin', + NAME: 'origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + DESC: "origin (iframe) with unsafe-url in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'no-referrer-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "no-referrer (iframe) with origin in meta", + RESULT: 'none'}, + {NAME: 'no-referrer-in-meta', + META_POLICY: 'no-referrer', + DESC: "no-referrer in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'origin', + NAME: 'origin-with-no-meta', + META_POLICY: '', + DESC: "origin (iframe) with no meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'same-origin-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "same-origin with origin in meta", + RESULT: 'full'}, + + // 1. Downgrade. + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin-when-cross-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + + // 2. No downgrade. + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'origin in meta strict-origin-when-cross-origin in attr', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'strict-origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + DESC: "strict-origin-when-cross-origin with origin in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'same-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + DESC: "same-origin with origin in meta", + RESULT: 'none'}, + ]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> diff --git a/dom/base/test/test_iframe_referrer_changing.html b/dom/base/test/test_iframe_referrer_changing.html new file mode 100644 index 0000000000..c65058fe80 --- /dev/null +++ b/dom/base/test/test_iframe_referrer_changing.html @@ -0,0 +1,50 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test iframe referrer policy attribute for Bug 1175736</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that iframe referrer attribute is honoured correctly + * testing setAttribute and .referrer + https://bugzilla.mozilla.org/show_bug.cgi?id=1175736 + --> + + <script type="application/javascript;version=1.7"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY"]; + + const testCases = [ + {ACTION: ["generate-iframe-changing-policy-test-set-attribute"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NEW_ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'no-referrer-unsafe-url-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "no-referrer (iframe, orginally unsafe-url) with origin in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'origin', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-origin-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + DESC: "unsafe-url (iframe, orginally origin) with no-referrer in meta", + RESULT: 'full'}]}, + {ACTION: ["generate-iframe-changing-policy-test-property"], + TESTS: [ + {ATTRIBUTE_POLICY: 'no-referrer', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'unsafe-url-no-referrer-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "unsafe-url (iframe, orginally no-referrer) with origin in meta", + RESULT: 'full'}]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> diff --git a/dom/base/test/test_iframe_referrer_invalid.html b/dom/base/test/test_iframe_referrer_invalid.html new file mode 100644 index 0000000000..c4bd1d6ac5 --- /dev/null +++ b/dom/base/test/test_iframe_referrer_invalid.html @@ -0,0 +1,81 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test iframe referrer policy attribute for Bug 1175736</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that iframe referrer attribute is honoured correctly + * invalid referrer policies + https://bugzilla.mozilla.org/show_bug.cgi?id=1175736 + --> + + <script type="application/javascript;version=1.7"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "SCHEME_FROM", "SCHEME_TO"]; + + const testCases = [ + {ACTION: ["generate-iframe-policy-test"], + TESTS: [ + // setting invalid refer values -> we expect either full referrer (default) + // or whatever is specified in the meta referrer policy + + // Note that for those test cases which require cross-origin test, we use different + // scheme to result in cross-origin request. + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-no-meta', + META_POLICY: '', + DESC: "origin-when-cross-origin (iframe) with no meta", + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'default', + NAME: 'default-with-no-meta', + META_POLICY: '', + DESC: "default (iframe) with no meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'something', + NAME: 'something-with-no-meta', + META_POLICY: '', + DESC: "something (iframe) with no meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + DESC: "origin-when-cross-origin (iframe) with no-referrer in meta", + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + DESC: "origin-when-cross-origin (iframe) with unsafe-url in meta", + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + DESC: "origin-when-cross-origin (iframe) with origin in meta", + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'origin'}, + {NAME: 'origin-in-meta', + META_POLICY: 'origin', + DESC: "origin in meta", + RESULT: 'origin'}, + {NAME: 'no-referrer-in-meta', + META_POLICY: 'no-referrer', + DESC: "no-referrer in meta", + RESULT: 'none'}]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> diff --git a/dom/base/test/test_img_referrer.html b/dom/base/test/test_img_referrer.html new file mode 100644 index 0000000000..16259bcc39 --- /dev/null +++ b/dom/base/test/test_img_referrer.html @@ -0,0 +1,189 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test img policy attribute for Bug 1166910</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + +<!-- +Testing that img referrer attribute is honoured correctly +* Speculative parser loads (generate-img-policy-test) +* regular loads (generate-img-policy-test2) +* loading a single image multiple times with different policies (generate-img-policy-test3) +* testing setAttribute and .referrer (generate-setAttribute-test) +* regression tests that meta referrer is still working even if attribute referrers are enabled +https://bugzilla.mozilla.org/show_bug.cgi?id=1166910 +--> + +<script type="application/javascript;version=1.7"> + +SimpleTest.waitForExplicitFinish(); +var advance = function() { tests.next(); }; + +/** + * Listen for notifications from the child. + * These are sent in case of error, or when the loads we await have completed. + */ +window.addEventListener("message", function(event) { + if (event.data == "childLoadComplete" || + event.data.contains("childLoadComplete")) { + advance(); + } +}); + +/** + * helper to perform an XHR. + */ +function doXHR(aUrl, onSuccess, onFail) { + var xhr = new XMLHttpRequest(); + xhr.responseType = "json"; + xhr.onload = function () { + onSuccess(xhr); + }; + xhr.onerror = function () { + onFail(xhr); + }; + xhr.open('GET', aUrl, true); + xhr.send(null); +} + +/** + * Grabs the results via XHR and passes to checker. + */ +function checkIndividualResults(aTestname, aExpectedImg, aName) { + doXHR('/tests/dom/base/test/img_referrer_testserver.sjs?action=get-test-results', + function(xhr) { + var results = xhr.response; + info(JSON.stringify(xhr.response)); + + for (i in aName) { + ok(aName[i] in results.tests, aName[i] + " tests have to be performed."); + is(results.tests[aName[i]].policy, aExpectedImg[i], aTestname + ' --- ' + results.tests[aName[i]].policy + ' (' + results.tests[aName[i]].referrer + ')'); + } + + advance(); + }, + function(xhr) { + ok(false, "Can't get results from the counter server."); + SimpleTest.finish(); + }); +} + +function resetState() { + doXHR('/tests/dom/base/test/img_referrer_testserver.sjs?action=resetState', + advance, + function(xhr) { + ok(false, "error in reset state"); + SimpleTest.finish(); + }); +} + +/** + * testing if img referrer attribute is honoured (1165501) + */ +var tests = (function() { + + // enable referrer attribute + yield SpecialPowers.pushPrefEnv({"set": [['network.http.enablePerElementReferrer', true]]}, advance); + + var iframe = document.getElementById("testframe"); + var sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-img-policy-test"; + + // setting img unsafe-url and meta origin - unsafe-url shall prevail (should use speculative load) + yield resetState(); + var name = 'unsaf-url-with-meta-in-origin'; + yield iframe.src = sjs + "&imgPolicy=" + escape('unsafe-url') + "&name=" + name + "&policy=" + escape('origin'); + yield checkIndividualResults("unsafe-url (img) with origin in meta", ["full"], [name]); + + // setting img no-referrer and meta default - no-referrer shall prevail (should use speculative load) + yield resetState(); + name = 'no-referrer-with-meta-in-origin'; + yield iframe.src = sjs + "&imgPolicy=" + escape('no-referrer')+ "&name=" + name + "&policy=" + escape('origin'); + yield checkIndividualResults("no-referrer (img) with default in meta", ["none"], [name]); + + // test referrer policy in regular load + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-img-policy-test2"; + name = 'regular-load-unsafe-url'; + yield iframe.src = sjs + "&imgPolicy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("unsafe-url in img", ["full"], [name]); + + // test referrer policy in regular load with multiple images + var policies = ['unsafe-url', 'origin', 'no-referrer']; + var expected = ["full", "origin", "none"]; + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-img-policy-test3"; + name = 'multiple-images-'+policies[0]+'-'+policies[1]+'-'+policies[2]; + yield iframe.src = sjs + "&imgPolicy1=" + escape(policies[0]) + "&imgPolicy2=" + escape(policies[1]) + "&imgPolicy3=" + escape(policies[2]) + "&name=" + name; + yield checkIndividualResults(policies[0]+", "+policies[1]+" and "+policies[2]+" in img", expected, [name+policies[0], name+policies[1], name+policies[2]]); + + policies = ['origin', 'no-referrer', 'unsafe-url']; + expected = ["origin", "none", "full"]; + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-img-policy-test3"; + name = 'multiple-images-'+policies[0]+'-'+policies[1]+'-'+policies[2]; + yield iframe.src = sjs + "&imgPolicy1=" + escape(policies[0]) + "&imgPolicy2=" + escape(policies[1]) + "&imgPolicy3=" + escape(policies[2]) + "&name=" + name; + yield checkIndividualResults(policies[0]+", "+policies[1]+" and "+policies[2]+" in img", expected, [name+policies[0], name+policies[1], name+policies[2]]); + + policies = ['no-referrer', 'origin', 'unsafe-url']; + expected = ["none", "origin", "full"]; + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-img-policy-test3"; + name = 'multiple-images-'+policies[0]+'-'+policies[1]+'-'+policies[2]; + yield iframe.src = sjs + "&imgPolicy1=" + escape(policies[0]) + "&imgPolicy2=" + escape(policies[1]) + "&imgPolicy3=" + escape(policies[2]) + "&name=" + name; + yield checkIndividualResults(policies[0]+", "+policies[1]+" and "+policies[2]+" in img", expected, [name+policies[0], name+policies[1], name+policies[2]]); + + // regression tests that meta referrer is still working even if attribute referrers are enabled + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-img-policy-test4"; + name = 'regular-load-no-referrer-meta'; + yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name; + yield checkIndividualResults("no-referrer in meta (no img referrer policy), speculative load", ["none"], [name]); + + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-img-policy-test5"; + name = 'regular-load-no-referrer-meta'; + yield iframe.src = sjs + "&policy=" + escape('no-referrer') + "&name=" + name; + yield checkIndividualResults("no-referrer in meta (no img referrer policy), regular load", ["none"], [name]); + + //test setAttribute + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-setAttribute-test1"; + name = 'set-referrer-policy-attribute-before-src'; + yield iframe.src = sjs + "&imgPolicy=" + escape('no-referrer') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("no-referrer in img", ["none"], [name]); + + yield resetState(); + sjs = "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-setAttribute-test2"; + name = 'set-referrer-policy-attribute-after-src'; + yield iframe.src = sjs + "&imgPolicy=" + escape('no-referrer') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("no-referrer in img", ["none"], [name]); + + yield resetState(); + sjs = + "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-setAttribute-test2"; + name = 'set-invalid-referrer-policy-attribute-before-src-invalid'; + yield iframe.src = sjs + "&imgPolicy=" + escape('invalid') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("unsafe-url in meta, invalid in img", ["full"], [name]); + + yield resetState(); + sjs = + "/tests/dom/base/test/img_referrer_testserver.sjs?action=generate-setAttribute-test2"; + name = 'set-invalid-referrer-policy-attribute-before-src-invalid'; + yield iframe.src = sjs + "&imgPolicy=" + escape('default') + "&policy=" + escape('unsafe-url') + "&name=" + name; + yield checkIndividualResults("unsafe-url in meta, default in img", ["full"], [name]); + + // complete. Be sure to yield so we don't call this twice. + yield SimpleTest.finish(); +})(); + +</script> +</head> + +<body onload="tests.next();"> + <iframe id="testframe"></iframe> + +</body> +</html> + diff --git a/dom/base/test/test_innersize_scrollport.html b/dom/base/test/test_innersize_scrollport.html new file mode 100644 index 0000000000..a000e93554 --- /dev/null +++ b/dom/base/test/test_innersize_scrollport.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 919437</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=919437">Mozilla Bug 919437</a> +<div id="content" style="display: none"></div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 919437 **/ + +SimpleTest.waitForExplicitFinish(); + +function run() +{ + var oldWidth = window.innerWidth; + var oldHeight = window.innerHeight; + var newWidth = oldWidth / 2; + var newHeight = oldHeight / 2; + + var utils = SpecialPowers.getDOMWindowUtils(window); + utils.setScrollPositionClampingScrollPortSize(newWidth, newHeight); + is(window.innerWidth, newWidth, "innerWidth not updated to scroll port width"); + is(window.innerHeight, newHeight, "innerHeight not updated to scroll port height"); + + var innerWidthGetter = Object.getOwnPropertyDescriptor(window, "innerWidth").get; + var innerHeightGetter = Object.getOwnPropertyDescriptor(window, "innerHeight").get; + + window.innerWidth = oldWidth; + window.innerHeight = oldHeight; + is(window.innerWidth, oldWidth, "Should have redefined innerWidth"); + is(window.innerHeight, oldHeight, "Should have redefined innerWidth"); + is(innerWidthGetter.call(window), newWidth, "innerWidth clobbered by direct set"); + is(innerHeightGetter.call(window), newHeight, "innerHeight clobbered by direct set"); + + SimpleTest.finish(); +} + +window.addEventListener("load", run, false); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_integer_attr_with_leading_zero.html b/dom/base/test/test_integer_attr_with_leading_zero.html new file mode 100644 index 0000000000..816fb331c4 --- /dev/null +++ b/dom/base/test/test_integer_attr_with_leading_zero.html @@ -0,0 +1,64 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for parsing of integer attributes with leading zero</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> +var td = document.createElement("td"); +var li = document.createElement("li"); +// Array of tests: "values" are the values to set, "tdreflection" is the +// corresponding td.rowspan value, "lireflection" is the corresponding li.value +// value. +var testData = [ + { + values: [ + "2", + "02", + "002", + "00002", + ], + tdreflection: 2, + lireflection: 2, + }, + { + values: [ + "-2", + "-02", + "-002", + "-00002", + ], + tdreflection: 1, + lireflection: -2, + }, + { + values: [ + "-0", + "-00", + "0", + "00", + ], + tdreflection: 0, + lireflection: 0, + }, +]; + +for (var data of testData) { + for (var value of data.values) { + td.setAttribute("rowspan", value); + li.setAttribute("value", value); + test(function() { + assert_equals(td.rowSpan, data.tdreflection); + }, `<td> reflection for ${value}`); + test(function() { + assert_equals(td.getAttribute("rowspan"), value); + }, `<td> setAttribute roundtripping for ${value}`); + test(function() { + assert_equals(li.value, data.lireflection); + }, `<li> reflection for ${value}`); + test(function() { + assert_equals(li.getAttribute("value"), value); + }, `<li> setAttribute roundtripping for ${value}`); + } +} +</script> diff --git a/dom/base/test/test_intersectionobservers.html b/dom/base/test/test_intersectionobservers.html new file mode 100644 index 0000000000..e7875e3af0 --- /dev/null +++ b/dom/base/test/test_intersectionobservers.html @@ -0,0 +1,1214 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1243846 + +Some tests ported from IntersectionObserver/polyfill/intersection-observer-test.html + +Original license header: + +Copyright 2016 Google Inc. All Rights Reserved. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1243846</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="next()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1243846">Mozilla Bug 1243846</a> +<p id="display"></p> +<pre id="test"> +<script type="application/javascript"> + + SpecialPowers.setIntPref("layout.visibility.min-notify-intersection-observers-interval-ms", 0); + + var tests = []; + var curDescribeMsg = ''; + var curItMsg = ''; + + function beforeEach_fn() { }; + function afterEach_fn() { }; + + function before(fn) { + fn(); + } + + function beforeEach(fn) { + beforeEach_fn = fn; + } + + function afterEach(fn) { + afterEach_fn = fn; + } + + function it(msg, fn) { + tests.push({ + msg: `${msg} [${curDescribeMsg}]`, + fn: fn + }); + } + + var callbacks = []; + function callDelayed(fn, delay) { + callbacks.push({ + fn: fn, + time: +new Date() + delay + }); + } + + requestAnimationFrame(function tick() { + var i = callbacks.length; + while (i--) { + var cb = callbacks[i]; + if (+new Date() >= cb.time) { + SimpleTest.executeSoon(cb.fn); + callbacks.splice(i, 1); + } + } + requestAnimationFrame(tick); + }); + + function expect(val) { + return { + to: { + throwException: function (regexp) { + try { + val(); + ok(false, `${curItMsg} - an exception should have beeen thrown`); + } catch (e) { + ok(regexp.test(e), `${curItMsg} - supplied regexp should match thrown exception`); + } + }, + get be() { + var fn = function (expected) { + is(val, expected, curItMsg); + }; + fn.ok = function () { + ok(val, curItMsg); + }; + fn.greaterThan = function (other) { + ok(val > other, `${curItMsg} - ${val} should be greater than ${other}`); + }; + fn.lessThan = function (other) { + ok(val < other, `${curItMsg} - ${val} should be less than ${other}`); + }; + return fn; + }, + eql: function (expected) { + if (Array.isArray(expected)) { + if (!Array.isArray(val)) { + ok(false, curItMsg, `${curItMsg} - should be an array,`); + return; + } + is(val.length, expected.length, curItMsg, `${curItMsg} - arrays should be the same length`); + if (expected.length != val.length) { + return; + } + for (var i = 0; i < expected.length; i++) { + is(val[i], expected[i], `${curItMsg} - array elements at position ${i} should be equal`); + if (expected[i] != val[i]) { + return; + } + } + ok(true); + } + }, + } + } + } + + function describe(msg, fn) { + curDescribeMsg = msg; + fn(); + curDescribeMsg = ''; + } + + function next() { + var test = tests.shift(); + if (test) { + console.log(test.msg); + curItMsg = test.msg; + var fn = test.fn; + beforeEach_fn(); + if (fn.length) { + fn(function () { + afterEach_fn(); + next(); + }); + } else { + fn(); + afterEach_fn(); + next(); + } + } else { + SimpleTest.finish(); + } + } + + var sinon = { + spy: function () { + var callbacks = []; + var fn = function () { + fn.callCount++; + fn.lastCall = { args: arguments }; + if (callbacks.length) { + callbacks.shift()(); + } + }; + fn.callCount = 0; + fn.lastCall = { args: [] }; + fn.waitForNotification = (fn) => { + callbacks.push(fn); + }; + return fn; + } + }; + + var ASYNC_TIMEOUT = 300; + + + var io; + var noop = function() {}; + + + // References to DOM elements, which are accessible to any test + // and reset prior to each test so state isn't shared. + var rootEl; + var grandParentEl; + var parentEl; + var targetEl1; + var targetEl2; + var targetEl3; + var targetEl4; + var targetEl5; + + + describe('IntersectionObserver', function() { + + before(function() { + + }); + + + beforeEach(function() { + addStyles(); + addFixtures(); + }); + + + afterEach(function() { + if (io && 'disconnect' in io) io.disconnect(); + io = null; + + window.onmessage = null; + + removeStyles(); + removeFixtures(); + }); + + + describe('constructor', function() { + + it('throws when callback is not a function', function() { + expect(function() { + io = new IntersectionObserver(null); + }).to.throwException(/.*/i); + }); + + + it('instantiates root correctly', function() { + io = new IntersectionObserver(noop); + expect(io.root).to.be(null); + + io = new IntersectionObserver(noop, {root: rootEl}); + expect(io.root).to.be(rootEl); + }); + + + it('throws when root is not an Element', function() { + expect(function() { + io = new IntersectionObserver(noop, {root: 'foo'}); + }).to.throwException(/.*/i); + }); + + + it('instantiates rootMargin correctly', function() { + io = new IntersectionObserver(noop, {rootMargin: '10px'}); + expect(io.rootMargin).to.be('10px 10px 10px 10px'); + + io = new IntersectionObserver(noop, {rootMargin: '10px -5%'}); + expect(io.rootMargin).to.be('10px -5% 10px -5%'); + + io = new IntersectionObserver(noop, {rootMargin: '10px 20% 0px'}); + expect(io.rootMargin).to.be('10px 20% 0px 20%'); + + io = new IntersectionObserver(noop, {rootMargin: '0px 0px -5% 5px'}); + expect(io.rootMargin).to.be('0px 0px -5% 5px'); + }); + + + it('throws when rootMargin is not in pixels or percent', function() { + expect(function() { + io = new IntersectionObserver(noop, {rootMargin: 'auto'}); + }).to.throwException(/pixels.*percent/i); + }); + + + it('instantiates thresholds correctly', function() { + io = new IntersectionObserver(noop); + expect(io.thresholds).to.eql([0]); + + io = new IntersectionObserver(noop, {threshold: 0.5}); + expect(io.thresholds).to.eql([0.5]); + + io = new IntersectionObserver(noop, {threshold: [0.25, 0.5, 0.75]}); + expect(io.thresholds).to.eql([0.25, 0.5, 0.75]); + + io = new IntersectionObserver(noop, {threshold: [1, .5, 0]}); + expect(io.thresholds).to.eql([0, .5, 1]); + }); + + it('throws when a threshold value is not between 0 and 1', function() { + expect(function() { + io = new IntersectionObserver(noop, {threshold: [0, -1]}); + }).to.throwException(/threshold/i); + }); + + it('throws when a threshold value is not a number', function() { + expect(function() { + io = new IntersectionObserver(noop, {threshold: "foo"}); + }).to.throwException(/.*/i); + }); + + }); + + + describe('observe', function() { + + it('throws when target is not an Element', function() { + expect(function() { + io = new IntersectionObserver(noop); + io.observe(null); + }).to.throwException(/.*/i); + }); + + + it('triggers if target intersects when observing begins', function(done) { + io = new IntersectionObserver(function(records) { + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, {root: rootEl}); + io.observe(targetEl1); + }); + + + it('triggers with the correct arguments', function(done) { + io = new IntersectionObserver(function(records, observer) { + expect(records.length).to.be(1); + expect(records[0] instanceof IntersectionObserverEntry).to.be.ok(); + expect(observer).to.be(io); + expect(this).to.be(io); + done(); + }, {root: rootEl}); + io.observe(targetEl1); + }); + + + it('does not trigger if target does not intersect when observing begins', + function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + targetEl2.style.top = '-40px'; + io.observe(targetEl2); + callDelayed(function() { + expect(spy.callCount).to.be(0); + done(); + }, ASYNC_TIMEOUT); + }); + + + it('does not trigger if target is not a descendant of the intersection root in the containing block chain', + function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: parentEl}); + + parentEl.style.position = 'static'; + io.observe(targetEl2); + callDelayed(function() { + expect(spy.callCount).to.be(0); + done(); + }, ASYNC_TIMEOUT); + }); + + it('triggers if target or root becomes invisible', + function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + runSequence([ + function(done) { + io.observe(targetEl1); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.display = 'none'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(2); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.display = 'block'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(3); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + rootEl.style.display = 'none'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(4); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + rootEl.style.display = 'block'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(5); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + }, + ], done); + }); + + + it('handles container elements with non-visible overflow', + function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + runSequence([ + function(done) { + io.observe(targetEl1); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.left = '-40px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(2); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + parentEl.style.overflow = 'visible'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(3); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + } + ], done); + }); + + + it('observes one target at a single threshold correctly', function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl, threshold: 0.5}); + + runSequence([ + function(done) { + targetEl1.style.left = '-5px'; + io.observe(targetEl1); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be.greaterThan(0.5); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.left = '-15px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(2); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be.lessThan(0.5); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.left = '-25px'; + callDelayed(function() { + expect(spy.callCount).to.be(2); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.left = '-10px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(3); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0.5); + done(); + }, ASYNC_TIMEOUT); + } + ], done); + + }); + + + it('observes multiple targets at multiple thresholds correctly', + function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, { + root: rootEl, + threshold: [1, 0.5, 0] + }); + + runSequence([ + function(done) { + targetEl1.style.top = '0px'; + targetEl1.style.left = '-15px'; + targetEl2.style.top = '-5px'; + targetEl2.style.left = '0px'; + targetEl3.style.top = '0px'; + targetEl3.style.left = '205px'; + io.observe(targetEl1); + io.observe(targetEl2); + io.observe(targetEl3); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(2); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(0.25); + expect(records[1].target).to.be(targetEl2); + expect(records[1].intersectionRatio).to.be(0.75); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.top = '0px'; + targetEl1.style.left = '-5px'; + targetEl2.style.top = '-15px'; + targetEl2.style.left = '0px'; + targetEl3.style.top = '0px'; + targetEl3.style.left = '195px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(2); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(3); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(0.75); + expect(records[1].target).to.be(targetEl2); + expect(records[1].intersectionRatio).to.be(0.25); + expect(records[2].target).to.be(targetEl3); + expect(records[2].intersectionRatio).to.be(0.25); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.top = '0px'; + targetEl1.style.left = '5px'; + targetEl2.style.top = '-25px'; + targetEl2.style.left = '0px'; + targetEl3.style.top = '0px'; + targetEl3.style.left = '185px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(3); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(3); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(1); + expect(records[1].target).to.be(targetEl2); + expect(records[1].intersectionRatio).to.be(0); + expect(records[2].target).to.be(targetEl3); + expect(records[2].intersectionRatio).to.be(0.75); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.top = '0px'; + targetEl1.style.left = '15px'; + targetEl2.style.top = '-35px'; + targetEl2.style.left = '0px'; + targetEl3.style.top = '0px'; + targetEl3.style.left = '175px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(4); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].target).to.be(targetEl3); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + } + ], done); + }); + + + it('handles rootMargin properly', function(done) { + + parentEl.style.overflow = 'visible'; + targetEl1.style.top = '0px'; + targetEl1.style.left = '-20px'; + targetEl2.style.top = '-20px'; + targetEl2.style.left = '0px'; + targetEl3.style.top = '0px'; + targetEl3.style.left = '200px'; + targetEl4.style.top = '180px'; + targetEl4.style.left = '180px'; + + runSequence([ + function(done) { + io = new IntersectionObserver(function(records) { + records = sortRecords(records); + expect(records.length).to.be(4); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(1); + expect(records[1].target).to.be(targetEl2); + expect(records[1].intersectionRatio).to.be(.5); + expect(records[2].target).to.be(targetEl3); + expect(records[2].intersectionRatio).to.be(.5); + expect(records[3].target).to.be(targetEl4); + expect(records[3].intersectionRatio).to.be(1); + io.disconnect(); + done(); + }, {root: rootEl, rootMargin: '10px'}); + + io.observe(targetEl1); + io.observe(targetEl2); + io.observe(targetEl3); + io.observe(targetEl4); + }, + function(done) { + io = new IntersectionObserver(function(records) { + records = sortRecords(records); + expect(records.length).to.be(3); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(0.5); + expect(records[1].target).to.be(targetEl3); + expect(records[1].intersectionRatio).to.be(0.5); + expect(records[2].target).to.be(targetEl4); + expect(records[2].intersectionRatio).to.be(0.5); + io.disconnect(); + done(); + }, {root: rootEl, rootMargin: '-10px 10%'}); + + io.observe(targetEl1); + io.observe(targetEl2); + io.observe(targetEl3); + io.observe(targetEl4); + }, + function(done) { + io = new IntersectionObserver(function(records) { + records = sortRecords(records); + expect(records.length).to.be(2); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(0.5); + expect(records[1].target).to.be(targetEl4); + expect(records[1].intersectionRatio).to.be(0.5); + io.disconnect(); + done(); + }, {root: rootEl, rootMargin: '-5% -2.5% 0px'}); + + io.observe(targetEl1); + io.observe(targetEl2); + io.observe(targetEl3); + io.observe(targetEl4); + }, + function(done) { + io = new IntersectionObserver(function(records) { + records = sortRecords(records); + expect(records.length).to.be(3); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(0.5); + expect(records[1].target).to.be(targetEl2); + expect(records[1].intersectionRatio).to.be(0.5); + expect(records[2].target).to.be(targetEl4); + expect(records[2].intersectionRatio).to.be(0.25); + io.disconnect(); + done(); + }, {root: rootEl, rootMargin: '5% -2.5% -10px -190px'}); + + io.observe(targetEl1); + io.observe(targetEl2); + io.observe(targetEl3); + io.observe(targetEl4); + } + ], done); + }); + + + it('handles targets on the boundary of root', function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + runSequence([ + function(done) { + targetEl1.style.top = '0px'; + targetEl1.style.left = '-21px'; + targetEl2.style.top = '-20px'; + targetEl2.style.left = '0px'; + io.observe(targetEl1); + io.observe(targetEl2); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + expect(records[0].target).to.be(targetEl2); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.top = '0px'; + targetEl1.style.left = '-20px'; + targetEl2.style.top = '-21px'; + targetEl2.style.left = '0px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(2); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(2); + expect(records[0].intersectionRatio).to.be(0); + expect(records[0].target).to.be(targetEl1); + expect(records[1].intersectionRatio).to.be(0); + expect(records[1].target).to.be(targetEl2); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl1.style.top = '-20px'; + targetEl1.style.left = '200px'; + targetEl2.style.top = '200px'; + targetEl2.style.left = '200px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(3); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + expect(records[0].target).to.be(targetEl2); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + targetEl3.style.top = '20px'; + targetEl3.style.left = '-20px'; + targetEl4.style.top = '-20px'; + targetEl4.style.left = '20px'; + io.observe(targetEl3); + io.observe(targetEl4); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(4); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(2); + expect(records[0].intersectionRatio).to.be(0); + expect(records[0].target).to.be(targetEl3); + expect(records[1].intersectionRatio).to.be(0); + expect(records[1].target).to.be(targetEl4); + done(); + }, ASYNC_TIMEOUT); + } + ], done); + + }); + + + it('handles zero-size targets within the root coordinate space', + function(done) { + + io = new IntersectionObserver(function(records) { + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + done(); + }, {root: rootEl}); + + targetEl1.style.top = '0px'; + targetEl1.style.left = '0px'; + targetEl1.style.width = '0px'; + targetEl1.style.height = '0px'; + io.observe(targetEl1); + }); + + + it('handles root/target elements not yet in the DOM', function(done) { + + rootEl.parentNode.removeChild(rootEl); + targetEl1.parentNode.removeChild(targetEl1); + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + runSequence([ + function(done) { + io.observe(targetEl1); + callDelayed(done, 0); + }, + function(done) { + document.getElementById('fixtures').appendChild(rootEl); + callDelayed(function() { + expect(spy.callCount).to.be(0); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + parentEl.insertBefore(targetEl1, targetEl2); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + expect(records[0].target).to.be(targetEl1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + grandParentEl.parentNode.removeChild(grandParentEl); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(2); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + expect(records[0].target).to.be(targetEl1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + rootEl.appendChild(targetEl1); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(3); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + expect(records[0].target).to.be(targetEl1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + rootEl.parentNode.removeChild(rootEl); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(4); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(0); + expect(records[0].target).to.be(targetEl1); + done(); + }, ASYNC_TIMEOUT); + } + ], done); + }); + + + it('handles sub-root element scrolling', function(done) { + io = new IntersectionObserver(function(records) { + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, {root: rootEl}); + + io.observe(targetEl3); + callDelayed(function() { + parentEl.scrollLeft = 40; + }, 0); + }); + + + it('supports CSS transitions and transforms', function(done) { + + targetEl1.style.top = '220px'; + targetEl1.style.left = '220px'; + + io = new IntersectionObserver(function(records) { + expect(records.length).to.be(1); + expect(records[0].intersectionRatio).to.be(1); + done(); + }, {root: rootEl, threshold: [1]}); + + io.observe(targetEl1); + callDelayed(function() { + targetEl1.style.transform = 'translateX(-40px) translateY(-40px)'; + }, 0); + }); + + + it('uses the viewport when no root is specified', function(done) { + window.onmessage = function (e) { + expect(e.data).to.be.ok(); + win.close(); + done(); + }; + + var win = window.open("intersectionobserver_window.html"); + }); + + }); + + describe('observe subframe', function () { + + it('should not trigger if target and root are not in the same document', + function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + targetEl4.onload = function () { + targetEl5 = targetEl4.contentDocument.getElementById('target5'); + io.observe(targetEl5); + callDelayed(function() { + expect(spy.callCount).to.be(0); + done(); + }, ASYNC_TIMEOUT); + } + + targetEl4.src = "intersectionobserver_iframe.html"; + + }); + + it('boundingClientRect matches target.getBoundingClientRect() for an element inside an iframe', + function(done) { + + io = new IntersectionObserver(function(records) { + expect(records.length).to.be(1); + expect(records[0].boundingClientRect.top, targetEl5.getBoundingClientRect().top); + expect(records[0].boundingClientRect.left, targetEl5.getBoundingClientRect().left); + expect(records[0].boundingClientRect.width, targetEl5.getBoundingClientRect().width); + expect(records[0].boundingClientRect.height, targetEl5.getBoundingClientRect().height); + done(); + }, {threshold: [1]}); + + targetEl4.onload = function () { + targetEl5 = targetEl4.contentDocument.getElementById('target5'); + io.observe(targetEl5); + } + + targetEl4.src = "intersectionobserver_iframe.html"; + }); + + it('rootBounds should is set to null for cross-origin observations', function(done) { + + window.onmessage = function (e) { + expect(e.data).to.be.ok(); + done(); + }; + + targetEl4.src = "http://example.org/tests/dom/base/test/intersectionobserver_iframe.html"; + + }); + + }); + + describe('takeRecords', function() { + + it('supports getting records before the callback is invoked', + function(done) { + + var lastestRecords = []; + io = new IntersectionObserver(function(records) { + lastestRecords = lastestRecords.concat(records); + }, {root: rootEl}); + io.observe(targetEl1); + + window.requestAnimationFrame && requestAnimationFrame(function() { + lastestRecords = lastestRecords.concat(io.takeRecords()); + }); + + callDelayed(function() { + expect(lastestRecords.length).to.be(1); + expect(lastestRecords[0].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + }); + + }); + + + describe('unobserve', function() { + + it('removes targets from the internal store', function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + runSequence([ + function(done) { + targetEl1.style.top = targetEl2.style.top = '0px'; + targetEl1.style.left = targetEl2.style.left = '0px'; + io.observe(targetEl1); + io.observe(targetEl2); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(2); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(1); + expect(records[1].target).to.be(targetEl2); + expect(records[1].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + io.unobserve(targetEl1); + targetEl1.style.top = targetEl2.style.top = '0px'; + targetEl1.style.left = targetEl2.style.left = '-40px'; + spy.waitForNotification(function() { + expect(spy.callCount).to.be(2); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(1); + expect(records[0].target).to.be(targetEl2); + expect(records[0].intersectionRatio).to.be(0); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + io.unobserve(targetEl2); + targetEl1.style.top = targetEl2.style.top = '0px'; + targetEl1.style.left = targetEl2.style.left = '0px'; + callDelayed(function() { + expect(spy.callCount).to.be(2); + done(); + }, ASYNC_TIMEOUT); + } + ], done); + + }); + + }); + + describe('disconnect', function() { + + it('removes all targets and stops listening for changes', function(done) { + + var spy = sinon.spy(); + io = new IntersectionObserver(spy, {root: rootEl}); + + runSequence([ + function(done) { + targetEl1.style.top = targetEl2.style.top = '0px'; + targetEl1.style.left = targetEl2.style.left = '0px'; + io.observe(targetEl1); + io.observe(targetEl2); + spy.waitForNotification(function() { + expect(spy.callCount).to.be(1); + var records = sortRecords(spy.lastCall.args[0]); + expect(records.length).to.be(2); + expect(records[0].target).to.be(targetEl1); + expect(records[0].intersectionRatio).to.be(1); + expect(records[1].target).to.be(targetEl2); + expect(records[1].intersectionRatio).to.be(1); + done(); + }, ASYNC_TIMEOUT); + }, + function(done) { + io.disconnect(); + targetEl1.style.top = targetEl2.style.top = '0px'; + targetEl1.style.left = targetEl2.style.left = '-40px'; + callDelayed(function() { + expect(spy.callCount).to.be(1); + done(); + }, ASYNC_TIMEOUT); + } + ], done); + + }); + + }); + + }); + + + /** + * Runs a sequence of function and when finished invokes the done callback. + * Each function in the sequence is invoked with its own done function and + * it should call that function once it's complete. + * @param {Array<Function>} functions An array of async functions. + * @param {Function} done A final callback to be invoked once all function + * have run. + */ + function runSequence(functions, done) { + var next = functions.shift(); + if (next) { + next(function() { + runSequence(functions, done); + }); + } else { + done && done(); + } + } + + + /** + * Sorts an array of records alphebetically by ascending ID. Since the current + * native implementation doesn't sort change entries by `observe` order, we do + * that ourselves for the non-polyfill case. Since all tests call observe + * on targets in sequential order, this should always match. + * https://crbug.com/613679 + * @param {Array<IntersectionObserverEntry>} entries The entries to sort. + * @return {Array<IntersectionObserverEntry>} The sorted array. + */ + function sortRecords(entries) { + entries = entries.sort(function(a, b) { + return a.target.id < b.target.id ? -1 : 1; + }); + return entries; + } + + + /** + * Adds the common styles used by all tests to the page. + */ + function addStyles() { + var styles = document.createElement('style'); + styles.id = 'styles'; + document.documentElement.appendChild(styles); + + var cssText = + '#root {' + + ' position: relative;' + + ' width: 400px;' + + ' height: 200px;' + + ' background: #eee' + + '}' + + '#grand-parent {' + + ' position: relative;' + + ' width: 200px;' + + ' height: 200px;' + + '}' + + '#parent {' + + ' position: absolute;' + + ' top: 0px;' + + ' left: 200px;' + + ' overflow: hidden;' + + ' width: 200px;' + + ' height: 200px;' + + ' background: #ddd;' + + '}' + + '#target1, #target2, #target3, #target4 {' + + ' position: absolute;' + + ' top: 0px;' + + ' left: 0px;' + + ' width: 20px;' + + ' height: 20px;' + + ' transform: translateX(0px) translateY(0px);' + + ' transition: transform .5s;' + + ' background: #f00;' + + ' border: none;' + + '}'; + + styles.innerHTML = cssText; + } + + + /** + * Adds the DOM fixtures used by all tests to the page and assigns them to + * global variables so they can be referenced within the tests. + */ + function addFixtures() { + var fixtures = document.createElement('div'); + fixtures.id = 'fixtures'; + + fixtures.innerHTML = + '<div id="root">' + + ' <div id="grand-parent">' + + ' <div id="parent">' + + ' <div id="target1"></div>' + + ' <div id="target2"></div>' + + ' <div id="target3"></div>' + + ' <iframe id="target4"></iframe>' + + ' </div>' + + ' </div>' + + '</div>'; + + document.body.appendChild(fixtures); + + rootEl = document.getElementById('root'); + grandParentEl = document.getElementById('grand-parent'); + parentEl = document.getElementById('parent'); + targetEl1 = document.getElementById('target1'); + targetEl2 = document.getElementById('target2'); + targetEl3 = document.getElementById('target3'); + targetEl4 = document.getElementById('target4'); + } + + + /** + * Removes the common styles from the page. + */ + function removeStyles() { + var styles = document.getElementById('styles'); + styles.parentNode.removeChild(styles); + } + + + /** + * Removes the DOM fixtures from the page and resets the global references. + */ + function removeFixtures() { + var fixtures = document.getElementById('fixtures'); + fixtures.parentNode.removeChild(fixtures); + + rootEl = null; + grandParentEl = null; + parentEl = null; + targetEl1 = null; + targetEl2 = null; + targetEl3 = null; + targetEl4 = null; + } + + SimpleTest.waitForExplicitFinish(); +</script> +</pre> +<div id="log"> +</div> +</body> +</html> diff --git a/dom/base/test/test_ipc_messagemanager_blob.html b/dom/base/test/test_ipc_messagemanager_blob.html new file mode 100644 index 0000000000..74eab29459 --- /dev/null +++ b/dom/base/test/test_ipc_messagemanager_blob.html @@ -0,0 +1,143 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for OOP Blobs in MessageManager</title> + <script type="application/javascript" + src="/tests/SimpleTest/SimpleTest.js"> + </script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + const childFrameURL = + "data:text/html,<!DOCTYPE HTML><html><body></body></html>"; + + function childFrameScript() { + "use strict"; + + addMessageListener("test:ipcClonedMessage", function(message) { + if (!(message.json instanceof Components.interfaces.nsIDOMBlob)) { + sendAsyncMessage(message.name, message.json); + return; + } + + let reader = new FileReader(); + reader.addEventListener("load", function() { + let response = reader.result == "this is a great success!" ? + message.json : + "error"; + sendAsyncMessage(message.name, response); + }); + reader.readAsText(message.json); + }); + } + + function runTests() { + function done() { + SpecialPowers.removePermission("browser", document); + SimpleTest.finish(); + } + + ok("Browser prefs set."); + + let iframe = document.createElement("iframe"); + SpecialPowers.wrap(iframe).mozbrowser = true; + iframe.id = "iframe"; + iframe.src = childFrameURL; + + iframe.addEventListener("mozbrowserloadend", function() { + ok(true, "Got iframe load event."); + + const blobString = "this is a great success!"; + + const messages = [ + "hi!", + "", + 2, + -.04, + 3432987324987239872948732982, + true, + false, + null, + 0, + + // Make sure this one is always last. + new Blob(["this ", "is ", "a ", "great ", "success!"], + {"type" : "text\/plain"}), + ]; + let receivedMessageIndex = 0; + + let mm = SpecialPowers.getBrowserFrameMessageManager(iframe); + mm.addMessageListener("test:ipcClonedMessage", function(message) { + let data = message.json; + + if (data instanceof Blob) { + is(receivedMessageIndex, messages.length - 1, "Blob is last"); + is (data.size, + messages[receivedMessageIndex].size, + "Correct blob size"); + is (data.type, + messages[receivedMessageIndex].type, + "Correct blob type"); + + let result1, result2; + + let reader1 = new FileReader(); + reader1.onload = function() { + result1 = reader1.result == blobString ? reader1.result : "bad1"; + if (result2) { + is(result1, result2, "Same results"); + done(); + } + }; + + let reader2 = new FileReader(); + reader2.onload = function() { + result2 = reader2.result == blobString ? reader2.result : "bad2"; + if (result1) { + is(result1, result2, "Same results"); + done(); + } + }; + + reader1.readAsText(data); + reader2.readAsText(messages[receivedMessageIndex]); + return; + } + + is(message.json, + messages[receivedMessageIndex++], + "Got correct round-tripped response"); + }); + mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();", + false); + + for (let message of messages) { + mm.sendAsyncMessage("test:ipcClonedMessage", message); + } + }); + + document.body.appendChild(iframe); + } + + addEventListener("load", function() { + info("Got load event."); + + SpecialPowers.addPermission("browser", true, document); + SpecialPowers.pushPrefEnv({ + "set": [ + ["dom.ipc.browser_frames.oop_by_default", true], + ["dom.mozBrowserFramesEnabled", true], + ["network.disable.ipc.security", true], + ["browser.pagethumbnails.capturing_disabled", true] + ] + }, runTests); + }); + </script> +</body> +</html> diff --git a/dom/base/test/test_link_prefetch.html b/dom/base/test/test_link_prefetch.html new file mode 100644 index 0000000000..c13492fd10 --- /dev/null +++ b/dom/base/test/test_link_prefetch.html @@ -0,0 +1,220 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test link policy attribute for Bug 1264165</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that link referrer attributes are honoured correctly + https://bugzilla.mozilla.org/show_bug.cgi?id=1264165 + --> + + <script type="application/javascript;version=1.8"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL", "SCHEME_FROM", "SCHEME_TO"]; + + const testCases = [ + {ACTION: ["generate-link-policy-test"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'prefetch-unsafe-url-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'prefetch', + DESC: "prefetch-unsafe-url with origin in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin', + NAME: 'prefetch-origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + REL: 'prefetch', + DESC: "prefetch-origin with unsafe-url in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'prefetch-no-referrer-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'prefetch', + DESC: "prefetch-no-referrer with origin in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'prefetch-same-origin-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'prefetch', + DESC: "prefetch-same-origin with origin in meta", + RESULT: 'full'}, + {NAME: 'prefetch-no-referrer-in-meta', + META_POLICY: 'no-referrer', + REL: 'prefetch', + DESC: "prefetch-no-referrer in meta", + RESULT: 'none'}, + + // Downgrade. + {ATTRIBUTE_POLICY: 'no-referrer-when-downgrade', + NAME: 'prefetch-origin-in-meta-downgrade-in-attr', + META_POLICY: 'origin', + DESC: 'prefetch-origin in meta downgrade in attr', + REL: 'prefetch', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'prefetch-origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'prefetch-origin in meta strict-origin in attr', + REL: 'prefetch', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'prefetch-origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'prefetch-origin in meta strict-origin-when-cross-origin in attr', + REL: 'prefetch', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + + // No downgrade. + {ATTRIBUTE_POLICY: 'no-referrer-when-downgrade', + NAME: 'prefetch-origin-in-meta-downgrade-in-attr', + META_POLICY: 'origin', + DESC: 'prefetch-origin in meta downgrade in attr', + REL: 'prefetch', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'full'}, + + {ATTRIBUTE_POLICY: 'origin', + NAME: 'prefetch-origin-with-no-meta', + META_POLICY: '', + REL: 'prefetch', + DESC: "prefetch-origin with no meta", + RESULT: 'origin'}, + + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'prefetch-origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'prefetch-origin in meta strict-origin in attr', + REL: 'prefetch', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'prefetch-origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'prefetch-origin in meta strict-origin-when-cross-origin in attr', + REL: 'prefetch', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'full'}, + + // Cross origin + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'prefetch-origin-when-cross-origin-with-no-meta', + META_POLICY: '', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'prefetch', + DESC: "prefetch-origin-when-cross-origin with no meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'prefetch-origin-when-cross-origin-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'prefetch', + DESC: "prefetch-origin-when-cross-origin with no-referrer in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'prefetch-origin-when-cross-origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'prefetch', + DESC: "prefetch-origin-when-cross-origin with unsafe-url in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'prefetch-origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'prefetch', + DESC: "prefetch-origin-when-cross-origin with origin in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'prefetch-strict-origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + REL: 'prefetch', + DESC: "prefetch-strict-origin-when-cross-origin with origin in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'prefetch-same-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + REL: 'prefetch', + DESC: "prefetch-same-origin with origin in meta", + RESULT: 'none'}, + + // Invalid + {ATTRIBUTE_POLICY: 'default', + NAME: 'prefetch-default-with-no-meta', + META_POLICY: '', + REL: 'prefetch', + DESC: "prefetch-default with no meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'something', + NAME: 'prefetch-something-with-no-meta', + META_POLICY: '', + REL: 'prefetch', + DESC: "prefetch-something with no meta", + RESULT: 'full'}, + ]}, + + {ACTION: ["generate-link-policy-test-set-attribute"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NEW_ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'prefetch-no-referrer-unsafe-url-set-attribute-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'prefetch', + DESC: "prefetch-no-referrer-set-attribute (orginally unsafe-url) with origin in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'origin', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'prefetch-unsafe-url-origin-set-attribute-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + REL: 'prefetch', + DESC: "prefetch-unsafe-url-set-attribute(orginally origin) with no-referrer in meta", + RESULT: 'full'}, + ]}, + + {ACTION: ["generate-link-policy-test-property"], + TESTS: [ + {ATTRIBUTE_POLICY: 'no-referrer', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'prefetch-unsafe-url-no-referrer-property-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'prefetch', + DESC: "prefetch-unsafe-url-property (orginally no-referrer) with origin in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'prefetch-unsafe-url-origin-property-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + REL: 'prefetch', + DESC: "prefetch-unsafe-url-property (orginally origin) with no-referrer in meta", + RESULT: 'full'}, + ]}, + ]; + + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> diff --git a/dom/base/test/test_link_stylesheet.html b/dom/base/test/test_link_stylesheet.html new file mode 100644 index 0000000000..58f70668af --- /dev/null +++ b/dom/base/test/test_link_stylesheet.html @@ -0,0 +1,221 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test link policy attribute for Bug 1264165</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing that link referrer attributes are honoured correctly + https://bugzilla.mozilla.org/show_bug.cgi?id=1264165 + --> + + <script type="application/javascript;version=1.8"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY", "REL", "SCHEME_FROM", "SCHEME_TO"]; + + const testCases = [ + {ACTION: ["generate-link-policy-test"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'stylesheet-unsafe-url-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'stylesheet', + DESC: "stylesheet-unsafe-url with origin in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin', + NAME: 'stylesheet-origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + REL: 'stylesheet', + DESC: "stylesheet-origin with unsafe-url in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'stylesheet-no-referrer-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'stylesheet', + DESC: "stylesheet-no-referrer with origin in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'stylesheet-same-origin-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'stylesheet', + DESC: "stylesheet-same-origin with origin in meta", + RESULT: 'full'}, + {NAME: 'stylesheet-no-referrer-in-meta', + META_POLICY: 'no-referrer', + REL: 'stylesheet', + DESC: "stylesheet-no-referrer in meta", + RESULT: 'none'}, + + // Downgrade. + {ATTRIBUTE_POLICY: 'no-referrer-when-downgrade', + NAME: 'stylesheet-origin-in-meta-downgrade-in-attr', + META_POLICY: 'origin', + DESC: 'stylesheet-origin in meta downgrade in attr', + REL: 'stylesheet', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'stylesheet-origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'stylesheet-origin in meta strict-origin in attr', + REL: 'stylesheet', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'stylesheet-origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'stylesheet-origin in meta strict-origin-when-cross-origin in attr', + REL: 'stylesheet', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + RESULT: 'none'}, + + // No downgrade. + {ATTRIBUTE_POLICY: 'no-referrer-when-downgrade', + NAME: 'stylesheet-origin-in-meta-downgrade-in-attr', + META_POLICY: 'origin', + DESC: 'stylesheet-origin in meta downgrade in attr', + REL: 'stylesheet', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'full'}, + + {ATTRIBUTE_POLICY: 'origin', + NAME: 'stylesheet-origin-with-no-meta', + META_POLICY: '', + REL: 'stylesheet', + DESC: "stylesheet-origin with no meta", + RESULT: 'origin'}, + + {ATTRIBUTE_POLICY: 'strict-origin', + NAME: 'stylesheet-origin-in-meta-strict-origin-in-attr', + META_POLICY: 'origin', + DESC: 'stylesheet-origin in meta strict-origin in attr', + REL: 'stylesheet', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'stylesheet-origin-in-meta-strict-origin-when-cross-origin-in-attr', + META_POLICY: 'origin', + DESC: 'stylesheet-origin in meta strict-origin-when-cross-origin in attr', + REL: 'stylesheet', + SCHEME_FROM: 'https', + SCHEME_TO: 'https', + RESULT: 'full'}, + + // Cross origin + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'stylesheet-origin-when-cross-origin-with-no-meta', + META_POLICY: '', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'stylesheet', + DESC: "stylesheet-origin-when-cross-origin with no meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'stylesheet-origin-when-cross-origin-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'stylesheet', + DESC: "stylesheet-origin-when-cross-origin with no-referrer in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'stylesheet-origin-when-cross-origin-with-unsafe-url-in-meta', + META_POLICY: 'unsafe-url', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'stylesheet', + DESC: "stylesheet-origin-when-cross-origin with unsafe-url in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'origin-when-cross-origin', + NAME: 'stylesheet-origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'https', + SCHEME_TO: 'http', + REL: 'stylesheet', + DESC: "stylesheet-origin-when-cross-origin with origin in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'strict-origin-when-cross-origin', + NAME: 'stylesheet-strict-origin-when-cross-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + REL: 'stylesheet', + DESC: "stylesheet-strict-origin-when-cross-origin with origin in meta", + RESULT: 'origin'}, + {ATTRIBUTE_POLICY: 'same-origin', + NAME: 'stylesheet-same-origin-with-origin-in-meta', + META_POLICY: 'origin', + SCHEME_FROM: 'http', + SCHEME_TO: 'https', + REL: 'stylesheet', + DESC: "stylesheet-same-origin with origin in meta", + RESULT: 'none'}, + + // Invalid + {ATTRIBUTE_POLICY: 'default', + NAME: 'stylesheet-default-with-no-meta', + META_POLICY: '', + REL: 'stylesheet', + DESC: "stylesheet-default with no meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'something', + NAME: 'stylesheet-something-with-no-meta', + META_POLICY: '', + REL: 'stylesheet', + DESC: "stylesheet-something with no meta", + RESULT: 'full'}, + ]}, + + {ACTION: ["generate-link-policy-test-set-attribute"], + TESTS: [ + {ATTRIBUTE_POLICY: 'unsafe-url', + NEW_ATTRIBUTE_POLICY: 'no-referrer', + NAME: 'stylesheet-no-referrer-unsafe-url-set-attribute-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'stylesheet', + DESC: "stylesheet-no-referrer-set-attribute (orginally unsafe-url) with origin in meta", + RESULT: 'none'}, + {ATTRIBUTE_POLICY: 'origin', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'stylesheet-unsafe-url-origin-set-attribute-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + REL: 'stylesheet', + DESC: "stylesheet-unsafe-url-set-attribute (orginally origin) with no-referrer in meta", + RESULT: 'full'}, + ]}, + + {ACTION: ["generate-link-policy-test-property"], + TESTS: [ + {ATTRIBUTE_POLICY: 'no-referrer', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'stylesheet-unsafe-url-no-referrer-property-with-origin-in-meta', + META_POLICY: 'origin', + REL: 'stylesheet', + DESC: "stylesheet-unsafe-url-property (orginally no-referrer) with origin in meta", + RESULT: 'full'}, + {ATTRIBUTE_POLICY: 'origin', + NEW_ATTRIBUTE_POLICY: 'unsafe-url', + NAME: 'stylesheet-unsafe-url-origin-property-with-no-referrer-in-meta', + META_POLICY: 'no-referrer', + REL: 'stylesheet', + DESC: "stylesheet-unsafe-url-property (orginally origin) with no-referrer in meta", + RESULT: 'full'}, + ]}, + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> + + diff --git a/dom/base/test/test_messagePort.html b/dom/base/test/test_messagePort.html new file mode 100644 index 0000000000..6f37e683eb --- /dev/null +++ b/dom/base/test/test_messagePort.html @@ -0,0 +1,115 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=912456 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 912456 - port cloning</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=912456">Mozilla Bug 912456</a> +<script type="application/javascript"> + + function testTransfer() { + var a = new MessageChannel(); + ok(a, "MessageChannel created"); + + window.addEventListener('message', receiveMessage, false); + function receiveMessage(evt) { + ok(evt.data.port, "Port has been received!"); + + var a = new MessageChannel(); + ok(a, "MessageChannel created"); + + try { + evt.data.port.postMessage({port: a.port2}); + ok(false, "PostMessage should throw! - no transfered port"); + } catch(e) { + ok(true, "PostMessage should throw! - no transfered port"); + } + + try { + evt.data.port.postMessage({port: a.port2}, [a.port2, a.port2]); + ok(false, "PostMessage should throw - no duplicate!"); + } catch(e) { + ok(true, "PostMessage should throw - no duplicate!"); + } + + evt.data.port.postMessage({port: a.port2}, [a.port2]); + } + + a.port1.onmessage = function(evt) { + ok(evt.data.port, "Port has been received!"); + window.removeEventListener('message', receiveMessage); + runTest(); + } + + try { + postMessage({ port: a.port2}, 42, '*'); + ok(false, "PostMessage should throw! - no transfered port"); + } catch(e) { + ok(true, "PostMessage should throw! - no transfered port"); + } + + try { + postMessage({ port: a.port2}, 42, '*', [a.port2, a.port2]); + ok(false, "PostMessage should throw - no duplicate!"); + } catch(e) { + ok(true, "PostMessage should throw - no duplicate!"); + } + + postMessage({port: a.port2}, '*', [a.port2]); + } + + function testPorts() { + var a = new MessageChannel(); + ok(a, "MessageChannel created"); + + window.addEventListener('message', receiveMessage, false); + function receiveMessage(evt) { + ok(evt.data, "Data is 42"); + ok(evt.ports, "Port is received"); + is(evt.ports.length, 1, "Ports.length is 1"); + + var a = new MessageChannel(); + ok(a, "MessageChannel created"); + + evt.ports[0].postMessage(42, [a.port2]); + } + + a.port1.onmessage = function(evt) { + ok(evt.data, "Data is 42"); + ok(evt.ports, "Port is received"); + is(evt.ports.length, 1, "Ports.length is 1"); + window.removeEventListener('message', receiveMessage); + runTest(); + } + + postMessage(42, '*', [a.port2]); + } + + var tests = [ + testTransfer, + testPorts + ]; + + function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); + } + + SimpleTest.waitForExplicitFinish(); + runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_messagemanager_principal.html b/dom/base/test/test_messagemanager_principal.html new file mode 100644 index 0000000000..cd5528e67d --- /dev/null +++ b/dom/base/test/test_messagemanager_principal.html @@ -0,0 +1,95 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Principal in MessageManager</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +</head> +<body> + + <script type="application/javascript;version=1.7"> + "use strict"; + + const Ci = Components.interfaces; + const Cc = Components.classes; + const Cu = Components.utils; + + var permManager = Cc["@mozilla.org/permissionmanager;1"] + .getService(Ci.nsIPermissionManager); + + SimpleTest.waitForExplicitFinish(); + + const childFrameURL = + "data:text/html,<!DOCTYPE HTML><html><body></body></html>"; + + function childFrameScript() { + "use strict"; + + addMessageListener("test:ipcMessage", function(message) { + sendAsyncMessage(message.name, "principal: " + (message.principal ? "OK" : "KO")); + + sendAsyncMessage(message.name, "principal.appId: " + + ("appId" in message.principal ? "OK" : "KO")); + + sendAsyncMessage(message.name, "principal.origin: " + + ("origin" in message.principal ? "OK" : "KO")); + + sendAsyncMessage(message.name, "principal.isInIsolatedMozBrowserElement: " + + ("isInIsolatedMozBrowserElement" in message.principal ? "OK" : "KO")); + + sendAsyncMessage(message.name, "DONE"); + }); + } + + function runTests() { + ok("Browser prefs set."); + + let iframe = document.createElement("iframe"); + SpecialPowers.wrap(iframe).mozbrowser = true; + iframe.id = "iframe"; + iframe.src = childFrameURL; + + iframe.addEventListener("mozbrowserloadend", function() { + ok(true, "Got iframe load event."); + + let mm = SpecialPowers.getBrowserFrameMessageManager(iframe); + mm.addMessageListener("test:ipcMessage", function(message) { + // We need to wrap to access message.json, and unwrap to do the + // identity check. + var msg = SpecialPowers.unwrap(SpecialPowers.wrap(message).json); + if (/OK$/.exec(msg)) { + ok(true, msg); + } else if(/KO$/.exec(msg)) { + ok(true, false); + } else if (/DONE/.exec(msg)) { + permManager.removeFromPrincipal(window.document.nodePrincipal, "browser", + Ci.nsIPermissionManager.ALLOW_ACTION); + SimpleTest.finish(); + } + }); + mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();", + false); + + mm.sendAsyncMessage("test:ipcMessage", 42, null, window.document.nodePrincipal); + }); + + document.body.appendChild(iframe); + } + + addEventListener("load", function() { + info("Got load event."); + + permManager.addFromPrincipal(window.document.nodePrincipal, "browser", + Ci.nsIPermissionManager.ALLOW_ACTION); + + SpecialPowers.pushPrefEnv({ + "set": [ + ["dom.mozBrowserFramesEnabled", true], + ["network.disable.ipc.security", true], + ["browser.pagethumbnails.capturing_disabled", true] + ] + }, runTests); + }); + </script> +</body> +</html> diff --git a/dom/base/test/test_messagemanager_send_principal.html b/dom/base/test/test_messagemanager_send_principal.html new file mode 100644 index 0000000000..c50cdfeb30 --- /dev/null +++ b/dom/base/test/test_messagemanager_send_principal.html @@ -0,0 +1,131 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Principal in MessageManager</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +</head> +<body> + + <script type="application/javascript;version=1.7"> + "use strict"; + + const Ci = Components.interfaces; + const Cc = Components.classes; + const Cu = Components.utils; + + var permManager = Cc["@mozilla.org/permissionmanager;1"] + .getService(Ci.nsIPermissionManager); + + SimpleTest.waitForExplicitFinish(); + + const childFrameURL = + "data:text/html,<!DOCTYPE HTML><html><body></body></html>"; + + function childFrameScript() { + "use strict"; + + const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]. + getService(Ci.nsIScriptSecurityManager); + + addMessageListener("test:content", function(message) { + sendAsyncMessage("test:result", "is nsIPrincipal: " + + (message.data instanceof Ci.nsIPrincipal ? "OK" : "KO")); + + sendAsyncMessage("test:result", "principal.appId: " + + ("appId" in message.data ? "OK" : "KO")); + + sendAsyncMessage("test:result", "principal.origin: " + + ("origin" in message.data ? "OK" : "KO")); + + sendAsyncMessage("test:result", "principal.isInIsolatedMozBrowserElement: " + + ("isInIsolatedMozBrowserElement" in message.data ? "OK" : "KO")); + }); + + addMessageListener("test:system", function(message) { + sendAsyncMessage("test:result", "isSystemPrincipal: " + + (secMan.isSystemPrincipal(message.data) ? "OK" : "KO")); + }); + + addMessageListener("test:ep", function(message) { + sendAsyncMessage("test:result", "expanded principal: " + + (message.data.isExpandedPrincipal ? "OK" : "KO")); + sendAsyncMessage("test:result", "correct origin: " + + (message.data.origin == "[Expanded Principal [http://bar.example.com, http://foo.example.com]]" ? "OK" : "KO")); + }); + + addMessageListener("test:null", function(message) { + sendAsyncMessage("test:result", "is nsIPrincipal: " + + (message.data instanceof Ci.nsIPrincipal ? "OK" : "KO")); + + sendAsyncMessage("test:result", "isNullPrincipal: " + + (message.data.isNullPrincipal ? "OK" : "KO")); + sendAsyncMessage("test:result", "DONE"); + }); + } + + function runTests() { + ok("Browser prefs set."); + + let iframe = document.createElement("iframe"); + SpecialPowers.wrap(iframe).mozbrowser = true; + iframe.id = "iframe"; + iframe.src = childFrameURL; + + let sb = new Cu.Sandbox(['http://foo.example.com', 'http://bar.example.com']); + let ep = Components.utils.getObjectPrincipal(sb); + + iframe.addEventListener("mozbrowserloadend", function() { + ok(true, "Got iframe load event."); + + let mm = SpecialPowers.getBrowserFrameMessageManager(iframe); + mm.addMessageListener("test:result", function(message) { + // We need to wrap to access message.json, and unwrap to do the + // identity check. + var msg = SpecialPowers.unwrap(SpecialPowers.wrap(message).data); + if (/OK$/.exec(msg)) { + ok(true, msg); + } else if(/KO$/.exec(msg)) { + ok(true, false); + } else if (/DONE/.exec(msg)) { + permManager.removeFromPrincipal(window.document.nodePrincipal, "browser", + Ci.nsIPermissionManager.ALLOW_ACTION); + SimpleTest.finish(); + } + }); + mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();", + false); + + mm.sendAsyncMessage("test:content", window.document.nodePrincipal); + + let system = Cc["@mozilla.org/systemprincipal;1"]. + createInstance(Ci.nsIPrincipal); + mm.sendAsyncMessage("test:system", system); + + mm.sendAsyncMessage("test:ep", ep); + + let nullP = Cc["@mozilla.org/nullprincipal;1"]. + createInstance(Ci.nsIPrincipal); + mm.sendAsyncMessage("test:null", nullP); + }); + + document.body.appendChild(iframe); + } + + addEventListener("load", function() { + info("Got load event."); + + permManager.addFromPrincipal(window.document.nodePrincipal, "browser", + Ci.nsIPermissionManager.ALLOW_ACTION); + + SpecialPowers.pushPrefEnv({ + "set": [ + ["dom.mozBrowserFramesEnabled", true], + ["network.disable.ipc.security", true], + ["browser.pagethumbnails.capturing_disabled", true] + ] + }, runTests); + }); + </script> +</body> +</html> diff --git a/dom/base/test/test_messagemanager_targetchain.html b/dom/base/test/test_messagemanager_targetchain.html new file mode 100644 index 0000000000..3f3f8f60fb --- /dev/null +++ b/dom/base/test/test_messagemanager_targetchain.html @@ -0,0 +1,126 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for EventTarget chain of MessageManagers</title> + <script type="application/javascript" + src="/tests/SimpleTest/SimpleTest.js"> + </script> + <script type="application/javascript" + src="/tests/SimpleTest/EventUtils.js"> + </script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + const browserFrameURL = "file_empty.html"; + const contentFrameURL = + "data:text/html,<!DOCTYPE HTML><html><body><button id=\"target\">target</button></body></html>"; + + function frameScript() { + "use strict"; + addEventListener("test-event", function (e) { + sendSyncMessage("test-event"); + }, true); + } + + function runTests() { + // messageIndex is incremented for each message/event received + let messageIndex = 0; + + let iframe = document.createElement("iframe"); + iframe.setAttribute("mozbrowser", true); + iframe.setAttribute("src", browserFrameURL); + + iframe.addEventListener("mozbrowserloadend", function () { + info("First iframe loaded"); + // First message manager + let mm = SpecialPowers.getBrowserFrameMessageManager(iframe); + mm.addMessageListener("test-event", function onEvent(message) { + is(messageIndex, 0, + "first mm should be the first one to receive the test event"); + messageIndex++; + }); + mm.loadFrameScript("data:,(" + frameScript.toString() + ")();", false); + + // Document in the middle + let doc1 = SpecialPowers.wrap(iframe).contentDocument; + doc1.addEventListener("test-event", function (e) { + ok(false, "content document shouldn't receive test event from child"); + }, true); + + let iframe2 = doc1.createElement("iframe"); + iframe2.setAttribute("mozbrowser", true); + iframe2.setAttribute("src", browserFrameURL); + + iframe2.addEventListener("mozbrowserloadend", function () { + info("Second iframe loaded"); + // Second message manager + let mm2 = SpecialPowers.getBrowserFrameMessageManager(iframe2); + mm2.addMessageListener("test-event", function onEvent(message) { + is(messageIndex, 1, + "second mm should be the second one to receive the test event"); + messageIndex++; + }); + mm2.loadFrameScript("data:,(" + frameScript.toString() +")();", false); + + // Third is the regular iframe + let doc2 = SpecialPowers.wrap(iframe2).contentDocument; + let iframe3 = doc2.createElement("iframe"); + iframe3.setAttribute("src", contentFrameURL); + + iframe3.addEventListener("load", function (e) { + info("Third iframe loaded"); + let doc3 = SpecialPowers.wrap(iframe3).contentDocument; + let target = doc3.getElementById("target"); + target.addEventListener("test-event", function onEvent(e) { + is(messageIndex, 2, + "target should be the last one to receive the test event"); + messageIndex++; + SimpleTest.finish(); + }); + + // Fire test event after load + SimpleTest.executeSoon(function () { + var event = new Event("test-event"); + SpecialPowers.dispatchEvent(iframe3.contentWindow, target, event); + }); + }); + doc2.body.appendChild(iframe3); + }); + doc1.body.appendChild(iframe2); + }); + document.addEventListener("test-event", function (e) { + ok(false, "top document shouldn't receive test event from child"); + }, true); + document.body.appendChild(iframe); + } + + addEventListener("load", function() { + var principal = SpecialPowers.wrap(document).nodePrincipal; + SpecialPowers.pushPermissions([ + { type: "browser", allow: 1, context: { url: principal.URI.spec, + originAttributes: { + appId: principal.appId + }}}, + { type: "browser", allow: 1, context: { url: principal.URI.spec, + originAttributes: { + appId: principal.appId, + inIsolatedMozBrowser: true }}} + ], () => { + SpecialPowers.pushPrefEnv({ + set: [ + ["dom.mozBrowserFramesEnabled", true], + ["network.disable.ipc.security", true], + ["dom.ipc.browser_frames.oop_by_default", false], + ] + }, runTests); + }); + }); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport0.html b/dom/base/test/test_meta_viewport0.html new file mode 100644 index 0000000000..0e0d8991cc --- /dev/null +++ b/dom/base/test/test_meta_viewport0.html @@ -0,0 +1,81 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>No <meta name="viewport"> tag</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + function fuzzeq(a, b, msg) { + ok(Math.abs(a - b) < 1e-6, msg); + } + + tests.push(function test1() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + let info = getViewportInfo(800, 480); + fuzzeq(info.defaultZoom, 0.1, "initial scale is unspecified"); + fuzzeq(info.minZoom, 0.1, "minimum scale defaults to the absolute minimum"); + is(info.maxZoom, 10, "maximum scale defaults to the absolute maximum"); + is(info.width, 980, "width is the default width"); + is(info.height, 588, "height is proportional to displayHeight"); + is(info.autoSize, false, "autoSize is disabled by default"); + is(info.allowZoom, true, "zooming is enabled by default"); + + info = getViewportInfo(490, 600); + is(info.width, 980, "width is still the default width"); + is(info.height, 1200, "height is proportional to the new displayHeight"); + + nextTest(); + }); + }); + + tests.push(function test2() { + SpecialPowers.pushPrefEnv(scaleRatio(1.5), + function() { + let info = getViewportInfo(800, 480); + is(info.width, 980, "width is still the default width"); + is(info.height, 588, "height is still proportional to displayHeight"); + + nextTest(); + }); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function nextTest() { + if (tests.length) + (tests.shift())(); + else + SimpleTest.finish(); + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport1.html b/dom/base/test/test_meta_viewport1.html new file mode 100644 index 0000000000..678931d4ec --- /dev/null +++ b/dom/base/test/test_meta_viewport1.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>width=device-width, initial-scale=1</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + tests.push(function test1() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + let info = getViewportInfo(800, 480); + is(info.defaultZoom, 1, "initial zoom is 100%"); + is(info.width, 800, "width is the same as the displayWidth"); + is(info.height, 480, "height is the same as the displayHeight"); + is(info.autoSize, true, "width=device-width enables autoSize"); + is(info.allowZoom, true, "zooming is enabled by default"); + + info = getViewportInfo(900, 600); + is(info.width, 900, "changing the displayWidth changes the width"); + is(info.height, 600, "changing the displayHeight changes the height"); + + nextTest(); + }); + }); + + tests.push(function test2() { + SpecialPowers.pushPrefEnv(scaleRatio(1.5), + function() { + let info = getViewportInfo(900, 600); + is(info.defaultZoom, 1.5, "initial zoom is 150%"); + is(info.width, 600, "width equals displayWidth/1.5"); + is(info.height, 400, "height equals displayHeight/1.5"); + + nextTest(); + }); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function nextTest() { + if (tests.length) + (tests.shift())(); + else + SimpleTest.finish(); + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport2.html b/dom/base/test/test_meta_viewport2.html new file mode 100644 index 0000000000..c31d1909e8 --- /dev/null +++ b/dom/base/test/test_meta_viewport2.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta name="viewport" content="width=device-width"> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>width=device-width</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + tests.push(function test1() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + let info = getViewportInfo(800, 480); + is(info.defaultZoom, 1, "initial zoom is 100%"); + is(info.width, 800, "width is the same as the displayWidth"); + is(info.height, 480, "height is the same as the displayHeight"); + is(info.autoSize, true, "width=device-width enables autoSize"); + is(info.allowZoom, true, "zooming is enabled by default"); + + info = getViewportInfo(900, 600); + is(info.width, 900, "changing the displayWidth changes the width"); + is(info.height, 600, "changing the displayHeight changes the height"); + + nextTest(); + }); + }); + + tests.push(function test2() { + SpecialPowers.pushPrefEnv(scaleRatio(1.5), + function() { + let info = getViewportInfo(900, 600); + is(info.defaultZoom, 1.5, "initial zoom is 150%"); + is(info.width, 600, "width equals displayWidth/1.5"); + is(info.height, 400, "height equals displayHeight/1.5"); + + nextTest(); + }); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function nextTest() { + if (tests.length) + (tests.shift())(); + else + SimpleTest.finish(); + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport3.html b/dom/base/test/test_meta_viewport3.html new file mode 100644 index 0000000000..cf1153d497 --- /dev/null +++ b/dom/base/test/test_meta_viewport3.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta name="viewport" content="width=320"> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>width=320</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + tests.push(function test1() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + let info = getViewportInfo(800, 80); + is(info.defaultZoom, 2.5, "initial zoom fits the displayWidth"); + is(info.width, 320, "width is set explicitly"); + is(info.height, 40, "height is at the absolute minimum"); + is(info.autoSize, false, "width=device-width enables autoSize"); + is(info.allowZoom, true, "zooming is enabled by default"); + + info = getViewportInfo(480, 800); + is(info.defaultZoom, 1.5, "initial zoom fits the new displayWidth"); + is(info.width, 320, "explicit width is unchanged"); + is(info.height, 533, "height changes proportional to displayHeight"); + + nextTest(); + }); + }); + + tests.push(function test2() { + SpecialPowers.pushPrefEnv(scaleRatio(1.5), + function() { + // With an explicit width in CSS px, the scaleRatio has no effect. + let info = getViewportInfo(800, 80); + is(info.defaultZoom, 2.5, "initial zoom still fits the displayWidth"); + is(info.width, 320, "width is still set explicitly"); + is(info.height, 40, "height is still minimum height"); + + nextTest(); + }); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function nextTest() { + if (tests.length) + (tests.shift())(); + else + SimpleTest.finish(); + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport4.html b/dom/base/test/test_meta_viewport4.html new file mode 100644 index 0000000000..9e53419ae2 --- /dev/null +++ b/dom/base/test/test_meta_viewport4.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>initial-scale=1.0, user-scalable=no</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + tests.push(function test1() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + let info = getViewportInfo(800, 480); + is(info.defaultZoom, 1, "initial zoom is set explicitly"); + is(info.width, 800, "width fits the initial zoom level"); + is(info.height, 480, "height fits the initial zoom level"); + is(info.autoSize, true, "initial-scale=1 enables autoSize"); + is(info.allowZoom, false, "zooming is explicitly disabled"); + + info = getViewportInfo(480, 800); + is(info.defaultZoom, 1, "initial zoom is still set explicitly"); + is(info.width, 480, "width changes to match the displayWidth"); + is(info.height, 800, "height changes to match the displayHeight"); + + nextTest(); + }); + }); + + tests.push(function test2() { + SpecialPowers.pushPrefEnv(scaleRatio(1.5), + function() { + let info = getViewportInfo(800, 480); + is(info.defaultZoom, 1.5, "initial zoom is adjusted for device pixel ratio"); + is(info.width, 533, "width fits the initial zoom"); + is(info.height, 320, "height fits the initial zoom"); + + nextTest(); + }); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function nextTest() { + if (tests.length) + (tests.shift())(); + else + SimpleTest.finish(); + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport5.html b/dom/base/test/test_meta_viewport5.html new file mode 100644 index 0000000000..739e5b7fe6 --- /dev/null +++ b/dom/base/test/test_meta_viewport5.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta name="viewport" content="user-scalable=NO"> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>user-scalable=NO</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + tests.push(function test1() { + let info = getViewportInfo(800, 480); + is(info.allowZoom, true, "user-scalable values are case-sensitive; 'NO' is not valid"); + + nextTest(); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function nextTest() { + if (tests.length) + (tests.shift())(); + else + SimpleTest.finish(); + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport6.html b/dom/base/test/test_meta_viewport6.html new file mode 100644 index 0000000000..b003ed2c01 --- /dev/null +++ b/dom/base/test/test_meta_viewport6.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta name="viewport" content="width=2000, minimum-scale=0.75"> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>width=2000, minimum-scale=0.75</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + tests.push(function test1() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + let info = getViewportInfo(800, 480); + is(info.minZoom, 0.75, "minumum scale is set explicitly"); + is(info.defaultZoom, 0.75, "initial scale is bounded by the minimum scale"); + is(info.maxZoom, 10, "maximum scale defaults to the absolute maximum"); + is(info.width, 2000, "width is set explicitly"); + is(info.height, 1200, "height is proportional to displayHeight"); + is(info.autoSize, false, "autoSize is disabled by default"); + is(info.allowZoom, true, "zooming is enabled by default"); + + info = getViewportInfo(2000, 1000); + is(info.minZoom, 0.75, "minumum scale is still set explicitly"); + is(info.defaultZoom, 1, "initial scale fits the width"); + is(info.width, 2000, "width is set explicitly"); + is(info.height, 1000, "height is proportional to the new displayHeight"); + + nextTest(); + }); + }); + + tests.push(function test2() { + SpecialPowers.pushPrefEnv(scaleRatio(1.5), + function() { + let info = getViewportInfo(800, 480); + is(info.minZoom, 1.125, "minumum scale is converted to device pixel scale"); + is(info.defaultZoom, 1.125, "initial scale is bounded by the minimum scale"); + is(info.maxZoom, 15, "maximum scale defaults to the absolute maximum"); + is(info.width, 2000, "width is still set explicitly"); + is(info.height, 1200, "height is still proportional to displayHeight"); + + nextTest(); + }); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function nextTest() { + if (tests.length) + (tests.shift())(); + else + SimpleTest.finish(); + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_meta_viewport7.html b/dom/base/test/test_meta_viewport7.html new file mode 100644 index 0000000000..373674c536 --- /dev/null +++ b/dom/base/test/test_meta_viewport7.html @@ -0,0 +1,114 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>meta viewport test</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <meta name="viewport" content="width=320"> + <script src="viewport_helpers.js"></script> +</head> +<body> + <p>Dynamic viewport updates</p> + <script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + let tests = []; + + tests.push(function test1() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + updateViewport("width=device-width"); + let info = getViewportInfo(800, 480); + is(info.defaultZoom, 1, "initial zoom is 100%"); + is(info.width, 800, "width is the same as the displayWidth"); + is(info.height, 480, "height is the same as the displayHeight"); + is(info.autoSize, true, "width=device-width enables autoSize"); + is(info.allowZoom, true, "zooming is enabled by default"); + + info = getViewportInfo(900, 600); + is(info.width, 900, "changing the displayWidth changes the width"); + is(info.height, 600, "changing the displayHeight changes the height"); + + nextTest(); + }); + }); + + tests.push(function test2() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + updateViewport("width=320"); + let info = getViewportInfo(800, 80); + is(info.defaultZoom, 2.5, "initial zoom fits the displayWidth"); + is(info.width, 320, "width is set explicitly"); + is(info.height, 40, "height is at the absolute minimum"); + is(info.autoSize, false, "width=device-width enables autoSize"); + is(info.allowZoom, true, "zooming is enabled by default"); + + info = getViewportInfo(480, 800); + is(info.defaultZoom, 1.5, "initial zoom fits the new displayWidth"); + is(info.width, 320, "explicit width is unchanged"); + is(info.height, 533, "height changes proportional to displayHeight"); + + nextTest(); + }); + }); + + tests.push(function test3() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + updateViewport("user-scalable=no"); + let info = getViewportInfo(800, 480); + is(info.allowZoom, false, "zooming is explicitly disabled"); + + nextTest(); + }); + }); + + tests.push(function test4() { + SpecialPowers.pushPrefEnv(scaleRatio(1.0), + function() { + updateViewport("user-scalable=yes"); + let info = getViewportInfo(800, 480); + is(info.allowZoom, true, "zooming is explicitly allowed"); + + nextTest(); + }); + }); + + function getViewportInfo(aDisplayWidth, aDisplayHeight) { + let defaultZoom = {}, allowZoom = {}, minZoom = {}, maxZoom = {}, + width = {}, height = {}, autoSize = {}; + + let cwu = SpecialPowers.getDOMWindowUtils(window); + cwu.getViewportInfo(aDisplayWidth, aDisplayHeight, defaultZoom, allowZoom, + minZoom, maxZoom, width, height, autoSize); + return { + defaultZoom: defaultZoom.value, + minZoom: minZoom.value, + maxZoom: maxZoom.value, + width: width.value, + height: height.value, + autoSize: autoSize.value, + allowZoom: allowZoom.value + }; + } + + function updateViewport(content) { + let meta = document.querySelector("meta[name=viewport]"); + meta.content = content; + } + + function nextTest() { + if (tests.length) { + (tests.shift())(); + } else { + SimpleTest.finish(); + } + } + addEventListener("load", nextTest); + </script> +</body> +</html> diff --git a/dom/base/test/test_mozMatchesSelector.html b/dom/base/test/test_mozMatchesSelector.html new file mode 100644 index 0000000000..3f163e07a9 --- /dev/null +++ b/dom/base/test/test_mozMatchesSelector.html @@ -0,0 +1,14 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test for legacy mozMatchesSelector</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div id=log></div> +<div id=test></div> +<script> +test(function() { + var element = document.getElementById("test"); + assert_true(element.matches("#test"), "matches"); + assert_true(element.mozMatchesSelector("#test"), "mozMatchesSelector"); +}); +</script> diff --git a/dom/base/test/test_mozbrowser_apis_allowed.html b/dom/base/test/test_mozbrowser_apis_allowed.html new file mode 100644 index 0000000000..86ff3e2ffd --- /dev/null +++ b/dom/base/test/test_mozbrowser_apis_allowed.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Verify mozbrowser APIs are allowed with browser permission</title> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script> + <script type="text/javascript" src="mozbrowser_api_utils.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> +</head> + +<body> +<script type="application/javascript;version=1.8"> + add_task(function*() { + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv( + { "set": [["dom.mozBrowserFramesEnabled", true], + ["network.disable.ipc.security", true]] }, + resolve); + }); + }); + + add_task(function*() { + // Create <iframe mozbrowser> + let frame = yield loadFrame({ + mozbrowser: "true", + // FIXME: Bug 1270790 + remote: true + }); + + // Verify that mozbrowser APIs are accessible + for (let method in METHODS) { + let { alwaysFails } = METHODS[method]; + if (alwaysFails) { + ok(!(method in frame), `frame does not have method ${method}, ` + + `needs more permissions`); + } else { + ok(method in frame, `frame has method ${method}`); + } + } + for (let attribute of ATTRIBUTES) { + ok(attribute in frame, `frame has attribute ${attribute}`); + } + }); +</script> +</body> +</html> diff --git a/dom/base/test/test_mozbrowser_apis_blocked.html b/dom/base/test/test_mozbrowser_apis_blocked.html new file mode 100644 index 0000000000..303c48625c --- /dev/null +++ b/dom/base/test/test_mozbrowser_apis_blocked.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Verify mozbrowser APIs are blocked without browser permission</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <script type="text/javascript" src="mozbrowser_api_utils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<script type="application/javascript;version=1.8"> + add_task(function*() { + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv( + { "set": [["dom.mozBrowserFramesEnabled", true], + ["network.disable.ipc.security", true]] }, + resolve); + }); + }); + + add_task(function*() { + // Create <iframe mozbrowser> + let frame = yield loadFrame({ + mozbrowser: "true" + }); + + // Verify that mozbrowser APIs are not accessible + for (let method in METHODS) { + ok(!(method in frame), `frame does not have method ${method}`); + } + for (let attribute of ATTRIBUTES) { + ok(!(attribute in frame), `frame does not have attribute ${attribute}`); + } + }); +</script> +</body> +</html> diff --git a/dom/base/test/test_mozfiledataurl.html b/dom/base/test/test_mozfiledataurl.html new file mode 100644 index 0000000000..b842336d8d --- /dev/null +++ b/dom/base/test/test_mozfiledataurl.html @@ -0,0 +1,225 @@ +<!DOCTYPE HTML> +<html> +<head> + <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> + <title>Test for File urls</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="start()"> +<p id="display"> +<iframe id=inner></iframe> +<iframe id=iframe></iframe> +<img id=img onload="gen.send(event);"> +<audio id=audio onloadeddata="gen.send(event);"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="application/javascript;version=1.8"> + +try { + URL.createObjectURL(undefined); +} catch(e) { } + +window.addEventListener("message", function(e) { + gen.send(JSON.parse(e.data)); +}, false); + +const innerSameSiteURI = "file_mozfiledataurl_inner.html"; +const innerCrossSiteURI = "http://example.com/tests/dom/base/test/file_mozfiledataurl_inner.html" + +var fileNames = ["file_mozfiledataurl_img.jpg", + "file_mozfiledataurl_audio.ogg", + "file_mozfiledataurl_doc.html", + "file_mozfiledataurl_text.txt"]; + +function start() { + let xhr = new XMLHttpRequest; + xhr.open("GET", "/dynamic/getMyDirectory.sjs", false); + xhr.send(); + let basePath = xhr.responseText; + + let fullFileNames = []; + for (let name of fileNames) { + fullFileNames.push(basePath + name); + } + + var script = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL("create_file_objects.js")); + + script.addMessageListener("created-file-objects", function handler(files) { + script.removeMessageListener("created-file-objects", handler); + gen = runTest(files); + gen.next(); + }); + + script.sendAsyncMessage("create-file-objects", {fileNames: fullFileNames}); +}; + +SimpleTest.waitForExplicitFinish(); + +function runTest([imgFile, audioFile, docFile, xhrFile]) { + inner = document.getElementById('inner'); + img = document.getElementById('img'); + audio = document.getElementById('audio'); + iframe = document.getElementById('iframe'); + inner.onload = function() { gen.send("inner loaded"); }; + + // Attempt to load a image in this document + var fileurl = URL.createObjectURL(imgFile); + img.src = fileurl; + var e = (yield); + is(e.type, "load", "loaded successfully"); + is(img.width, 120, "correct width"); + is(img.height, 90, "correct height"); + + // Revoke url and attempt to load a image in this document + img.src = "file_mozfiledataurl_img.jpg"; + is((yield).type, "load", "successfull reset image"); + URL.revokeObjectURL(fileurl); + todo(false, "urls need to act like 404s, not fail to parse"); +/* img.src = fileurl; + var e = (yield); + is(e.type, "error", "failed successfully"); + isnot(img.width, 120, "correct error width"); + isnot(img.height, 90, "correct error height"); +*/ + // Generate new fileurl and make sure it's different from the old + var oldFileurl = fileurl; + fileurl = URL.createObjectURL(imgFile); + isnot(fileurl, oldFileurl, "URL.createObjectURL generated the same url twice"); + + // Attempt to load an image in a different same-origin document + inner.src = innerSameSiteURI; + yield undefined; + inner.contentWindow.postMessage(JSON.stringify({img:fileurl}), "*"); + var res = (yield); + is(res.type, "load", "loaded successfully"); + is(res.width, 120, "correct width"); + is(res.height, 90, "correct height"); + + // Attempt to load an image in a different cross-origin document + inner.src = innerCrossSiteURI; + yield undefined; + inner.contentWindow.postMessage(JSON.stringify({img:fileurl}), "*"); + var res = (yield); + is(res.type, "error", "failed successfully"); + isnot(res.width, 120, "correct error width"); + isnot(res.height, 90, "correct error height"); + + // Attempt to load an audio in this document + fileurl = URL.createObjectURL(audioFile); + audio.src = fileurl; + var e = (yield); + is(e.type, "loadeddata", "loaded successfully"); + + // Revoke url and attempt to load a audio in this document + audio.src = "file_mozfiledataurl_audio.ogg"; + is((yield).type, "loadeddata", "successfully reset audio"); + URL.revokeObjectURL(fileurl); + todo(false, "urls need to act like 404s, not fail to parse"); +/* img.src = fileurl; + var e = (yield); + is(e.type, "error", "failed successfully"); + isnot(img.width, 120, "correct error width"); + isnot(img.height, 90, "correct error height"); +*/ + // Generate new fileurl and make sure it's different from the old + var oldFileurl = fileurl; + fileurl = URL.createObjectURL(audioFile); + isnot(fileurl, oldFileurl, "URL.createObjectURL generated the same url twice"); + + // Attempt to load an audio in a different same-origin document + inner.src = innerSameSiteURI; + yield undefined; + inner.contentWindow.postMessage(JSON.stringify({audio:fileurl}), "*"); + var res = (yield); + is(res.type, "loadeddata", "loaded successfully"); + + // Attempt to load an audio in a different cross-origin document + inner.src = innerCrossSiteURI; + yield undefined; + inner.contentWindow.postMessage(JSON.stringify({audio:fileurl}), "*"); + var res = (yield); + is(res.type, "error", "failed successfully"); + + // Attempt to load a HTML document in an iframe in this document + iframe.onload = function() { gen.next(); }; + iframe.src = "file_mozfiledataurl_doc.html"; + yield undefined; + is(iframe.contentDocument.getElementsByTagName("p")[0].textContent, + "This here is a document!", + "iframe loaded successfully"); + is(iframe.contentDocument.getElementById("img").width, 120, + "image in iframe width"); + is(iframe.contentDocument.getElementById("img").height, 90, + "image in iframe height"); + + // Attempt to load a HTML document in an iframe in this document, using file url + fileurl = URL.createObjectURL(docFile); + iframe.src = fileurl; + yield undefined; + is(iframe.contentDocument.getElementsByTagName("p")[0].textContent, + "This here is a document!", + "iframe loaded successfully"); + isnot(iframe.contentDocument.getElementById("img").width, 120, + "failed image in iframe width"); + isnot(iframe.contentDocument.getElementById("img").height, 90, + "failed image in iframe height"); + + // Attempt to load a HTML document in an iframe in inner document + inner.src = innerSameSiteURI; + is((yield), "inner loaded", "correct gen.next()"); + inner.contentWindow.postMessage(JSON.stringify({iframe:"file_mozfiledataurl_doc.html"}), "*"); + var res = (yield); + is(res.type, "load", "loaded successfully"); + is(res.text, "This here is a document!", "loaded successfully"); + is(res.imgWidth, 120, "correct width"); + + // Attempt to load a HTML document in an iframe in inner document, using file url + inner.contentWindow.postMessage(JSON.stringify({iframe:fileurl}), "*"); + var res = (yield); + is(res.type, "load", "loaded successfully"); + is(res.text, "This here is a document!", "loaded successfully"); + isnot(res.imgWidth, 120, "correct width"); + + // Attempt to load a HTML document in an iframe in inner cross-site document, using file url + inner.src = innerCrossSiteURI; + is((yield), "inner loaded", "correct gen.next()"); + inner.contentWindow.postMessage(JSON.stringify({iframe:fileurl}), "*"); + var res = (yield); + is(res.type, "error", "load failed successfully"); + + // Attempt to load file url using XHR + fileurl = URL.createObjectURL(xhrFile); + xhr = new XMLHttpRequest; + xhr.onload = function() { gen.send("XHR finished"); }; + xhr.open("GET", fileurl); + xhr.send(); + is((yield), "XHR finished", "correct gen.next()"); + xhr.responseText == "Yarr, here be plaintext file, ya landlubber\n"; + + // Attempt to load file url using XHR in inner document + inner.src = innerSameSiteURI; + is((yield), "inner loaded", "correct gen.next()"); + inner.contentWindow.postMessage(JSON.stringify({xhr:fileurl}), "*"); + var res = (yield); + is(res.didThrow, undefined, "load successful"); + is(res.text, "Yarr, here be plaintext file, ya landlubber\n", "load successful"); + + // Attempt to load file url using XHR + inner.src = innerCrossSiteURI; + is((yield), "inner loaded", "correct gen.next()"); + inner.contentWindow.postMessage(JSON.stringify({xhr:fileurl}), "*"); + var res = (yield); + is(res.didError, true, "load failed successfully"); + + SimpleTest.finish(); + + yield undefined; +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_mutationobserver_anonymous.html b/dom/base/test/test_mutationobserver_anonymous.html new file mode 100644 index 0000000000..98ff6e3a47 --- /dev/null +++ b/dom/base/test/test_mutationobserver_anonymous.html @@ -0,0 +1,265 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1034110 +--> +<head> + <title>Test for Bug 1034110</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1034110">Mozilla Bug 1034110</a> +<style type="text/css"> + #pseudo.before::before { content: "before"; } + #pseudo.after::after { content: "after"; } +</style> +<div id="pseudo"></div> +<video id="video"></video> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<pre id="test"> +<script type="application/javascript;version=1.7"> + +/** Test for Bug 1034110 **/ + +SimpleTest.waitForExplicitFinish(); + +function getWalker(node) { + return SpecialPowers.createDOMWalker(node, true); +} + +function getFirstChild(parent) { + return SpecialPowers.unwrap(getWalker(parent).firstChild); +} + +function getLastChild(parent) { + return SpecialPowers.unwrap(getWalker(parent).lastChild); +} + +function assertSamePseudoElement(which, node1, node2) { + is(SpecialPowers.wrap(node1).nodeName, "_moz_generated_content_" + which, + "Correct pseudo element type"); + is(node1, node2, + "Referencing the same ::after element"); +} + +window.onload = function () { + testOneAdded(); +}; + +function testOneAdded() { + let parent = document.getElementById("pseudo"); + var m = new MutationObserver(function(records, observer) { + is(records.length, 1, "Correct number of records"); + is(records[0].type, "nativeAnonymousChildList", "Correct record type"); + is(records[0].target, parent, "Correct target"); + + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent)); + is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + observer.disconnect(); + testAddedAndRemoved(); + }); + + SpecialPowers.observeMutationEvents(m, parent, true); + parent.className = "before"; +} + +function testAddedAndRemoved() { + let parent = document.getElementById("pseudo"); + let originalBeforeElement = getFirstChild(parent); + var m = new MutationObserver(function(records, observer) { + is(records.length, 2, "Correct number of records"); + is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)"); + is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)"); + is(records[0].target, parent, "Correct target (1)"); + is(records[1].target, parent, "Correct target (2)"); + + // Two records are sent - one for removed and one for added. + is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes"); + is(records[0].removedNodes.length, 1, "Should have got removedNodes"); + assertSamePseudoElement("before", records[0].removedNodes[0], originalBeforeElement); + + is(records[1].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent)); + is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + observer.disconnect(); + testRemoved(); + }); + + SpecialPowers.observeMutationEvents(m, parent, true); + parent.className = "after"; +} + +function testRemoved() { + let parent = document.getElementById("pseudo"); + let originalAfterElement = getLastChild(parent); + var m = new MutationObserver(function(records, observer) { + is(records.length, 1, "Correct number of records"); + is(records[0].type, "nativeAnonymousChildList", "Correct record type"); + is(records[0].target, parent, "Correct target"); + + is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes"); + is(records[0].removedNodes.length, 1, "Should have got removedNodes"); + assertSamePseudoElement("after", records[0].removedNodes[0], originalAfterElement); + + observer.disconnect(); + testMultipleAdded(); + }); + + SpecialPowers.observeMutationEvents(m, parent, true); + parent.className = ""; +} + +function testMultipleAdded() { + let parent = document.getElementById("pseudo"); + var m = new MutationObserver(function(records, observer) { + is(records.length, 2, "Correct number of records"); + is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)"); + is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)"); + is(records[0].target, parent, "Correct target (1)"); + is(records[1].target, parent, "Correct target (2)"); + + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent)); + is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + is(records[1].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent)); + is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + observer.disconnect(); + testRemovedDueToDisplay(); + }); + + SpecialPowers.observeMutationEvents(m, parent, true); + parent.className = "before after"; +} + +function testRemovedDueToDisplay() { + let parent = document.getElementById("pseudo"); + let originalBeforeElement = getFirstChild(parent); + let originalAfterElement = getLastChild(parent); + var m = new MutationObserver(function(records, observer) { + is(records.length, 2, "Correct number of records"); + is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)"); + is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)"); + is(records[0].target, parent, "Correct target (1)"); + is(records[1].target, parent, "Correct target (2)"); + + is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes"); + is(records[0].removedNodes.length, 1, "Should have got removedNodes"); + assertSamePseudoElement("before", records[0].removedNodes[0], originalBeforeElement); + + is(records[1].addedNodes.length, 0, "Shouldn't have got addedNodes"); + is(records[1].removedNodes.length, 1, "Should have got removedNodes"); + assertSamePseudoElement("after", records[1].removedNodes[0], originalAfterElement); + + observer.disconnect(); + testAddedDueToDisplay(); + }); + + SpecialPowers.observeMutationEvents(m, parent, true); + parent.style.display = "none"; +} + +function testAddedDueToDisplay() { + let parent = document.getElementById("pseudo"); + var m = new MutationObserver(function(records, observer) { + is(records.length, 2, "Correct number of records"); + is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)"); + is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)"); + is(records[0].target, parent, "Correct target (1)"); + is(records[1].target, parent, "Correct target (2)"); + + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent)); + is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + is(records[1].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent)); + is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + observer.disconnect(); + testDifferentTargetNoSubtree(); + }); + + SpecialPowers.observeMutationEvents(m, parent, true); + parent.style.display = "block"; +} + +function testDifferentTargetNoSubtree() { + let parent = document.getElementById("pseudo"); + var m = new MutationObserver(function(records, observer) { + ok(false, + "No mutation should fire when observing on a parent without subtree option."); + }); + SpecialPowers.observeMutationEvents(m, document, true); + parent.style.display = "none"; + + // Wait for the actual mutation to come through, making sure that + // the original observer never fires. + var m2 = new MutationObserver(function(records, observer) { + ok(!getFirstChild(parent), "Pseudo element has been removed, but no mutation"); + ok(!getLastChild(parent), "Pseudo element has been removed, but no mutation"); + observer.disconnect(); + testSubtree(); + }); + SpecialPowers.observeMutationEvents(m2, parent, true); +} + +function testSubtree() { + let parent = document.getElementById("pseudo"); + var m = new MutationObserver(function(records, observer) { + is(records.length, 2, "Correct number of records"); + is(records[0].type, "nativeAnonymousChildList", "Correct record type (1)"); + is(records[1].type, "nativeAnonymousChildList", "Correct record type (2)"); + is(records[0].target, parent, "Correct target (1)"); + is(records[1].target, parent, "Correct target (2)"); + + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("before", records[0].addedNodes[0], getFirstChild(parent)); + is(records[0].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + is(records[1].addedNodes.length, 1, "Should have got addedNodes"); + assertSamePseudoElement("after", records[1].addedNodes[0], getLastChild(parent)); + is(records[1].removedNodes.length, 0, "Shouldn't have got removedNodes"); + + observer.disconnect(); + testDictionaryWithoutChromePriv(); + }); + SpecialPowers.observeMutationEvents(m, document, true, true); + parent.style.display = "block"; +} + +function testDictionaryWithoutChromePriv() +{ + var m = new MutationObserver(function() {}); + try { + m.observe(document, { childList: true, get nativeAnonymousChildList() { throw "Foo1"; } } ); + ok(true, "Shouldn't throw!"); + } catch(ex) { + ok(false, "Did throw " + ex); + } + + try { + m.observe(document, { childList: true, get animations() { throw "Foo2"; } } ); + ok(true, "Shouldn't throw!"); + } catch(ex) { + ok(false, "Did throw " + ex); + } + + SimpleTest.finish(); +} + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_mutationobservers.html b/dom/base/test/test_mutationobservers.html new file mode 100644 index 0000000000..bde07c79cb --- /dev/null +++ b/dom/base/test/test_mutationobservers.html @@ -0,0 +1,935 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=641821 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 641821</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="runTest()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=641821">Mozilla Bug 641821</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 641821 **/ + +SimpleTest.requestFlakyTimeout("requestFlakyTimeout is silly. (But make sure marquee has time to initialize itself.)"); + +var div = document.createElement("div"); + +var M; +if ("MozMutationObserver" in window) { + M = window.MozMutationObserver; +} else if ("WebKitMutationObserver" in window) { + M = window.WebKitMutationObserver; +} else { + M = window.MutationObserver; +} + +function log(str) { + var d = document.createElement("div"); + d.textContent = str; + if (str.indexOf("PASSED") >= 0) { + d.setAttribute("style", "color: green;"); + } else { + d.setAttribute("style", "color: red;"); + } + document.getElementById("log").appendChild(d); +} + +// Some helper functions so that this test runs also outside mochitest. +if (!("ok" in window)) { + window.ok = function(val, str) { + log(str + (val ? " PASSED\n" : " FAILED\n")); + } +} + +if (!("is" in window)) { + window.is = function(val, refVal, str) { + log(str + (val == refVal? " PASSED " : " FAILED ") + + (val != refVal ? "expected " + refVal + " got " + val + "\n" : "\n")); + } +} + +if (!("isnot" in window)) { + window.isnot = function(val, refVal, str) { + log(str + (val != refVal? " PASSED " : " FAILED ") + + (val == refVal ? "Didn't expect " + refVal + "\n" : "\n")); + } +} + +if (!("SimpleTest" in window)) { + window.SimpleTest = + { + finish: function() { + document.getElementById("log").appendChild(document.createTextNode("DONE")); + }, + waitForExplicitFinish: function() {} + } +} + +function then(thenFn) { + setTimeout(function() { + if (thenFn) { + setTimeout(thenFn, 0); + } else { + SimpleTest.finish(); + } + }, 0); +} + +var m; +var m2; +var m3; +var m4; + +// Checks basic parameter validation and normal 'this' handling. +// Tests also basic attribute handling. +function runTest() { + m = new M(function(){}); + ok(m, "MutationObserver supported"); + + var e = null; + try { + m.observe(document, {}); + } catch (ex) { + e = ex; + } + ok(e, "Should have thrown an exception"); + is(e.name, "TypeError", "Should have thrown TypeError"); + + e = null; + try { + m.observe(document, { childList: true, attributeOldValue: true }); + } catch (ex) { + e = ex; + } + ok(!e, "Shouldn't have thrown an exception"); + + e = null; + try { + m.observe(document, { childList: true, attributeFilter: ["foo"] }); + } catch (ex) { + e = ex; + } + ok(!e, "Shouldn't have thrown an exception"); + + e = null; + try { + m.observe(document, { childList: true, characterDataOldValue: true }); + } catch (ex) { + e = ex; + } + ok(!e, "Shouldn't have thrown an exception"); + + e = null; + try { + m.observe(document); + } catch (ex) { + e = ex; + } + ok(e, "Should have thrown an exception"); + + m = new M(function(records, observer) { + is(observer, m, "2nd parameter should be the mutation observer"); + is(observer, this, "2nd parameter should be 'this'"); + is(records.length, 1, "Should have one record."); + is(records[0].type, "attributes", "Should have got attributes record"); + is(records[0].target, div, "Should have got div as target"); + is(records[0].attributeName, "foo", "Should have got record about foo attribute"); + observer.disconnect(); + then(testThisBind); + m = null; + }); + m.observe(div, { attributes: true, attributeFilter: ["foo"] }); + is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributes, true); + is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributeFilter.length, 1) + is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributeFilter[0], "foo") + div.setAttribute("foo", "bar"); +} + +// 'this' handling when fn.bind() is used. +function testThisBind() { + var child = div.appendChild(document.createElement("div")); + var gchild = child.appendChild(document.createElement("div")); + m = new M((function(records, observer) { + is(observer, m, "2nd parameter should be the mutation observer"); + isnot(observer, this, "2nd parameter should be 'this'"); + is(records.length, 3, "Should have one record."); + is(records[0].type, "attributes", "Should have got attributes record"); + is(records[0].target, div, "Should have got div as target"); + is(records[0].attributeName, "foo", "Should have got record about foo attribute"); + is(records[0].oldValue, "bar", "oldValue should be bar"); + is(records[1].type, "attributes", "Should have got attributes record"); + is(records[1].target, div, "Should have got div as target"); + is(records[1].attributeName, "foo", "Should have got record about foo attribute"); + is(records[1].oldValue, "bar2", "oldValue should be bar2"); + is(records[2].type, "attributes", "Should have got attributes record"); + is(records[2].target, gchild, "Should have got div as target"); + is(records[2].attributeName, "foo", "Should have got record about foo attribute"); + is(records[2].oldValue, null, "oldValue should be bar2"); + observer.disconnect(); + then(testCharacterData); + m = null; + }).bind(window)); + m.observe(div, { attributes: true, attributeOldValue: true, subtree: true }); + is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributes, true) + is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].attributeOldValue, true) + is(SpecialPowers.wrap(div).getBoundMutationObservers()[0].getObservingInfo()[0].subtree, true) + div.setAttribute("foo", "bar2"); + div.removeAttribute("foo"); + div.removeChild(child); + child.removeChild(gchild); + div.appendChild(gchild); + div.removeChild(gchild); + gchild.setAttribute("foo", "bar"); +} + +function testCharacterData() { + m = new M(function(records, observer) { + is(records[0].type, "characterData", "Should have got characterData"); + is(records[0].oldValue, null, "Shouldn't have got oldData"); + observer.disconnect(); + m = null; + }); + m2 = new M(function(records, observer) { + is(records[0].type, "characterData", "Should have got characterData"); + is(records[0].oldValue, "foo", "Should have got oldData"); + observer.disconnect(); + m2 = null; + }); + m3 = new M(function(records, observer) { + ok(false, "This should not be called!"); + observer.disconnect(); + m3 = null; + }); + m4 = new M(function(records, observer) { + is(records[0].oldValue, null, "Shouldn't have got oldData"); + observer.disconnect(); + m3.disconnect(); + m3 = null; + then(testChildList); + m4 = null; + }); + + div.appendChild(document.createTextNode("foo")); + m.observe(div, { characterData: true, subtree: true }); + m2.observe(div, { characterData: true, characterDataOldValue: true, subtree: true}); + // If observing the same node twice, only the latter option should apply. + m3.observe(div, { characterData: true, subtree: true }); + m3.observe(div, { characterData: true, subtree: false }); + m4.observe(div.firstChild, { characterData: true, subtree: false }); + + is(SpecialPowers.wrap(div).getBoundMutationObservers().length, 3) + is(SpecialPowers.wrap(div).getBoundMutationObservers()[2].getObservingInfo()[0].characterData, true) + is(SpecialPowers.wrap(div).getBoundMutationObservers()[2].getObservingInfo()[0].subtree, false) + + div.firstChild.data = "bar"; +} + +function testChildList() { + var fc = div.firstChild; + m = new M(function(records, observer) { + is(records[0].type, "childList", "Should have got childList"); + is(records[0].addedNodes.length, 0, "Shouldn't have got addedNodes"); + is(records[0].removedNodes.length, 1, "Should have got removedNodes"); + is(records[0].removedNodes[0], fc, "Should have removed a text node"); + observer.disconnect(); + then(testChildList2); + m = null; + }); + m.observe(div, { childList: true}); + div.removeChild(div.firstChild); +} + +function testChildList2() { + div.innerHTML = "<span>1</span><span>2</span>"; + m = new M(function(records, observer) { + is(records[0].type, "childList", "Should have got childList"); + is(records[0].removedNodes.length, 2, "Should have got removedNodes"); + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + observer.disconnect(); + then(testChildList3); + m = null; + }); + m.observe(div, { childList: true }); + div.innerHTML = "<span><span>foo</span></span>"; +} + +function testChildList3() { + m = new M(function(records, observer) { + is(records[0].type, "childList", "Should have got childList"); + is(records[0].removedNodes.length, 1, "Should have got removedNodes"); + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + observer.disconnect(); + then(testChildList4); + m = null; + }); + m.observe(div, { childList: true }); + div.textContent = "hello"; +} + +function testChildList4() { + div.textContent = null; + var df = document.createDocumentFragment(); + var t1 = df.appendChild(document.createTextNode("Hello ")); + var t2 = df.appendChild(document.createTextNode("world!")); + var s1 = div.appendChild(document.createElement("span")); + s1.textContent = "foo"; + var s2 = div.appendChild(document.createElement("span")); + function callback(records, observer) { + is(records.length, 3, "Should have got one record for removing nodes from document fragment and one record for adding them to div"); + is(records[0].removedNodes.length, 2, "Should have got removedNodes"); + is(records[0].removedNodes[0], t1, "Should be the 1st textnode"); + is(records[0].removedNodes[1], t2, "Should be the 2nd textnode"); + is(records[1].addedNodes.length, 2, "Should have got addedNodes"); + is(records[1].addedNodes[0], t1, "Should be the 1st textnode"); + is(records[1].addedNodes[1], t2, "Should be the 2nd textnode"); + is(records[1].previousSibling, s1, "Should have previousSibling"); + is(records[1].nextSibling, s2, "Should have nextSibling"); + is(records[2].type, "characterData", "3rd record should be characterData"); + is(records[2].target, t1, "target should be the textnode"); + is(records[2].oldValue, "Hello ", "oldValue was 'Hello '"); + observer.disconnect(); + then(testChildList5); + m = null; + }; + m = new M(callback); + m.observe(df, { childList: true, characterData: true, characterDataOldValue: true, subtree: true }); + is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].childList, true) + is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].characterData, true) + is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].characterDataOldValue, true) + is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo()[0].subtree, true) + ok(SpecialPowers.compare(SpecialPowers.wrap(df).getBoundMutationObservers()[0].mutationCallback, callback)) + m.observe(div, { childList: true }); + is(SpecialPowers.wrap(df).getBoundMutationObservers()[0].getObservingInfo().length, 2) + + // Make sure transient observers aren't leaked. + var leakTest = new M(function(){}); + leakTest.observe(div, { characterData: true, subtree: true }); + + div.insertBefore(df, s2); + s1.firstChild.data = "bar"; // This should *not* create a record. + t1.data = "Hello the whole "; // This should create a record. +} + +function testChildList5() { + div.textContent = null; + var c1 = div.appendChild(document.createElement("div")); + var c2 = document.createElement("div"); + var div2 = document.createElement("div"); + var c3 = div2.appendChild(document.createElement("div")); + var c4 = document.createElement("div"); + var c5 = document.createElement("div"); + var df = document.createDocumentFragment(); + var emptyDF = document.createDocumentFragment(); + var dfc1 = df.appendChild(document.createElement("div")); + var dfc2 = df.appendChild(document.createElement("div")); + var dfc3 = df.appendChild(document.createElement("div")); + m = new M(function(records, observer) { + is(records.length, 6 , ""); + is(records[0].removedNodes.length, 1, "Should have got removedNodes"); + is(records[0].removedNodes[0], c1, ""); + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + is(records[0].addedNodes[0], c2, ""); + is(records[0].previousSibling, null, ""); + is(records[0].nextSibling, null, ""); + is(records[1].removedNodes.length, 1, "Should have got removedNodes"); + is(records[1].removedNodes[0], c3, ""); + is(records[1].addedNodes.length, 0, "Shouldn't have got addedNodes"); + is(records[1].previousSibling, null, ""); + is(records[1].nextSibling, null, ""); + is(records[2].removedNodes.length, 1, "Should have got removedNodes"); + is(records[2].removedNodes[0], c2, ""); + is(records[2].addedNodes.length, 1, "Should have got addedNodes"); + is(records[2].addedNodes[0], c3, ""); + is(records[2].previousSibling, null, ""); + is(records[2].nextSibling, null, ""); + // Check document fragment handling + is(records[5].removedNodes.length, 1, ""); + is(records[5].removedNodes[0], c4, ""); + is(records[5].addedNodes.length, 3, ""); + is(records[5].addedNodes[0], dfc1, ""); + is(records[5].addedNodes[1], dfc2, ""); + is(records[5].addedNodes[2], dfc3, ""); + is(records[5].previousSibling, c3, ""); + is(records[5].nextSibling, c5, ""); + observer.disconnect(); + then(testAdoptNode); + m = null; + }); + m.observe(div, { childList: true, subtree: true }); + m.observe(div2, { childList: true, subtree: true }); + div.replaceChild(c2, c1); + div.replaceChild(c3, c2); + div.appendChild(c4); + div.appendChild(c5); + div.replaceChild(df, c4); + div.appendChild(emptyDF); // empty document shouldn't cause mutation records +} + +function testAdoptNode() { + var d1 = document.implementation.createHTMLDocument(null); + var d2 = document.implementation.createHTMLDocument(null); + var addedNode; + m = new M(function(records, observer) { + is(records.length, 3, "Should have 2 records"); + is(records[0].target.ownerDocument, d1, "ownerDocument should be the initial document") + is(records[1].target.ownerDocument, d2, "ownerDocument should be the new document"); + is(records[2].type, "attributes", "Should have got attribute mutation") + is(records[2].attributeName, "foo", "Should have got foo attribute mutation") + observer.disconnect(); + then(testOuterHTML); + m = null; + }); + m.observe(d1, { childList: true, subtree: true, attributes: true }); + d2.body.appendChild(d1.body); + addedNode = d2.body.lastChild.appendChild(d2.createElement("div")); + addedNode.setAttribute("foo", "bar"); +} + +function testOuterHTML() { + var doc = document.implementation.createHTMLDocument(null); + var d1 = doc.body.appendChild(document.createElement("div")); + var d2 = doc.body.appendChild(document.createElement("div")); + var d3 = doc.body.appendChild(document.createElement("div")); + var d4 = doc.body.appendChild(document.createElement("div")); + m = new M(function(records, observer) { + is(records.length, 4, "Should have 1 record"); + is(records[0].removedNodes.length, 1, "Should have 1 removed nodes"); + is(records[0].addedNodes.length, 2, "Should have 2 added nodes"); + is(records[0].previousSibling, null, ""); + is(records[0].nextSibling, d2, ""); + is(records[1].removedNodes.length, 1, "Should have 1 removed nodes"); + is(records[1].addedNodes.length, 2, "Should have 2 added nodes"); + is(records[1].previousSibling, records[0].addedNodes[1], ""); + is(records[1].nextSibling, d3, ""); + is(records[2].removedNodes.length, 1, "Should have 1 removed nodes"); + is(records[2].addedNodes.length, 2, "Should have 2 added nodes"); + is(records[2].previousSibling, records[1].addedNodes[1], ""); + is(records[2].nextSibling, d4, ""); + is(records[3].removedNodes.length, 1, "Should have 1 removed nodes"); + is(records[3].addedNodes.length, 0); + is(records[3].previousSibling, records[2].addedNodes[1], ""); + is(records[3].nextSibling, null, ""); + observer.disconnect(); + then(testInsertAdjacentHTML); + m = null; + }); + m.observe(doc, { childList: true, subtree: true }); + d1.outerHTML = "<div>1</div><div>1</div>"; + d2.outerHTML = "<div>2</div><div>2</div>"; + d3.outerHTML = "<div>3</div><div>3</div>"; + d4.outerHTML = ""; +} + +function testInsertAdjacentHTML() { + var doc = document.implementation.createHTMLDocument(null); + var d1 = doc.body.appendChild(document.createElement("div")); + var d2 = doc.body.appendChild(document.createElement("div")); + var d3 = doc.body.appendChild(document.createElement("div")); + var d4 = doc.body.appendChild(document.createElement("div")); + m = new M(function(records, observer) { + is(records.length, 4, ""); + is(records[0].target, doc.body, ""); + is(records[0].previousSibling, null, ""); + is(records[0].nextSibling, d1, ""); + is(records[1].target, d2, ""); + is(records[1].previousSibling, null, ""); + is(records[1].nextSibling, null, ""); + is(records[2].target, d3, ""); + is(records[2].previousSibling, null, ""); + is(records[2].nextSibling, null, ""); + is(records[3].target, doc.body, ""); + is(records[3].previousSibling, d4, ""); + is(records[3].nextSibling, null, ""); + observer.disconnect(); + then(testSyncXHR); + m = null; + }); + m.observe(doc, { childList: true, subtree: true }); + d1.insertAdjacentHTML("beforebegin", "<div></div><div></div>"); + d2.insertAdjacentHTML("afterbegin", "<div></div><div></div>"); + d3.insertAdjacentHTML("beforeend", "<div></div><div></div>"); + d4.insertAdjacentHTML("afterend", "<div></div><div></div>"); +} + + +var callbackHandled = false; + +function testSyncXHR() { + div.textContent = null; + m = new M(function(records, observer) { + is(records.length, 1, ""); + is(records[0].addedNodes.length, 1, ""); + callbackHandled = true; + observer.disconnect(); + m = null; + }); + m.observe(div, { childList: true, subtree: true }); + div.innerHTML = "<div>hello</div>"; + var x = new XMLHttpRequest(); + x.open("GET", window.location, false); + x.send(); + ok(!callbackHandled, "Shouldn't have called the mutation callback!"); + setTimeout(testSyncXHR2, 0); +} + +function testSyncXHR2() { + ok(callbackHandled, "Should have called the mutation callback!"); + then(testModalDialog); +} + +function testModalDialog() { + var didHandleCallback = false; + div.innerHTML = "<span>1</span><span>2</span>"; + m = new M(function(records, observer) { + is(records[0].type, "childList", "Should have got childList"); + is(records[0].removedNodes.length, 2, "Should have got removedNodes"); + is(records[0].addedNodes.length, 1, "Should have got addedNodes"); + observer.disconnect(); + m = null; + didHandleCallback = true; + }); + m.observe(div, { childList: true }); + div.innerHTML = "<span><span>foo</span></span>"; + try { + window.showModalDialog("mutationobserver_dialog.html"); + ok(didHandleCallback, "Should have called the callback while showing modal dialog!"); + } catch(e) { + todo(false, "showModalDialog not implemented on this platform"); + } + then(testTakeRecords); +} + +function testTakeRecords() { + var s = "<span>1</span><span>2</span>"; + div.innerHTML = s; + var takenRecords; + m = new M(function(records, observer) { + is(records.length, 3, "Should have got 3 records"); + + is(records[0].type, "attributes", "Should have got attributes"); + is(records[0].attributeName, "foo", ""); + is(records[0].attributeNamespace, null, ""); + is(records[0].prevValue, null, ""); + is(records[1].type, "childList", "Should have got childList"); + is(records[1].removedNodes.length, 2, "Should have got removedNodes"); + is(records[1].addedNodes.length, 2, "Should have got addedNodes"); + is(records[2].type, "attributes", "Should have got attributes"); + is(records[2].attributeName, "foo", ""); + + is(records.length, takenRecords.length, "Should have had similar mutations"); + is(records[0].type, takenRecords[0].type, "Should have had similar mutations"); + is(records[1].type, takenRecords[1].type, "Should have had similar mutations"); + is(records[2].type, takenRecords[2].type, "Should have had similar mutations"); + + is(records[1].removedNodes.length, takenRecords[1].removedNodes.length, "Should have had similar mutations"); + is(records[1].addedNodes.length, takenRecords[1].addedNodes.length, "Should have had similar mutations"); + + is(m.takeRecords().length, 0, "Shouldn't have any records"); + observer.disconnect(); + then(testMutationObserverAndEvents); + m = null; + }); + m.observe(div, { childList: true, attributes: true }); + div.setAttribute("foo", "bar"); + div.innerHTML = s; + div.removeAttribute("foo"); + takenRecords = m.takeRecords(); + div.setAttribute("foo", "bar"); + div.innerHTML = s; + div.removeAttribute("foo"); +} + +function testTakeRecords() { + function mutationListener(e) { + ++mutationEventCount; + is(e.attrChange, MutationEvent.ADDITION, "unexpected change"); + } + + m = new M(function(records, observer) { + is(records.length, 2, "Should have got 2 records"); + is(records[0].type, "attributes", "Should have got attributes"); + is(records[0].attributeName, "foo", ""); + is(records[0].oldValue, null, ""); + is(records[1].type, "attributes", "Should have got attributes"); + is(records[1].attributeName, "foo", ""); + is(records[1].oldValue, "bar", ""); + observer.disconnect(); + div.removeEventListener("DOMAttrModified", mutationListener); + then(testExpandos); + m = null; + }); + m.observe(div, { attributes: true, attributeOldValue: true }); + // Note, [0] points to a mutation observer which is there for a leak test! + ok(SpecialPowers.compare(SpecialPowers.wrap(div).getBoundMutationObservers()[1], m)); + var mutationEventCount = 0; + div.addEventListener("DOMAttrModified", mutationListener); + div.setAttribute("foo", "bar"); + div.setAttribute("foo", "bar"); + is(mutationEventCount, 1, "Should have got only one mutation event!"); +} + +function testExpandos() { + var m2 = new M(function(records, observer) { + is(observer.expandoProperty, true); + observer.disconnect(); + then(testOutsideShadowDOM); + }); + m2.expandoProperty = true; + m2.observe(div, { attributes: true }); + m2 = null; + if (SpecialPowers) { + // Run GC several times to see if the expando property disappears. + + SpecialPowers.gc(); + SpecialPowers.gc(); + SpecialPowers.gc(); + SpecialPowers.gc(); + } + div.setAttribute("foo", "bar2"); +} + +function testOutsideShadowDOM() { + var m = new M(function(records, observer) { + is(records.length, 1); + is(records[0].type, "attributes", "Should have got attributes"); + observer.disconnect(); + then(testInsideShadowDOM); + }); + m.observe(div, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }) + var sr = div.createShadowRoot(); + sr.innerHTML = "<div" + ">text</" + "div>"; + sr.firstChild.setAttribute("foo", "bar"); + sr.firstChild.firstChild.data = "text2"; + sr.firstChild.appendChild(document.createElement("div")); + div.setAttribute("foo", "bar"); +} + +function testInsideShadowDOM() { + var m = new M(function(records, observer) { + is(records.length, 4); + is(records[0].type, "childList"); + is(records[1].type, "attributes"); + is(records[2].type, "characterData"); + is(records[3].type, "childList"); + observer.disconnect(); + then(testMarquee); + }); + var sr = div.createShadowRoot(); + m.observe(sr, { + attributes: true, + childList: true, + characterData: true, + subtree: true + }); + + sr.innerHTML = "<div" + ">text</" + "div>"; + sr.firstChild.setAttribute("foo", "bar"); + sr.firstChild.firstChild.data = "text2"; + sr.firstChild.appendChild(document.createElement("div")); + div.setAttribute("foo", "bar2"); + +} + +function testMarquee() { + var m = new M(function(records, observer) { + is(records.length, 1); + is(records[0].type, "attributes"); + is(records[0].attributeName, "ok"); + is(records[0].oldValue, null); + observer.disconnect(); + then(testStyleCreate); + }); + var marquee = document.createElement("marquee"); + m.observe(marquee, { + attributes: true, + attributeOldValue: true, + childList: true, + characterData: true, + subtree: true + }); + document.body.appendChild(marquee); + setTimeout(function() {marquee.setAttribute("ok", "ok")}, 500); +} + +function testStyleCreate() { + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "style", "record.attributeName"); + is(records[0].oldValue, null, "record.oldValue"); + isnot(div.getAttribute("style"), null, "style attribute after creation"); + observer.disconnect(); + m = null; + div.removeAttribute("style"); + then(testStyleModify); + }); + m.observe(div, { attributes: true, attributeOldValue: true }); + is(div.getAttribute("style"), null, "style attribute before creation"); + div.style.color = "blue"; +} + +function testStyleModify() { + div.style.color = "yellow"; + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "style", "record.attributeName"); + isnot(div.getAttribute("style"), null, "style attribute after modification"); + observer.disconnect(); + m = null; + div.removeAttribute("style"); + then(testStyleRead); + }); + m.observe(div, { attributes: true }); + isnot(div.getAttribute("style"), null, "style attribute before modification"); + div.style.color = "blue"; +} + +function testStyleRead() { + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "data-test", "record.attributeName"); + is(div.getAttribute("style"), null, "style attribute after read"); + observer.disconnect(); + div.removeAttribute("data-test"); + m = null; + then(testStyleRemoveProperty); + }); + m.observe(div, { attributes: true }); + is(div.getAttribute("style"), null, "style attribute before read"); + var value = div.style.color; // shouldn't generate any mutation records + div.setAttribute("data-test", "a"); +} + +function testStyleRemoveProperty() { + div.style.color = "blue"; + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "style", "record.attributeName"); + isnot(div.getAttribute("style"), null, "style attribute after successful removeProperty"); + observer.disconnect(); + m = null; + div.removeAttribute("style"); + then(testStyleRemoveProperty2); + }); + m.observe(div, { attributes: true }); + isnot(div.getAttribute("style"), null, "style attribute before successful removeProperty"); + div.style.removeProperty("color"); +} + +function testStyleRemoveProperty2() { + m = new M(function(records, observer) { + is(records.length, 1, "number of records"); + is(records[0].type, "attributes", "record.type"); + is(records[0].attributeName, "data-test", "record.attributeName"); + is(div.getAttribute("style"), null, "style attribute after unsuccessful removeProperty"); + observer.disconnect(); + m = null; + div.removeAttribute("data-test"); + then(testAttributeRecordMerging1); + }); + m.observe(div, { attributes: true }); + is(div.getAttribute("style"), null, "style attribute before unsuccessful removeProperty"); + div.style.removeProperty("color"); // shouldn't generate any mutation records + div.setAttribute("data-test", "a"); +} + +function testAttributeRecordMerging1() { + ok(true, "testAttributeRecordMerging1"); + var m = new M(function(records, observer) { + is(records.length, 2); + is(records[0].type, "attributes"); + is(records[0].target, div); + is(records[0].attributeName, "foo"); + is(records[0].attributeNamespace, null); + is(records[0].oldValue, null); + + is(records[1].type, "attributes"); + is(records[1].target, div.firstChild); + is(records[1].attributeName, "foo"); + is(records[1].attributeNamespace, null); + is(records[1].oldValue, null); + observer.disconnect(); + div.innerHTML = ""; + div.removeAttribute("foo"); + then(testAttributeRecordMerging2); + }); + m.observe(div, { + attributes: true, + subtree: true + }); + SpecialPowers.wrap(m).mergeAttributeRecords = true; + + div.setAttribute("foo", "bar_1"); + div.setAttribute("foo", "bar_2"); + div.innerHTML = "<div></div>"; + div.firstChild.setAttribute("foo", "bar_1"); + div.firstChild.setAttribute("foo", "bar_2"); +} + +function testAttributeRecordMerging2() { + ok(true, "testAttributeRecordMerging2"); + var m = new M(function(records, observer) { + is(records.length, 2); + is(records[0].type, "attributes"); + is(records[0].target, div); + is(records[0].attributeName, "foo"); + is(records[0].attributeNamespace, null); + is(records[0].oldValue, "initial"); + + is(records[1].type, "attributes"); + is(records[1].target, div.firstChild); + is(records[1].attributeName, "foo"); + is(records[1].attributeNamespace, null); + is(records[1].oldValue, "initial"); + observer.disconnect(); + div.innerHTML = ""; + div.removeAttribute("foo"); + then(testAttributeRecordMerging3); + }); + + div.setAttribute("foo", "initial"); + div.innerHTML = "<div></div>"; + div.firstChild.setAttribute("foo", "initial"); + m.observe(div, { + attributes: true, + subtree: true, + attributeOldValue: true + }); + SpecialPowers.wrap(m).mergeAttributeRecords = true; + + div.setAttribute("foo", "bar_1"); + div.setAttribute("foo", "bar_2"); + div.firstChild.setAttribute("foo", "bar_1"); + div.firstChild.setAttribute("foo", "bar_2"); +} + +function testAttributeRecordMerging3() { + ok(true, "testAttributeRecordMerging3"); + var m = new M(function(records, observer) { + is(records.length, 4); + is(records[0].type, "attributes"); + is(records[0].target, div); + is(records[0].attributeName, "foo"); + is(records[0].attributeNamespace, null); + is(records[0].oldValue, "initial"); + + is(records[1].type, "attributes"); + is(records[1].target, div.firstChild); + is(records[1].attributeName, "foo"); + is(records[1].attributeNamespace, null); + is(records[1].oldValue, "initial"); + + is(records[2].type, "attributes"); + is(records[2].target, div); + is(records[2].attributeName, "foo"); + is(records[2].attributeNamespace, null); + is(records[2].oldValue, "bar_1"); + + is(records[3].type, "attributes"); + is(records[3].target, div.firstChild); + is(records[3].attributeName, "foo"); + is(records[3].attributeNamespace, null); + is(records[3].oldValue, "bar_1"); + + observer.disconnect(); + div.innerHTML = ""; + div.removeAttribute("foo"); + then(testAttributeRecordMerging4); + }); + + div.setAttribute("foo", "initial"); + div.innerHTML = "<div></div>"; + div.firstChild.setAttribute("foo", "initial"); + m.observe(div, { + attributes: true, + subtree: true, + attributeOldValue: true + }); + SpecialPowers.wrap(m).mergeAttributeRecords = true; + + // No merging should happen. + div.setAttribute("foo", "bar_1"); + div.firstChild.setAttribute("foo", "bar_1"); + div.setAttribute("foo", "bar_2"); + div.firstChild.setAttribute("foo", "bar_2"); +} + +function testAttributeRecordMerging4() { + ok(true, "testAttributeRecordMerging4"); + var m = new M(function(records, observer) { + }); + + div.setAttribute("foo", "initial"); + div.innerHTML = "<div></div>"; + div.firstChild.setAttribute("foo", "initial"); + m.observe(div, { + attributes: true, + subtree: true, + attributeOldValue: true + }); + SpecialPowers.wrap(m).mergeAttributeRecords = true; + + div.setAttribute("foo", "bar_1"); + div.setAttribute("foo", "bar_2"); + div.firstChild.setAttribute("foo", "bar_1"); + div.firstChild.setAttribute("foo", "bar_2"); + + var records = m.takeRecords(); + + is(records.length, 2); + is(records[0].type, "attributes"); + is(records[0].target, div); + is(records[0].attributeName, "foo"); + is(records[0].attributeNamespace, null); + is(records[0].oldValue, "initial"); + + is(records[1].type, "attributes"); + is(records[1].target, div.firstChild); + is(records[1].attributeName, "foo"); + is(records[1].attributeNamespace, null); + is(records[1].oldValue, "initial"); + m.disconnect(); + div.innerHTML = ""; + div.removeAttribute("foo"); + then(testChromeOnly); +} + +function testChromeOnly() { + // Content can't access nativeAnonymousChildList + try { + var mo = new M(function(records, observer) { }); + mo.observe(div, { nativeAnonymousChildList: true }); + ok(false, "Should have thrown when trying to observe with chrome-only init"); + } catch (e) { + ok(true, "Throws when trying to observe with chrome-only init"); + } + + then(); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<div id="log"> +</div> +</body> +</html> diff --git a/dom/base/test/test_named_frames.html b/dom/base/test/test_named_frames.html new file mode 100644 index 0000000000..e2cc572cad --- /dev/null +++ b/dom/base/test/test_named_frames.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=823227 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 823227</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 823227 **/ + + SimpleTest.waitForExplicitFinish(); + function doTest() { + is(frames[0].foo, frames[0][0], + "Should be able to look up frames by name in SVG documents"); + is(frames[1].foo, frames[1][0], + "Should be able to look up frames by name in XML documents"); + SimpleTest.finish(); + } + + addLoadEvent(doTest); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=823227">Mozilla Bug 823227</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><foreignObject><iframe name='foo' id='foo' xmlns='http://www.w3.org/1999/xhtml'/></foreignObject></svg>"></iframe> +<iframe src="data:text/xml,<root><iframe name='foo' id='foo' xmlns='http://www.w3.org/1999/xhtml'/></root>"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_navigatorPrefOverride.html b/dom/base/test/test_navigatorPrefOverride.html new file mode 100644 index 0000000000..d2c5133e81 --- /dev/null +++ b/dom/base/test/test_navigatorPrefOverride.html @@ -0,0 +1,54 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<!DOCTYPE HTML> +<html> +<head> + <title>Test for navigator property override</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"></pre> +<script class="testbody" type="text/javascript"> + + ok(navigator.appName, "This is used just to populate the cache"); + ok(navigator.appVersion, "This is used just to populate the cache"); + + // B2G could have an empty platform. + info(navigator.platform); + + ok(navigator.userAgent, "This is used just to populate the cache"); + + SpecialPowers.pushPrefEnv({"set": [ + ["general.appname.override", "appName overridden"], + ["general.appversion.override", "appVersion overridden"], + ["general.platform.override", "platform overridden"], + ["general.useragent.override", "userAgent overridden"], + ]}, + function() { + var ifr = document.createElement('IFRAME'); + ifr.src = "about:blank"; + + ifr.addEventListener('load', function() { + var nav = ifr.contentWindow.navigator; + isnot(navigator.appName, nav.appName, "appName should match"); + isnot(navigator.appVersion, nav.appVersion, "appVersion should match"); + isnot(navigator.platform, nav.platform, "platform should match"); + isnot(navigator.userAgent, nav.userAgent, "userAgent should match"); + SimpleTest.finish(); + }, false); + + document.getElementById('content').appendChild(ifr); + } + ); + + SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_navigator_hardwareConcurrency.html b/dom/base/test/test_navigator_hardwareConcurrency.html new file mode 100644 index 0000000000..b48e640e62 --- /dev/null +++ b/dom/base/test/test_navigator_hardwareConcurrency.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test for Navigator.hardwareConcurrency</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + var x = navigator.hardwareConcurrency; + is(typeof x, "number", "hardwareConcurrency should be a number."); + ok(x > 0, "hardwareConcurrency should be greater than 0."); + + </script> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_navigator_language.html b/dom/base/test/test_navigator_language.html new file mode 100644 index 0000000000..7b986aecbd --- /dev/null +++ b/dom/base/test/test_navigator_language.html @@ -0,0 +1,212 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=889335 +--> +<head> + <meta charset="utf-8"> + <title>Test for NavigatorLanguage</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=889335">Mozilla Bug 889335</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +</pre> +<script type="application/javascript;version=1.7"> + "use strict"; + + SimpleTest.waitForExplicitFinish(); + + /** Test for NavigatorLanguage **/ + var actualLanguageChangesFromHandler = 0; + var actualLanguageChangesFromAVL = 0; + var expectedLanguageChanges = 0; + + var testValues = [ + { accept_languages: 'foo', language: 'foo', languages: ['foo'] }, + { accept_languages: '', language: '', languages: [] }, + { accept_languages: 'foo,bar', language: 'foo', languages: [ 'foo', 'bar' ] }, + { accept_languages: ' foo , bar ', language: 'foo', languages: [ 'foo', 'bar' ] }, + { accept_languages: ' foo ; bar ', language: 'foo ; bar', languages: [ 'foo ; bar' ] }, + { accept_languages: '_foo_', language: '_foo_', languages: ['_foo_'] }, + { accept_languages: 'en_', language: 'en-', languages: ['en-'] }, + { accept_languages: 'en__', language: 'en-_', languages: ['en-_'] }, + { accept_languages: 'en_US, fr_FR', language: 'en-US', languages: ['en-US', 'fr-FR'] }, + { accept_languages: 'en_US_CA', language: 'en-US_CA', languages: ['en-US_CA'] }, + { accept_languages: 'en_us-ca', language: 'en-US-CA', languages: ['en-US-CA'] }, + { accept_languages: 'en_us-cal, en_us-c', language: 'en-US-cal', languages: ['en-US-cal', 'en-US-c'] }, + ]; + + var currentTestIdx = 0; + var tests = []; + function nextTest() { + currentTestIdx++; + if (currentTestIdx >= tests.length) { + SimpleTest.finish(); + return; + } + + tests[currentTestIdx](); + } + + // Check that the API is there. + tests.push(function testAPIPresence() { + ok('language' in window.navigator); + ok('languages' in window.navigator); + ok('onlanguagechange' in window); + + nextTest(); + }); + + // Check that calling navigator.languages return the same array, unless there + // was a change. + tests.push(function testArrayCached() { + var previous = navigator.languages; + is(navigator.languages, navigator.languages, "navigator.languages is cached"); + is(navigator.languages, previous, "navigator.languages is cached"); + + window.onlanguagechange = function() { + isnot(navigator.languages, previous, "navigator.languages cached value was updated"); + window.onlanguagechange = null; + + nextTest(); + } + + setTimeout(function() { + SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'testArrayCached']]}); + }, 0); + }); + + // Test that event handler inside the <body> works as expected and that the + // event has the expected properties. + tests.push(function testEventProperties() { + document.body.setAttribute('onlanguagechange', + "document.body.removeAttribute('onlanguagechange');" + + "is(event.cancelable, false); is(event.bubbles, false);" + + "nextTest();"); + + setTimeout(function() { + SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'testEventProperties']]}, function() {}); + }, 0); + }); + + // Check that the returned values such as the behavior when the underlying + // languages change. + tests.push(function testBasicBehaviour() { + function checkIfDoneAndProceed() { + if (actualLanguageChangesFromHandler == actualLanguageChangesFromAVL) { + if (genEvents.next().done) { + window.onlanguagechange = null; + window.removeEventListener('languagechange', languageChangeAVL); + nextTest(); + } + } + } + window.onlanguagechange = function() { + actualLanguageChangesFromHandler++; + checkIfDoneAndProceed(); + } + function languageChangeAVL() { + actualLanguageChangesFromAVL++; + checkIfDoneAndProceed(); + } + window.addEventListener('languagechange', languageChangeAVL); + + function* testEvents() { + for (var i = 0; i < testValues.length; ++i) { + var data = testValues[i]; + setTimeout(function(data) { + SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', data.accept_languages]]}); + }, 0, data); + expectedLanguageChanges++; + yield undefined; + + is(actualLanguageChangesFromAVL, expectedLanguageChanges); + is(actualLanguageChangesFromHandler, expectedLanguageChanges); + + is(navigator.language, data.language); + is(navigator.languages.length, data.languages.length); + if (navigator.languages.length > 0) { + is(navigator.languages[0], navigator.language) + } + for (var j = 0; j < navigator.languages.length; ++j) { + is(navigator.languages[j], data.languages[j]); + } + } + } + + var genEvents = testEvents(); + genEvents.next(); + }); + + // Check that the languagechange event isn't sent twice if the preference + // is set to the same value. + tests.push(function testOnlyFireIfRealChange() { + function* changeLanguage() { + setTimeout(function() { + SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-CA']]}); + }); + yield undefined; + + setTimeout(function() { + // Twice the same change, should fire only one event. + SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-CA']]}); + setTimeout(function() { + // A real change to tell the test it should now count how many changes were + // received until now. + SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'fr-FR']]}); + }); + }); + yield undefined; + } + + var genChanges = changeLanguage(); + + var doubleEventCount = 0; + window.onlanguagechange = function() { + if (navigator.language == 'fr-FR') { + is(1, doubleEventCount); + window.onlanguagechange = null; + nextTest(); + return; + } + + if (navigator.language == 'fr-CA') { + doubleEventCount++; + } + genChanges.next(); + } + + genChanges.next(); + }); + + // Check that there is no crash when a change happen after a window listening + // to them is killed. + tests.push(function testThatAddingAnEventDoesNotHaveSideEffects() { + var frame = document.createElement('iframe'); + frame.src = 'data:text/html,<script>window.onlanguagechange=function(){}<\/script>'; + document.body.appendChild(frame); + + frame.contentWindow.onload = function() { + document.body.removeChild(frame); + frame = null; + + SpecialPowers.exactGC(function() { + // This should not crash. + SpecialPowers.pushPrefEnv({"set": [['intl.accept_languages', 'en-GB']]}, nextTest); + }); + } + }); + + // There is one test using document.body. + addLoadEvent(function() { + tests[0](); + }); + +</script> +</body> +</html> diff --git a/dom/base/test/test_navigator_resolve_identity_xrays.xul b/dom/base/test/test_navigator_resolve_identity_xrays.xul new file mode 100644 index 0000000000..cf3e23d9f9 --- /dev/null +++ b/dom/base/test/test_navigator_resolve_identity_xrays.xul @@ -0,0 +1,42 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=985827 +--> +<window title="Mozilla Bug 985827" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=985827" + target="_blank">Mozilla Bug 985827</a> + <iframe id="t"></iframe> + </body> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + /** Test for Bug 985827 **/ + + SimpleTest.waitForExplicitFinish(); + + Components.utils.import("resource://gre/modules/Services.jsm"); + + addLoadEvent(function() { + var iframe = document.getElementById("t"); + + var dir = "chrome://mochitests/content/chrome/dom/base/test/"; + iframe.src = dir + "file_navigator_resolve_identity_xrays.xul"; + iframe.onload = function() { finish(); }; + + function finish() { + SimpleTest.finish(); + } + }); + + ]]> + </script> +</window> diff --git a/dom/base/test/test_noAudioNotification.html b/dom/base/test/test_noAudioNotification.html new file mode 100644 index 0000000000..18ac833a8b --- /dev/null +++ b/dom/base/test/test_noAudioNotification.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for video controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var observer = { + observe: function(subject, topic, data) { + ok(false, "should not receive audio-playback notification!"); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var video = document.createElement("video"); +video.loop = true; +video.src = "noaudio.webm"; + +video.onplay = video.onpause = function() { + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + runTest(); + }); + }); + }); +}; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + video.play(); + }, + + function() { + video.pause(); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_noAudioNotificationOnMutedElement.html b/dom/base/test/test_noAudioNotificationOnMutedElement.html new file mode 100644 index 0000000000..e9cdd2759d --- /dev/null +++ b/dom/base/test/test_noAudioNotificationOnMutedElement.html @@ -0,0 +1,129 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; + +var observer = { + observe: function(subject, topic, data) { + if (expectedNotification !== null) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } else { + ok(false, "should not receive audio-playback notification!"); + } + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var audio = new Audio(); +audio.loop = true; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + + audio.src = "audio.ogg"; + // Wait for the audio metadata to become available so that we have an audio track. + audio.onloadedmetadata = runTest; + }, + + // Verify that muting and unmuting dispatches the events as expected. + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-nonaudible'; + audio.muted = true; + }, + + function() { + expectedNotification = 'active'; + audio.muted = false; + }, + + function() { + expectedNotification = 'inactive-pause'; + audio.pause(); + }, + + // Verify that no events are dispatched when muted. + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-nonaudible'; + audio.muted = true; + }, + + function() { + expectedNotification = null; + audio.onpause = function() { + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + audio.onpause = null; + runTest(); + }); + }); + }); + }; + audio.pause(); + }, + + function() { + expectedNotification = null; + audio.muted = false; + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + runTest(); + }); + }); + }); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_noAudioNotificationOnMutedOrVolume0Element.html b/dom/base/test/test_noAudioNotificationOnMutedOrVolume0Element.html new file mode 100644 index 0000000000..0e4cc93f03 --- /dev/null +++ b/dom/base/test/test_noAudioNotificationOnMutedOrVolume0Element.html @@ -0,0 +1,162 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; + +var observer = { + observe: function(subject, topic, data) { + if (expectedNotification !== null) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } else { + ok(false, "should not receive audio-playback notification!"); + } + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var audio = new Audio(); +audio.loop = true; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + + audio.src = "audio.ogg"; + // Wait for the audio metadata to become available so that we have an audio track. + audio.onloadedmetadata = runTest; + }, + + // Verify that unmuting when the volume is 0 doesn't dispatch the events. + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-nonaudible'; + audio.muted = true; + }, + + function() { + expectedNotification = null; + audio.volume = 0; + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + runTest(); + }); + }); + }); + }, + + function() { + expectedNotification = null; + audio.muted = false; + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + runTest(); + }); + }); + }); + }, + + function() { + expectedNotification = 'active'; + audio.volume = 0.5; + }, + + function() { + expectedNotification = 'inactive-pause'; + audio.pause(); + }, + + // Verify that raising the volume when muted doesn't dispatch the events. + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-nonaudible'; + audio.muted = true; + }, + + function() { + expectedNotification = null; + audio.volume = 0; + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + runTest(); + }); + }); + }); + }, + + function() { + expectedNotification = null; + audio.volume = 0.5; + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + runTest(); + }); + }); + }); + }, + + function() { + expectedNotification = 'active'; + audio.muted = false; + }, + + function() { + expectedNotification = 'inactive-pause'; + audio.pause(); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_noAudioNotificationOnVolume0Element.html b/dom/base/test/test_noAudioNotificationOnVolume0Element.html new file mode 100644 index 0000000000..530dc88bfc --- /dev/null +++ b/dom/base/test/test_noAudioNotificationOnVolume0Element.html @@ -0,0 +1,129 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; + +var observer = { + observe: function(subject, topic, data) { + if (expectedNotification !== null) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } else { + ok(false, "should not receive audio-playback notification!"); + } + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var audio = new Audio(); +audio.loop = true; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + + audio.src = "audio.ogg"; + // Wait for the audio metadata to become available so that we have an audio track. + audio.onloadedmetadata = runTest; + }, + + // Verify that muting and unmuting dispatches the events as expected. + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-nonaudible'; + audio.volume = 0; + }, + + function() { + expectedNotification = 'active'; + audio.volume = 1; + }, + + function() { + expectedNotification = 'inactive-pause'; + audio.pause(); + }, + + // Verify that no events are dispatched when volume is set to 0.. + function() { + expectedNotification = 'active'; + audio.play(); + }, + + function() { + expectedNotification = 'inactive-nonaudible'; + audio.volume = 0; + }, + + function() { + expectedNotification = null; + audio.onpause = function() { + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + audio.onpause = null; + runTest(); + }); + }); + }); + }; + audio.pause(); + }, + + function() { + expectedNotification = null; + audio.volume = 1; + // Yield to the event loop a few times to make sure that audio-playback is not dispatched. + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + runTest(); + }); + }); + }); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_noWebAudioNotification.html b/dom/base/test/test_noWebAudioNotification.html new file mode 100644 index 0000000000..794f92d577 --- /dev/null +++ b/dom/base/test/test_noWebAudioNotification.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for video controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); +SimpleTest.requestFlakyTimeout("Testing an event not happening"); + +var observer = { + observe: function(subject, topic, data) { + ok(false, "should not receive audio-playback notification!"); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var ac; + +var tests = [ + function() { + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + ac = new AudioContext(); + setTimeout(runTest, 100); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +runTest(); + +</script> +</body> +</html> + diff --git a/dom/base/test/test_nodelist_holes.html b/dom/base/test/test_nodelist_holes.html new file mode 100644 index 0000000000..a8aa8934f3 --- /dev/null +++ b/dom/base/test/test_nodelist_holes.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=699826 +--> +<head> + <title>Test for Bug 699826</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=699826">Mozilla Bug 699826</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 699826 **/ +HTMLCollection.prototype[0] = "PASSProto0"; +HTMLCollection.prototype[1] = "PASSProto1"; +var list = document.getElementsByTagName("testtag"); +is(list[0], "PASSProto0", "Should expose proto properties on the list"); +is(list[1], "PASSProto1", "Should expose more proto properties on the list"); + +var testtag = document.createElement("testtag"); + +document.body.appendChild(testtag); + +is(list[0], testtag, "Should expose elements in the list"); +is(list[1], "PASSProto1", "Should expose proto properties out of range on the list"); + +testtag.parentNode.removeChild(testtag); + +is(list[0], "PASSProto0", "Should expose proto properties on the list after removal"); +is(list[1], "PASSProto1", "Should expose more proto properties on the list after removal"); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_nonascii_blob_url.html b/dom/base/test/test_nonascii_blob_url.html new file mode 100644 index 0000000000..ce5d050e26 --- /dev/null +++ b/dom/base/test/test_nonascii_blob_url.html @@ -0,0 +1,30 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test blob URL for non-ascii domain</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="fileutils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<div id="content"></div> +<script class="testbody" type="text/javascript;version=1.7"> + +var iframe = document.createElement('iframe'); +iframe.src = 'http://xn--exmple-cua.test/tests/dom/base/test/file_nonascii_blob_url.html'; +iframe.onload = function() { + iframe.contentWindow.postMessage('hello world', '*'); + onmessage = function(e) { + is(e.data, 'hello world', "Blob URL for non-ascii domain works"); + SimpleTest.finish(); + } +} + +document.getElementById('content').appendChild(iframe); +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_openDialogChromeOnly.html b/dom/base/test/test_openDialogChromeOnly.html new file mode 100644 index 0000000000..6548668c0c --- /dev/null +++ b/dom/base/test/test_openDialogChromeOnly.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=931768 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 931768</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 931768 **/ + + try { + openDialog("chrome://browser/content/browser.xul"); + ok(false, "Calling openDialog from unprivileged script should throw."); + } catch (e) { + ok(e instanceof ReferenceError, + "openDialog shouldn't be available to unprivileged script."); + } +</script> +</body> + + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=931768">Mozilla Bug 931768</a> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_open_null_features.html b/dom/base/test/test_open_null_features.html new file mode 100644 index 0000000000..f3f1e6196b --- /dev/null +++ b/dom/base/test/test_open_null_features.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1009529 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1009529</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1009529 **/ + SimpleTest.waitForExplicitFinish(); + + var win1 = open("about:blank", "_blank", null); + var win2 = open("about:blank", "_blank", ""); + for (var k in win1) { + var v; + try { + v = win1[k]; + } catch (ex) {} + if (v instanceof win1.BarProp) { + is(v.visible, win2[k] && win2[k].visible, "Both windows should have the same value for " + k); + } + } + + var closeCount = 0; + var closeInc = function(e) { + this.removeEventListener("unload", closeInc, true); + closeCount++; + if (closeCount == 2) { + SimpleTest.finish(); + } + }; + win1.addEventListener("unload", closeInc, true); + win2.addEventListener("unload", closeInc, true); + win1.close(); + win2.close(); + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1009529">Mozilla Bug 1009529</a> +<p id="display"> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_orientation_alternate.html b/dom/base/test/test_orientation_alternate.html new file mode 100644 index 0000000000..7276ad82cc --- /dev/null +++ b/dom/base/test/test_orientation_alternate.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test for ScreenOrientation API</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="orientationcommon.js"></script> +<div id="log"></div> +<script> +async_test(function(t) { + var originalOrientation = screen.orientation.type; + var alternateOrientation = originalOrientation == "portrait-primary" ? + "landscape-primary" : "portrait-primary"; + var p = specialPowersLock(alternateOrientation); + p.then(function() { + t.step(function() { assert_equals(screen.orientation.type, alternateOrientation); }); + return specialPowersLock(originalOrientation); + }).then(function() { + t.step(function() { assert_equals(screen.orientation.type, originalOrientation); }); + return specialPowersUnlock(); + }).then(function() { + t.done(); + }).catch(t.step_func(function(err) { + assert_unreached("Error setting orientation: " + err); + t.done(); + })); +}, "Test locking and unlocking orientation."); +</script> diff --git a/dom/base/test/test_orientation_frame.html b/dom/base/test/test_orientation_frame.html new file mode 100644 index 0000000000..748b3264ea --- /dev/null +++ b/dom/base/test/test_orientation_frame.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test for ScreenOrientation API</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="orientationcommon.js"></script> +<div id="log"></div> +<iframe id="frame"></iframe> +<script> +async_test(function(t) { + var originalOrientation = screen.orientation.type; + var alternateOrientation = originalOrientation == "portrait-primary" ? + "landscape-primary" : "portrait-primary"; + + window.addEventListener("message", function(event) { + t.step(function() { assert_array_equals(event.data, [alternateOrientation, originalOrientation]); }); + t.done(); + }, false); + + var frame = document.getElementById("frame"); + frame.src = "file_record_orientation.html"; + + frame.onload = function() { + var p = specialPowersLock(alternateOrientation); + p.then(function() { + return specialPowersLock(originalOrientation); + }).then(function() { + return specialPowersUnlock(); + }).then(function() { + frame.contentWindow.postMessage("report", "*"); + }).catch(t.step_func(function(err) { + assert_unreached("Error setting orientation: " + err); + t.done(); + })); + }; +}, "Test orientation change event in frame."); +</script> diff --git a/dom/base/test/test_orientation_frame_lock.html b/dom/base/test/test_orientation_frame_lock.html new file mode 100644 index 0000000000..f8b7a65d08 --- /dev/null +++ b/dom/base/test/test_orientation_frame_lock.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test for ScreenOrientation API</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="orientationcommon.js"></script> +<div id="log"></div> +<iframe sandbox="allow-scripts allow-orientation-lock" id="frame"></iframe> +<script> +async_test(function(t) { + var originalOrientation = screen.orientation.type; + var alternateOrientation = originalOrientation == "portrait-primary" ? + "landscape-primary" : "portrait-primary"; + + var orientationChanges = []; + window.screen.orientation.onchange = function() { + orientationChanges.push(screen.orientation.type); + }; + + window.addEventListener("message", function(event) { + t.step(function() { + assert_equals(event.data, "success"); + assert_array_equals(orientationChanges, [ alternateOrientation ]); + }); + + // Return the orientation to its original settings. + var p = specialPowersLock(originalOrientation); + p.then(function() { + return specialPowersUnlock(); + }).then(function() { + t.done(); + }).catch(t.step_func(function(err) { + assert_unreached("Error setting orientation: " + err); + t.done(); + })); + }, false); + + var frame = document.getElementById("frame"); + frame.src = "http://example.com/tests/dom/base/test/file_lock_orientation.html"; + + frame.onload = function() { + assert_array_equals(orientationChanges, []); + frame.contentWindow.postMessage(alternateOrientation, "*"); + }; +}, "Test orientation lock from within a frame with sandbox permission."); +</script> diff --git a/dom/base/test/test_orientation_sandbox_no_lock.html b/dom/base/test/test_orientation_sandbox_no_lock.html new file mode 100644 index 0000000000..e020a6daa9 --- /dev/null +++ b/dom/base/test/test_orientation_sandbox_no_lock.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test for ScreenOrientation API</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="orientationcommon.js"></script> +<div id="log"></div> +<iframe sandbox="allow-scripts" id="frame"></iframe> +<script> +async_test(function(t) { + var originalOrientation = screen.orientation.type; + var alternateOrientation = originalOrientation == "portrait-primary" ? + "landscape-primary" : "portrait-primary"; + + var orientationChanges = []; + window.screen.orientation.onchange = function() { + orientationChanges.push(screen.orientation.type); + }; + + window.addEventListener("message", function(event) { + t.step(function() { + assert_equals(event.data, "error"); + assert_array_equals(orientationChanges, []); + t.done(); + }); + }, false); + + var frame = document.getElementById("frame"); + frame.src = "http://example.com/tests/dom/base/test/file_lock_orientation.html"; + + frame.onload = function() { + assert_array_equals(orientationChanges, []); + frame.contentWindow.postMessage(alternateOrientation, "*"); + }; +}, "Test orientation lock from within a frame without sandbox permission."); +</script> diff --git a/dom/base/test/test_pluginAudioNotification.html b/dom/base/test/test_pluginAudioNotification.html new file mode 100644 index 0000000000..399a4307f9 --- /dev/null +++ b/dom/base/test/test_pluginAudioNotification.html @@ -0,0 +1,121 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> +<iframe></iframe> + +<script type="application/javascript"> + +// Copied from /dom/plugins/test/mochitest/utils.js +function getTestPlugin(pluginName) { + var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"] + .getService(SpecialPowers.Ci.nsIPluginHost); + var tags = ph.getPluginTags(); + var name = pluginName || "Test Plug-in"; + for (var tag of tags) { + if (tag.name == name) { + return tag; + } + } + + ok(false, "Could not find plugin tag with plugin name '" + name + "'"); + return null; +} +// Copied from /dom/plugins/test/mochitest/utils.js +function setTestPluginEnabledState(newEnabledState, pluginName) { + var oldEnabledState = SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName); + if (!oldEnabledState) { + return; + } + var plugin = getTestPlugin(pluginName); + while (plugin.enabledState != newEnabledState) { + // Run a nested event loop to wait for the preference change to + // propagate to the child. Yuck! + SpecialPowers.Services.tm.currentThread.processNextEvent(true); + } + SimpleTest.registerCleanupFunction(function() { + SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName); + }); +} +setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; +var iframe = null; + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + SimpleTest.executeSoon(runTest); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var tests = [ + function() { + iframe = document.querySelector("iframe"); + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + expectedNotification = 'active'; + iframe.src = "file_pluginAudio.html"; + }, + + function() { + info("=== Mute plugin ==="); + ok(!iframe.contentWindow.pluginMuted(), "Plugin should not be muted"); + iframe.contentWindow.toggleMuteState(true); + ok(iframe.contentWindow.pluginMuted(), "Plugin should be muted"); + expectedNotification = 'inactive-nonaudible'; + }, + + function() { + info("=== unmute plugin =="); + ok(iframe.contentWindow.pluginMuted(), "Plugin should be muted"); + iframe.contentWindow.toggleMuteState(false); + ok(!iframe.contentWindow.pluginMuted(), "Plugin should not be muted"); + expectedNotification = 'active'; + }, + + function() { + info("=== stop audio =="); + expectedNotification = 'inactive-pause'; + iframe.contentWindow.stopAudio(); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +onload = runTest; + +</script> +</body> +</html> + diff --git a/dom/base/test/test_pluginMutedBeforePlay.html b/dom/base/test/test_pluginMutedBeforePlay.html new file mode 100644 index 0000000000..658875dc9c --- /dev/null +++ b/dom/base/test/test_pluginMutedBeforePlay.html @@ -0,0 +1,76 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Mute window before the plugin starts playing</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> +<iframe></iframe> + +<script type="application/javascript"> + +// Copied from /dom/plugins/test/mochitest/utils.js +function getTestPlugin(pluginName) { + var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"] + .getService(SpecialPowers.Ci.nsIPluginHost); + var tags = ph.getPluginTags(); + var name = pluginName || "Test Plug-in"; + for (var tag of tags) { + if (tag.name == name) { + return tag; + } + } + + ok(false, "Could not find plugin tag with plugin name '" + name + "'"); + return null; +} +// Copied from /dom/plugins/test/mochitest/utils.js +function setTestPluginEnabledState(newEnabledState, pluginName) { + var oldEnabledState = SpecialPowers.setTestPluginEnabledState(newEnabledState, pluginName); + if (!oldEnabledState) { + return; + } + var plugin = getTestPlugin(pluginName); + while (plugin.enabledState != newEnabledState) { + // Run a nested event loop to wait for the preference change to + // propagate to the child. Yuck! + SpecialPowers.Services.tm.currentThread.processNextEvent(true); + } + SimpleTest.registerCleanupFunction(function() { + SpecialPowers.setTestPluginEnabledState(oldEnabledState, pluginName); + }); +} +setTestPluginEnabledState(SpecialPowers.Ci.nsIPluginTag.STATE_ENABLED); + +SimpleTest.waitForExplicitFinish(); + +function runTest() { + var iframe = document.querySelector("iframe"); + iframe.src = "file_pluginAudioNonAutoStart.html"; + + function muteBeforePlay() { + ok(!iframe.contentWindow.pluginMuted(), "Plugin should not be muted"); + iframe.contentWindow.toggleMuteState(true); + + iframe.contentWindow.startAudio(); + ok(iframe.contentWindow.pluginMuted(), "Plugin should still be muted after playing"); + + iframe.contentWindow.stopAudio(); + SimpleTest.finish(); + } + + iframe.onload = function() { + ok(true, "Already load iframe."); + muteBeforePlay(); + } +} + +onload = runTest; + +</script> +</body> +</html> + diff --git a/dom/base/test/test_plugin_freezing.html b/dom/base/test/test_plugin_freezing.html new file mode 100644 index 0000000000..41d41be580 --- /dev/null +++ b/dom/base/test/test_plugin_freezing.html @@ -0,0 +1,68 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for plugin freezing and thawing</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<div id="content" style="display: none"> +</div> +<embed id='e1' type='application/x-test'></embed> +<script> +var e1 = document.getElementById('e1'); +var w; + +var testIndex = 0; +var tests; + +window.addEventListener("unload", function() { + e1.stopWatchingInstanceCount(); +}, false); + +function nextTest() { + if (testIndex == tests.length) { + if (w) { + w.close(); + } + SimpleTest.waitForFocus(function() { + SimpleTest.finish(); + }); + return; + } + + var test = tests[testIndex]; + ++testIndex; + test(); +} + +function waitForInstanceCount(n) { + if (e1.getInstanceCount() == n) { + ok(true, "reached instance count " + n); + nextTest(); + return; + } + setTimeout(function() { waitForInstanceCount(n); }, 0); +} + +tests = [ + function() { waitForInstanceCount(1); }, + function() { w.location.href = "about:blank"; + waitForInstanceCount(0); }, +]; + +try { + e1.startWatchingInstanceCount(); + var w = window.open("data:text/html,<embed id='e2' type='application/x-test'></embed>"); + SimpleTest.waitForFocus(nextTest, w); + SimpleTest.waitForExplicitFinish(); +} catch (err) { + todo(false, "Instances already being watched?"); +} + +</script> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_postMessage_originAttributes.html b/dom/base/test/test_postMessage_originAttributes.html new file mode 100644 index 0000000000..5ababc1d44 --- /dev/null +++ b/dom/base/test/test_postMessage_originAttributes.html @@ -0,0 +1,60 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test window.postMessages from system principal to window with non-default originAttributes</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<iframe id="target-iframe"></iframe> +<script type="application/javascript"> + +add_task(function*() { + yield SpecialPowers.pushPrefEnv( + { "set": [["network.disable.ipc.security", true]] }); +}); + +add_task(function*() { + let iframe = document.querySelector("#target-iframe"); + + let win = SpecialPowers.wrap(iframe).contentWindow; + let docShell = win.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) + .getInterface(SpecialPowers.Ci.nsIDocShell); + + // Add private browsing ID to docShell origin and load document. + docShell.setOriginAttributes({privateBrowsingId: 1}); + + yield new Promise(resolve => { + iframe.addEventListener("load", resolve, true); + + iframe.src = SimpleTest.getTestFileURL("file_receiveMessage.html"); + }); + + // Set up console monitor to wait for warning. + const expectedMessage = ( + 'Attempting to post a message to window with url ' + + '"http://mochi.test:8888/tests/dom/base/test/file_receiveMessage.html" ' + + 'and origin "http://mochi.test:8888^privateBrowsingId=1" from a system ' + + 'principal scope with mismatched origin "[System Principal]".'); + + let consolePromise = new Promise(resolve => { + SimpleTest.monitorConsole(resolve, [e => e.message == expectedMessage]); + }); + + // Post to the content window via SpecialPowers' system principal scope. + win.postMessage("Hello. o/", "http://mochi.test:8888"); + yield new Promise(resolve => setTimeout(resolve, 0)); + + SimpleTest.endMonitorConsole(); + yield consolePromise; + + // Check that the window received and handled the message. + is(win.document.body.textContent, "|Hello. o/", + "Content window received the expected message"); +}); +</script> +</body> +</html> + diff --git a/dom/base/test/test_postMessage_solidus.html b/dom/base/test/test_postMessage_solidus.html new file mode 100644 index 0000000000..ab3e4ecec4 --- /dev/null +++ b/dom/base/test/test_postMessage_solidus.html @@ -0,0 +1,93 @@ + +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=949488 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 949488 - basic support</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=949488">Mozilla Bug 949488</a> + <div id="content"></div> + <script type="application/javascript"> + + function selfMessage() { + addEventListener('message', receiveMessage); + function receiveMessage(evt) { + is(evt.data, 1, "Message received"); + removeEventListener('message', receiveMessage); + runTest(); + } + + postMessage(1, '/'); + } + + function frameOk() { + var ifr = document.createElement("iframe"); + ifr.addEventListener("load", iframeLoaded, false); + ifr.setAttribute('src', "iframe_postMessage_solidus.html"); + + var div = document.getElementById("content"); + div.appendChild(ifr); + + function iframeLoaded() { + addEventListener('message', receiveMessage); + function receiveMessage(evt) { + is(evt.data, 2, "Message received"); + removeEventListener('message', receiveMessage); + runTest(); + } + + ifr.contentWindow.postMessage(2, '/'); + } + } + + function frameWrong() { + var ifr = document.createElement("iframe"); + ifr.addEventListener("load", iframeLoaded, false); + ifr.setAttribute('src', "http://www.example.com/tests/dom/base/test/iframe_postMessage_solidus.html"); + + var div = document.getElementById("content"); + div.appendChild(ifr); + + function iframeLoaded() { + addEventListener('message', receiveMessage); + function receiveMessage(evt) { + ok(evt.data, 3, "Message received"); + removeEventListener('message', receiveMessage); + runTest(); + } + + ifr.contentWindow.postMessage(4, '/'); + SimpleTest.executeSoon(function() { + ifr.contentWindow.postMessage(3, '*'); + }); + } + } + + var tests = [ + selfMessage, + frameOk, + frameWrong + ]; + + function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); + } + + SimpleTest.waitForExplicitFinish(); + runTest(); + + </script> +</body> +</html> diff --git a/dom/base/test/test_postMessages.html b/dom/base/test/test_postMessages.html new file mode 100644 index 0000000000..13a2842700 --- /dev/null +++ b/dom/base/test/test_postMessages.html @@ -0,0 +1,654 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for postMessages cloning/transferring objects</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body> +<input id="fileList" type="file"></input> +<script type="application/javascript;version=1.7"> + +function setup_tests() { + SpecialPowers.pushPrefEnv({"set": [["dom.input.dirpicker", true], + ["javascript.options.wasm", true]]}, next); +} + +function getType(a) { + if (a === null || a === undefined) + return 'null'; + + if (Array.isArray(a)) + return 'array'; + + if (typeof a == 'object') + return 'object'; + + if (SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported() && + a instanceof WebAssembly.Module) + return "wasm"; + + return 'primitive'; +} + +function compare(a, b) { + is (getType(a), getType(b), 'Type matches'); + + var type = getType(a); + if (type == 'array') { + is (a.length, b.length, 'Array.length matches'); + for (var i = 0; i < a.length; ++i) { + compare(a[i], b[i]); + } + + return; + } + + if (type == 'object') { + ok (a !== b, 'They should not match'); + + var aProps = []; + for (var p in a) aProps.push(p); + + var bProps = []; + for (var p in b) bProps.push(p); + + is (aProps.length, bProps.length, 'Props match'); + is (aProps.sort().toSource(), bProps.sort().toSource(), 'Props match - using toSource()'); + + for (var p in a) { + compare(a[p], b[p]); + } + + return; + } + + if (type == 'wasm') { + var wasmA = new WebAssembly.Instance(a); + ok(wasmA instanceof WebAssembly.Instance, "got an instance"); + + var wasmB = new WebAssembly.Instance(b); + ok(wasmB instanceof WebAssembly.Instance, "got an instance"); + + ok(wasmA.exports.foo() === wasmB.exports.foo(), "Same result!"); + ok(wasmB.exports.foo() === 42, "We want 42"); + } + + if (type != 'null') { + is (a.toSource(), b.toSource(), 'Matching using toSource()'); + } +} + +var clonableObjects = [ + { target: 'all', data: 'hello world' }, + { target: 'all', data: 123 }, + { target: 'all', data: null }, + { target: 'all', data: true }, + { target: 'all', data: new Date() }, + { target: 'all', data: [ 1, 'test', true, new Date() ] }, + { target: 'all', data: { a: true, b: null, c: new Date(), d: [ true, false, {} ] } }, + { target: 'all', data: new Blob([123], { type: 'plain/text' }) }, + { target: 'all', data: new ImageData(2, 2) }, +]; + +function create_fileList() { + var url = SimpleTest.getTestFileURL("script_postmessages_fileList.js"); + var script = SpecialPowers.loadChromeScript(url); + + function onOpened(message) { + var fileList = document.getElementById('fileList'); + SpecialPowers.wrap(fileList).mozSetFileArray([message.file]); + + // Just a simple test + var domFile = fileList.files[0]; + is(domFile.name, "prefs.js", "fileName should be prefs.js"); + + clonableObjects.push({ target: 'all', data: fileList.files }); + script.destroy(); + next(); + } + + script.addMessageListener("file.opened", onOpened); + script.sendAsyncMessage("file.open"); +} + +function create_directory() { + if (navigator.userAgent.toLowerCase().indexOf('Android') != -1) { + next(); + return; + } + + var url = SimpleTest.getTestFileURL("script_postmessages_fileList.js"); + var script = SpecialPowers.loadChromeScript(url); + + function onOpened(message) { + var fileList = document.getElementById('fileList'); + SpecialPowers.wrap(fileList).mozSetDirectory(message.dir); + + fileList.getFilesAndDirectories().then(function(list) { + // Just a simple test + is(list.length, 1, "This list has 1 element"); + ok(list[0] instanceof Directory, "We have a directory."); + + clonableObjects.push({ target: 'all', data: list[0] }); + script.destroy(); + next(); + }); + } + + script.addMessageListener("dir.opened", onOpened); + script.sendAsyncMessage("dir.open"); +} + +function create_wasmModule() { + info("Checking if we can play with WebAssembly..."); + + if (!SpecialPowers.Cu.getJSTestingFunctions().wasmIsSupported()) { + next(); + return; + } + + ok(WebAssembly, "WebAssembly object should exist"); + ok(WebAssembly.compile, "WebAssembly.compile function should exist"); + + const wasmTextToBinary = SpecialPowers.unwrap(SpecialPowers.Cu.getJSTestingFunctions().wasmTextToBinary); + const fooModuleCode = wasmTextToBinary(`(module + (func $foo (result i32) (i32.const 42)) + (export "foo" $foo) + )`, 'new-format'); + + WebAssembly.compile(fooModuleCode).then((m) => { + ok(m instanceof WebAssembly.Module, "The WasmModule has been compiled."); + clonableObjects.push({ target: 'sameProcess', data: m }); + next(); + }, () => { + ok(false, "The compilation of the wasmModule failed."); + }); +} + +function runTests(obj) { + ok(('clonableObjectsEveryWhere' in obj) && + ('clonableObjectsSameProcess' in obj) && + ('transferableObjects' in obj) && + (obj.clonableObjectsEveryWhere || obj.clonableObjectsSameProcess || obj.transferableObjects), "We must run some test!"); + + // cloning tests - everyWhere + new Promise(function(resolve, reject) { + if (!obj.clonableObjectsEveryWhere) { + resolve(); + return; + } + + var clonableObjectsId = 0; + function runClonableTest() { + if (clonableObjectsId >= clonableObjects.length) { + resolve(); + return; + } + + var object = clonableObjects[clonableObjectsId++]; + + if (object.target != 'all') { + runClonableTest(); + return; + } + + obj.send(object.data, []).then(function(received) { + compare(received.data, object.data); + runClonableTest(); + }); + } + + runClonableTest(); + }) + + // clonable same process + .then(function() { + return new Promise(function(resolve, reject) { + if (!obj.clonableObjectsSameProcess) { + resolve(); + return; + } + + var clonableObjectsId = 0; + function runClonableTest() { + if (clonableObjectsId >= clonableObjects.length) { + resolve(); + return; + } + + var object = clonableObjects[clonableObjectsId++]; + + if (object.target != 'sameProcess') { + runClonableTest(); + return; + } + + obj.send(object.data, []).then(function(received) { + compare(received.data, object.data); + runClonableTest(); + }); + } + + runClonableTest(); + }); + }) + + // transfering tests + .then(function() { + if (!obj.transferableObjects) { + return; + } + + // MessagePort + return new Promise(function(r, rr) { + var mc = new MessageChannel(); + obj.send(42, [mc.port1]).then(function(received) { + ok(received.ports.length, 1, "MessagePort has been transferred"); + mc.port2.postMessage("hello world"); + received.ports[0].onmessage = function(e) { + ok(e.data, "hello world", "Ports are connected!"); + r(); + } + }); + }); + }) + + // no dup transfering + .then(function() { + if (!obj.transferableObjects) { + return; + } + + // MessagePort + return new Promise(function(r, rr) { + var mc = new MessageChannel(); + obj.send(42, [mc.port1, mc.port1]).then(function(received) { + ok(false, "Duplicate ports should throw!"); + }, function() { + ok(true, "Duplicate ports should throw!"); + }) + .then(r); + }); + }) + + // non transfering tests + .then(function() { + if (obj.transferableObjects) { + return; + } + + // MessagePort + return new Promise(function(r, rr) { + var mc = new MessageChannel(); + obj.send(42, [mc.port1]).then(function(received) { + ok(false, "This object should not support port transferring"); + }, function() { + ok(true, "This object should not support port transferring"); + }) + .then(r); + }); + }) + + // done. + .then(function() { + obj.finished(); + }); +} + +// PostMessage to the same window. +function test_windowToWindow() { + info("Testing window to window"); + var resolve; + + onmessage = function(e) { + if (!resolve) { + ok(false, "Unexpected message!"); + return; + } + + let tmp = resolve; + resolve = null; + tmp({ data: e.data, ports: e.ports }); + } + + runTests({ + clonableObjectsEveryWhere: true, + clonableObjectsSameProcess: true, + transferableObjects: true, + send: function(what, ports) { + return new Promise(function(r, rr) { + resolve = r; + + try { + postMessage(what, '*', ports); + } catch(e) { + resolve = null; + rr(); + } + }); + }, + + finished: function() { + onmessage = null; + next(); + } + }); +} + +// PostMessage to iframe +function test_windowToIframe() { + info("Testing window to iframe"); + test_windowToIframeURL('iframe_postMessages.html'); +} + +// PostMessage to cross-origin iframe +function test_windowToCrossOriginIframe() { + info("Testing window to cross-origin iframe"); + test_windowToIframeURL('http://example.com/tests/dom/base/test/iframe_postMessages.html'); +} + +// iframe helper class +function test_windowToIframeURL(url) { + var resolve; + + onmessage = function(e) { + if (!resolve) { + ok(false, "Unexpected message!"); + return; + } + + let tmp = resolve; + resolve = null; + tmp({ data: e.data, ports: e.ports }); + } + + var ifr = document.createElement('iframe'); + ifr.src = url; + ifr.onload = function() { + runTests({ + clonableObjectsEveryWhere: true, + clonableObjectsSameProcess: true, + transferableObjects: true, + send: function(what, ports) { + return new Promise(function(r, rr) { + resolve = r; + try { + ifr.contentWindow.postMessage(what, '*', ports); + } catch(e) { + resolve = null; + rr(); + } + }); + }, + + finished: function() { + document.body.removeChild(ifr); + onmessage = null; + next(); + } + }); + } + document.body.appendChild(ifr); +} + +// PostMessage for Workers +function test_workers() { + info("Testing Workers"); + + var resolve; + + var w = new Worker('worker_postMessages.js'); + w.postMessage('workers'); + w.onmessage = function(e) { + is(e.data, 'ok', "Worker ready!"); + + w.onmessage = function(e) { + if (!resolve) { + ok(false, "Unexpected message!"); + return; + } + + let tmp = resolve; + resolve = null; + tmp({ data: e.data, ports: e.ports }); + } + + runTests({ + clonableObjectsEveryWhere: true, + clonableObjectsSameProcess: true, + transferableObjects: true, + send: function(what, ports) { + return new Promise(function(r, rr) { + resolve = r; + try { + w.postMessage(what, ports); + } catch(e) { + resolve = null; + rr(); + } + }); + }, + + finished: function() { + onmessage = null; + next(); + } + }); + } +} + +// PostMessage for BroadcastChannel +function test_broadcastChannel() { + info("Testing broadcastChannel"); + + var bc1 = new BroadcastChannel('postMessagesTest'); + var bc2 = new BroadcastChannel('postMessagesTest'); + + var resolve; + + bc2.onmessage = function(e) { + if (!resolve) { + ok(false, "Unexpected message!"); + return; + } + + let tmp = resolve; + resolve = null; + tmp({ data: e.data, ports: [] }); + } + + runTests({ + clonableObjectsEveryWhere: true, + clonableObjectsSameProcess: false, + transferableObjects: false, + send: function(what, ports) { + return new Promise(function(r, rr) { + if (ports.length) { + rr(); + return; + } + + resolve = r; + bc1.postMessage(what); + }); + }, + + finished: function() { + onmessage = null; + next(); + } + }); +} + +// PostMessage for BroadcastChannel in workers +function test_broadcastChannel_inWorkers() { + info("Testing broadcastChannel in Workers"); + + var bc = new BroadcastChannel('postMessagesTest_inWorkers'); + var resolve; + + var w = new Worker('worker_postMessages.js'); + w.postMessage('broadcastChannel'); + w.onmessage = function(e) { + is(e.data, 'ok', "Worker ready!"); + + w.onmessage = function(e) { + if (!resolve) { + ok(false, "Unexpected message!"); + return; + } + + let tmp = resolve; + resolve = null; + tmp({ data: e.data, ports: e.ports }); + } + + runTests({ + clonableObjectsEveryWhere: true, + clonableObjectsSameProcess: false, + transferableObjects: false, + send: function(what, ports) { + return new Promise(function(r, rr) { + if (ports.length) { + rr(); + return; + } + + resolve = r; + bc.postMessage(what); + }); + }, + + finished: function() { + onmessage = null; + next(); + } + }); + } +} + +// PostMessage for MessagePort +function test_messagePort() { + info("Testing messagePort"); + + var mc = new MessageChannel(); + var resolve; + + mc.port2.onmessage = function(e) { + if (!resolve) { + ok(false, "Unexpected message!"); + return; + } + + let tmp = resolve; + resolve = null; + tmp({ data: e.data, ports: e.ports }); + } + + runTests({ + clonableObjectsEveryWhere: true, + clonableObjectsSameProcess: false, + transferableObjects: true, + send: function(what, ports) { + return new Promise(function(r, rr) { + resolve = r; + try { + mc.port1.postMessage(what, ports); + } catch(e) { + resolve = null; + rr(); + } + }); + }, + + finished: function() { + onmessage = null; + next(); + } + }); +} + +// PostMessage for MessagePort in Workers +function test_messagePort_inWorkers() { + info("Testing messagePort in workers"); + + var mc = new MessageChannel(); + var resolve; + + var w = new Worker('worker_postMessages.js'); + w.postMessage('messagePort', [ mc.port2 ]); + w.onmessage = function(e) { + is(e.data, 'ok', "Worker ready!"); + + w.onmessage = function(e) { + if (!resolve) { + ok(false, "Unexpected message!"); + return; + } + + let tmp = resolve; + resolve = null; + tmp({ data: e.data, ports: e.ports }); + } + + runTests({ + clonableObjectsEveryWhere: true, + clonableObjectsSameProcess: false, + transferableObjects: true, + send: function(what, ports) { + return new Promise(function(r, rr) { + resolve = r; + try { + mc.port1.postMessage(what, ports); + } catch(e) { + resolve = null; + rr(); + } + }); + }, + + finished: function() { + onmessage = null; + next(); + } + }); + } +} + +var tests = [ + setup_tests, + + create_fileList, + create_directory, + create_wasmModule, + + test_windowToWindow, + test_windowToIframe, + test_windowToCrossOriginIframe, + + test_workers, + + test_broadcastChannel, + test_broadcastChannel_inWorkers, + + test_messagePort, + test_messagePort_inWorkers, +]; + +function next() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +SimpleTest.waitForExplicitFinish(); +next(); +</script> +</body> +</html> diff --git a/dom/base/test/test_processing_instruction_update_stylesheet.xhtml b/dom/base/test/test_processing_instruction_update_stylesheet.xhtml new file mode 100644 index 0000000000..c921bcc1c2 --- /dev/null +++ b/dom/base/test/test_processing_instruction_update_stylesheet.xhtml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet href="data:text/css;charset=UTF-8,p{color:red}" type="text/css"?> +<!DOCTYPE html +PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" +"DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=888864 +--> +<head> + <title>Test for Bug 888864</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 888864 **/ + SimpleTest.waitForExplicitFinish(); + + function changeColorAndRun(callback) { + var piNode = document.firstChild; + piNode.data = 'href="data:text/css;charset=UTF-8,p{color:green}" type="text/css"'; + piNode.addEventListener("load", callback); + } + + function runTest() { + var previousColor = window.getComputedStyle(document.getElementById("display")). + getPropertyValue("color"); + changeColorAndRun(function() { + var afterChange = window.getComputedStyle(document.getElementById("display")). + getPropertyValue("color"); + isnot(previousColor, afterChange, + "Color of the p element should change."); + SimpleTest.finish(); + }); + } + ]]> +</script> +</head> +<body onload="runTest();"> +<p id="display">This changes color</p> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=888864">Mozilla Bug 888864</a> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_progress_events_for_gzip_data.html b/dom/base/test/test_progress_events_for_gzip_data.html new file mode 100644 index 0000000000..46a0489349 --- /dev/null +++ b/dom/base/test/test_progress_events_for_gzip_data.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test progess events in case of gzipped data.</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="onLoadData()"> +<script class="testbody" type="text/javascript">"use strict"; +SimpleTest.waitForExplicitFinish(); + +var url = "send_gzip_content.sjs"; +var loaded = 0; +var total = 0; + +function onProgress(e) { + if(e.lengthComputable) { + loaded = e.loaded; + total = e.total; + if (loaded > total) { + ok(false, "We have loaded more bytes (" + loaded + + ") than the total amount of bytes (" + total + + ") available!!!"); + } + } +} + +function onLoadData() { + var xhr = new XMLHttpRequest(); + xhr.addEventListener('progress', onProgress, false); + xhr.open('GET', url, true); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + is(loaded, total, "loaded should be equal to total"); + isnot(loaded, 0, "loaded should be bigger than 0"); + SimpleTest.finish(); + } + } + xhr.send(null); +} + +</script> +</body> +</html> diff --git a/dom/base/test/test_range_bounds.html b/dom/base/test/test_range_bounds.html new file mode 100644 index 0000000000..bebb81d8e5 --- /dev/null +++ b/dom/base/test/test_range_bounds.html @@ -0,0 +1,288 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=421640 +--> +<head> + <title>Test for Bug 396392</title> + <meta http-equiv="content-type" content="text/html; charset=UTF-8"> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396392">Mozilla Bug Range getClientRects and getBoundingClientRect</a> +<div id="content" style="font-family:monospace;font-size:12px;width:100px"> +<p>000000<span>0</span></p><div>00000<span>0</span></div><p>0000<span>0000</span>0000</p><div><span>000000000000 00000000000000 000000</span></div><div>000000000000 00000000000003 100305</div> +</div> +<div id="mixeddir" style="font-family:monospace;font-size:12px;width:100px"><span>english <bdo id="bdo" dir="rtl">rtl-overide english</bdo> word</span></div> +<div id="mixeddir2" style="font-family:monospace;font-size:12px"><span>english <bdo id="bdo2" dir="rtl">rtl-override english</bdo> word</span></div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var isLTR = true; +var isTransformed = false; + +function annotateName(name) { + return (isLTR ? 'isLTR ' : 'isRTL ') + + (isTransformed ? 'transformed ' : '') + name; +} + +function isEmptyRect(rect, name) { + name = annotateName(name); + is(rect.left, 0, name+'empty rect should have left = 0'); + is(rect.right, 0, name+'empty rect should have right = 0'); + is(rect.top, 0, name+'empty rect should have top = 0'); + is(rect.bottom, 0, name+'empty rect should have bottom = 0'); + is(rect.width, 0, name+'empty rect should have width = 0'); + is(rect.height, 0, name+'empty rect should have height = 0'); +} + +function isEmptyRectList(rectlist, name) { + name = annotateName(name); + is(rectlist.length, 0, name + 'empty rectlist should have zero rects'); +} + +// round coordinates to the nearest 1/256 of a pixel +function roundCoord(x) { + return Math.round(x * 256) / 256; +} + +function _getRect(r) { + if (r.length) //array + return "{left:"+roundCoord(r[0])+",right:"+roundCoord(r[1])+ + ",top:" +roundCoord(r[2])+",bottom:"+roundCoord(r[3])+ + ",width:"+roundCoord(r[4])+",height:"+roundCoord(r[5])+"}"; + else + return "{left:"+roundCoord(r.left)+",right:"+roundCoord(r.right)+ + ",top:"+roundCoord(r.top)+",bottom:"+roundCoord(r.bottom)+ + ",width:"+roundCoord(r.width)+",height:"+roundCoord(r.height)+"}"; +} + +function runATest(obj) { + var range = document.createRange(); + try { + range.setStart(obj.range[0],obj.range[1]); + if (obj.range.length>2) { + range.setEnd(obj.range[2]||obj.range[0], obj.range[3]); + } + //test getBoundingClientRect() + var rect = range.getBoundingClientRect(); + var testname = 'range.getBoundingClientRect for ' + obj.name; + if (obj.rect) { + is(_getRect(rect),_getRect(obj.rect), annotateName(testname)); + } else { + isEmptyRect(rect,testname+": "); + } + //test getClientRects() + var rectlist = range.getClientRects(); + testname = 'range.getClientRects for ' + obj.name; + if (!obj.rectList) { + //rectList is not specified, use obj.rect to figure out rectList + obj.rectList = obj.rect?[obj.rect]:[]; + } + if (!obj.rectList.length) { + isEmptyRectList(rectlist, testname+": "); + } else { + is(rectlist.length, obj.rectList.length, + annotateName(testname+' should return '+obj.rectList.length+' rects.')); + if(!obj.rectList.forEach){ + //convert RectList to a real array + obj.rectList=Array.prototype.slice.call(obj.rectList, 0); + } + obj.rectList.forEach(function(rect,i) { + is(_getRect(rectlist[i]),_getRect(rect), + annotateName(testname+": item at "+i)); + }); + } + } finally { + range.detach(); + } +} +/** Test for Bug 396392 **/ +function doTest(){ + var root = document.getElementById('content'); + var firstP = root.firstElementChild, spanInFirstP = firstP.childNodes[1], + firstDiv = root.childNodes[2], spanInFirstDiv = firstDiv.childNodes[1], + secondP = root.childNodes[3], spanInSecondP = secondP.childNodes[1], + secondDiv = root.childNodes[4], spanInSecondDiv = secondDiv.firstChild, + thirdDiv = root.childNodes[5]; + var firstPRect = firstP.getBoundingClientRect(), + spanInFirstPRect = spanInFirstP.getBoundingClientRect(), + firstDivRect = firstDiv.getBoundingClientRect(), + spanInFirstDivRect = spanInFirstDiv.getBoundingClientRect(), + secondPRect = secondP.getBoundingClientRect(), + secondDivRect = secondDiv.getBoundingClientRect(), + spanInSecondPRect = spanInSecondP.getBoundingClientRect(), + spanInSecondDivRect = spanInSecondDiv.getBoundingClientRect(), + spanInSecondDivRectList = spanInSecondDiv.getClientRects(); + var widthPerchar = spanInSecondPRect.width / spanInSecondP.firstChild.length; + var testcases = [ + {name:'nodesNotInDocument', range:[document.createTextNode('abc'), 1], + rect:null}, + {name:'collapsedInBlockNode', range:[firstP, 2], rect:null}, + {name:'collapsedAtBeginningOfTextNode', range:[firstP.firstChild, 0], + rect:[spanInFirstPRect.left - 6 * widthPerchar, + spanInFirstPRect.left - 6 * widthPerchar, spanInFirstPRect.top, + spanInFirstPRect.bottom, 0, spanInFirstPRect.height]}, + {name:'collapsedWithinTextNode', range:[firstP.firstChild, 1], + rect:[spanInFirstPRect.left - 5 * widthPerchar, + spanInFirstPRect.left - 5 * widthPerchar, + spanInFirstPRect.top, spanInFirstPRect.bottom, 0, spanInFirstPRect.height]}, + {name:'collapsedAtEndOfTextNode', range:[firstP.firstChild, 6], + rect:[spanInFirstPRect.left, spanInFirstPRect.left, + spanInFirstPRect.top, spanInFirstPRect.bottom, 0, spanInFirstPRect.height]}, + {name:'singleBlockNode', range:[root, 1, root, 2], rect:firstPRect}, + {name:'twoBlockNodes', range:[root, 1, root, 3], + rect:[firstPRect.left, firstPRect.right, firstPRect.top, + firstDivRect.bottom, firstPRect.width, + firstDivRect.bottom - firstPRect.top], + rectList:[firstPRect, firstDivRect]}, + {name:'endOfTextNodeToEndOfAnotherTextNodeInAnotherBlock', + range:[spanInFirstP.firstChild, 1, firstDiv.firstChild, 5], + rect:[spanInFirstDivRect.left - 5*widthPerchar, spanInFirstDivRect.left, + spanInFirstDivRect.top, spanInFirstDivRect.bottom, 5 * widthPerchar, + spanInFirstDivRect.height]}, + {name:'startOfTextNodeToStartOfAnotherTextNodeInAnotherBlock', + range:[spanInFirstP.firstChild, 0, firstDiv.firstChild, 0], + rect:[spanInFirstPRect.left, spanInFirstPRect.left + widthPerchar, spanInFirstPRect.top, + spanInFirstPRect.bottom, widthPerchar, spanInFirstPRect.height]}, + {name:'endPortionOfATextNode', range:[firstP.firstChild, 3, + firstP.firstChild, 6], + rect:[spanInFirstPRect.left - 3*widthPerchar, spanInFirstPRect.left, + spanInFirstPRect.top, spanInFirstPRect.bottom, 3*widthPerchar, spanInFirstPRect.height]}, + {name:'startPortionOfATextNode', range:[firstP.firstChild, 0, + firstP.firstChild, 3], + rect:[spanInFirstPRect.left - 6*widthPerchar, + spanInFirstPRect.left - 3*widthPerchar, spanInFirstPRect.top, + spanInFirstPRect.bottom, 3 * widthPerchar, spanInFirstPRect.height]}, + {name:'spanTextNodes', range:[secondP.firstChild, 1, secondP.lastChild, 1], + rect:[spanInSecondPRect.left - 3*widthPerchar, spanInSecondPRect.right + + widthPerchar, spanInSecondPRect.top, spanInSecondPRect.bottom, + spanInSecondPRect.width + 4*widthPerchar, spanInSecondPRect.height], + rectList:[[spanInSecondPRect.left - 3*widthPerchar, spanInSecondPRect.left, + spanInSecondPRect.top, spanInSecondPRect.bottom, 3 * widthPerchar, + spanInSecondPRect.height], + spanInSecondPRect, + [spanInSecondPRect.right, spanInSecondPRect.right + widthPerchar, + spanInSecondPRect.top, spanInSecondPRect.bottom, widthPerchar, + spanInSecondPRect.height]]} + ]; + testcases.forEach(runATest); + + // testcases that have different ranges in LTR and RTL + var directionDependentTestcases; + if (isLTR) { + directionDependentTestcases = [ + {name:'spanAcrossLines',range:[spanInSecondDiv.firstChild, 1, spanInSecondDiv.firstChild, 30], + rect: spanInSecondDivRect, + rectList:[[spanInSecondDivRectList[0].left+widthPerchar, + spanInSecondDivRectList[0].right, spanInSecondDivRectList[0].top, + spanInSecondDivRectList[0].bottom, spanInSecondDivRectList[0].width - widthPerchar, + spanInSecondDivRectList[0].height], + spanInSecondDivRectList[1], + [spanInSecondDivRectList[2].left, + spanInSecondDivRectList[2].right - 4 * widthPerchar, spanInSecondDivRectList[2].top, + spanInSecondDivRectList[2].bottom, + spanInSecondDivRectList[2].width - 4 * widthPerchar, + spanInSecondDivRectList[2].height]]}, + {name:'textAcrossLines',range:[thirdDiv.firstChild, 13, thirdDiv.firstChild, 28], + rect: [spanInSecondDivRectList[1].left, spanInSecondDivRectList[1].right, + spanInSecondDivRectList[1].top + secondDivRect.height, + spanInSecondDivRectList[1].bottom + secondDivRect.height, + spanInSecondDivRectList[1].width, spanInSecondDivRectList[1].height]} + ]; + } else { + directionDependentTestcases = [ + {name:'spanAcrossLines',range:[spanInSecondDiv.firstChild, 1, spanInSecondDiv.firstChild, 30], + rect: spanInSecondDivRect, + rectList:[[spanInSecondDivRectList[0].left+widthPerchar, + spanInSecondDivRectList[0].right, spanInSecondDivRectList[0].top, + spanInSecondDivRectList[0].bottom, spanInSecondDivRectList[0].width - widthPerchar, + spanInSecondDivRectList[0].height], + spanInSecondDivRectList[1], + spanInSecondDivRectList[2], + spanInSecondDivRectList[3], + [spanInSecondDivRectList[4].left, + spanInSecondDivRectList[4].right - 4 * widthPerchar, + spanInSecondDivRectList[4].top, + spanInSecondDivRectList[4].bottom, + spanInSecondDivRectList[4].width - 4 * widthPerchar, + spanInSecondDivRectList[4].height]]}, + {name:'textAcrossLines',range:[thirdDiv.firstChild, 13, thirdDiv.firstChild, 28], + rect: [spanInSecondDivRectList[2].left, spanInSecondDivRectList[2].right, + spanInSecondDivRectList[2].top + secondDivRect.height, + spanInSecondDivRectList[2].bottom + secondDivRect.height, + spanInSecondDivRectList[2].width, spanInSecondDivRectList[2].height], + rectList:[[spanInSecondDivRectList[2].left, spanInSecondDivRectList[2].right, + spanInSecondDivRectList[2].top + secondDivRect.height, + spanInSecondDivRectList[2].bottom + secondDivRect.height, + spanInSecondDivRectList[2].width, spanInSecondDivRectList[2].height], + [spanInSecondDivRectList[2].left, spanInSecondDivRectList[2].left, + spanInSecondDivRectList[2].top + secondDivRect.height, + spanInSecondDivRectList[2].bottom + secondDivRect.height, + 0, spanInSecondDivRectList[2].height]]} + ]; + } + directionDependentTestcases.forEach(runATest); +} +function testMixedDir(){ + var root = document.getElementById('mixeddir'); + var firstSpan = root.firstElementChild, firstSpanRect=firstSpan.getBoundingClientRect(), + firstSpanRectList = firstSpan.getClientRects(); + runATest({name:'mixeddir',range:[firstSpan.firstChild,0,firstSpan.lastChild,firstSpan.lastChild.length], + rect: firstSpanRect, rectList:firstSpanRectList}); + + root = document.getElementById('mixeddir2'); + firstSpan = root.firstElementChild; + firstSpanRect = firstSpan.getBoundingClientRect(); + bdo = document.getElementById('bdo2'); + bdoRect=bdo.getBoundingClientRect(); + var widthPerChar = bdoRect.width / bdo.firstChild.length; + runATest({name:'mixeddirPartial', range:[firstSpan.firstChild, 3, + bdo.firstChild, 7], + rect: [firstSpanRect.left + 3*widthPerChar, bdoRect.right, + bdoRect.top, bdoRect.bottom, + (firstSpan.firstChild.length + bdo.firstChild.length - 3) * + widthPerChar, + bdoRect.height], + rectList:[[firstSpanRect.left + 3*widthPerChar, + bdoRect.left, + firstSpanRect.top, firstSpanRect.bottom, + (firstSpan.firstChild.length - 3) * widthPerChar, + firstSpanRect.height], + [bdoRect.right - 7 * widthPerChar, bdoRect.right, + bdoRect.top, bdoRect.bottom, + 7*widthPerChar, bdoRect.height]]}); +} +function test(){ + //test ltr + doTest(); + + //test rtl + isLTR = false; + var root = document.getElementById('content'); + root.dir = 'rtl'; + doTest(); + isLTR = true; + root.dir = 'ltr'; + + testMixedDir(); + + //test transforms + isTransformed = true; + root.style.transform = "translate(30px,50px)"; + doTest(); + + SimpleTest.finish(); +} + +window.onload = function() { + SimpleTest.waitForExplicitFinish(); + setTimeout(test, 0); +}; + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_reentrant_flush.html b/dom/base/test/test_reentrant_flush.html new file mode 100644 index 0000000000..fe1088526e --- /dev/null +++ b/dom/base/test/test_reentrant_flush.html @@ -0,0 +1,61 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=709256 +--> +<head> + <title>Test for Bug 709256</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=709256">Mozilla Bug 709256</a> +<p id="display"> +<iframe id="test" + style="width: 100px" src="data:text/html,<body style='width: 100%'>"> +</iframe> +</p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 709256 **/ +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function() { + var ifr = $("test"); + var bod = ifr.contentDocument.body; + + is(bod.getBoundingClientRect().width, 100, + "Width of body should be 100px to start with"); + + var resizeHandlerRan = false; + + function handleResize() { + resizeHandlerRan = true; + is(bod.getBoundingClientRect().width, 50, + "Width of body should now be 50px"); + } + + var win = ifr.contentWindow; + + win.addEventListener("resize", handleResize, false); + SpecialPowers.setFullZoom(win, 2); + + is(resizeHandlerRan, false, + "Resize handler should not have run yet for this test to be valid"); + + // Now flush out layout on the subdocument, to trigger the resize handler + is(bod.getBoundingClientRect().width, 50, "Width of body should still be 50px"); + + is(resizeHandlerRan, true, "Resize handler should have run"); + + win.removeEventListener("resize", handleResize, false); + + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_referrer_redirect.html b/dom/base/test/test_referrer_redirect.html new file mode 100644 index 0000000000..b5d968b6f9 --- /dev/null +++ b/dom/base/test/test_referrer_redirect.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta charset="utf-8"> + <title>Test anchor and area policy attribute for Bug 1184781</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + + <!-- + Testing referrer headers after redirects. + https://bugzilla.mozilla.org/show_bug.cgi?id=1184781 + --> + + <script type="application/javascript;version=1.8"> + + const SJS = "://example.com/tests/dom/base/test/referrer_testserver.sjs?"; + const PARAMS = ["ATTRIBUTE_POLICY", "NEW_ATTRIBUTE_POLICY", "META_POLICY"]; + + const testCases = [ + {ACTION: ["generate-img-redirect-policy-test", "generate-iframe-redirect-policy-test"], + TESTS: [ + { + ATTRIBUTE_POLICY: "no-referrer", + NAME: "no-referrer-with-no-meta", + DESC: "no-referrer (img/iframe) with no meta", + RESULT: "none" + }, + { + ATTRIBUTE_POLICY: "origin", + NAME: "origin-with-no-meta", + DESC: "origin (img/iframe) with no meta", + RESULT: "origin" + }, + { + ATTRIBUTE_POLICY: "unsafe-url", + NAME: "unsafe-url-with-no-meta", + DESC: "unsafe-url (img/iframe) with no meta", + RESULT: "full" + }, + { + META_POLICY: "unsafe-url", + NAME: "unsafe-url-in-meta", + DESC: "unsafe-url in meta", + RESULT: "full" + }, + { + META_POLICY: "origin", + NAME: "origin-in-meta", + DESC: "origin in meta", + RESULT: "origin" + }, + { + META_POLICY: "no-referrer", + NAME: "no-referrer-in-meta", + DESC: "no-referrer in meta", + RESULT: "none" + }, + { + META_POLICY: "origin-when-cross-origin", + NAME: "origin-when-cross-origin-in-meta", + DESC: "origin-when-cross-origin in meta", + RESULT: "origin" + }]} + ]; + </script> + <script type="application/javascript;version=1.7" src="/tests/dom/base/test/referrer_helper.js"></script> +</head> +<body onload="tests.next();"> + <iframe id="testframe"></iframe> +</body> +</html> + diff --git a/dom/base/test/test_root_iframe.html b/dom/base/test/test_root_iframe.html new file mode 100644 index 0000000000..ce99cc228d --- /dev/null +++ b/dom/base/test/test_root_iframe.html @@ -0,0 +1,27 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=511084 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 511084</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=511084">Mozilla Bug 511084</a> +<p id="display"><iframe></iframe></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> + <script type="application/javascript"> + /** Test for Bug 511084 **/ + var doc = frames[0].document; + doc.replaceChild(doc.createElement("iframe"), doc.documentElement); + ok(frames[0][0] instanceof Window, + "Should have a subframe window for a root iframe"); + </script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_sandboxed_blob_uri.html b/dom/base/test/test_sandboxed_blob_uri.html new file mode 100644 index 0000000000..8b94d72730 --- /dev/null +++ b/dom/base/test/test_sandboxed_blob_uri.html @@ -0,0 +1,24 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for Principal in MessageManager</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +</head> +<body> + + <script type="application/javascript;version=1.7"> + "use strict"; + + const Cu = Components.utils; + + var sb = new Cu.Sandbox('https://example.com', { wantGlobalProperties: [ 'Blob', 'URL' ] }); + Cu.evalInSandbox('var u = URL.createObjectURL(new Blob(["text"], { type: "text/plain" }));', sb); + Cu.nukeSandbox(sb); + Cu.forceCC(); + + ok(true, "are we leaking blobs?"); + + </script> +</body> +</html> diff --git a/dom/base/test/test_screen_orientation.html b/dom/base/test/test_screen_orientation.html new file mode 100644 index 0000000000..ea3016eef9 --- /dev/null +++ b/dom/base/test/test_screen_orientation.html @@ -0,0 +1,86 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=760735 +--> +<head> + <meta charset="utf-8"> + <title>Test for Screen Orientation API</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=760735">Screen Orientation API</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Tests for Screen Orientation API **/ + +// Screen Orientation API testing is problematic in that not every platform +// supports orientation-locking, and locking requires running in full-screen. +// So for now, only negative/sanity testing is done here, as that works globally. + +function unexpectedEvent(event) { + ok(false, "No unexpected orientation change events received"); +} + +window.screen.addEventListener("mozorientationchange", unexpectedEvent); +try { + const allowedOrientations = ["portrait-primary", "portrait-secondary", + "landscape-primary", "landscape-secondary"]; + + var initialOrientation = window.screen.mozOrientation; + + // Sanity tests + isnot(allowedOrientations.indexOf(initialOrientation), -1, + "mozOrientation is valid (value=" + initialOrientation + ")"); + + // Negative tests + ok(!window.screen.mozLockOrientation("Foobar-Bazbam"), "Cannot lock to an invalid string"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(""), "Cannot lock to an empty string"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(["Foobar", "Bazbam"]), "Cannot lock to an invalid string"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(["foo"]), "Cannot lock to an invalid string"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation([""]), "Cannot lock to an empty string"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(42), "Cannot lock to a number"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(undefined), "Cannot lock to undefined"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(null), "Cannot lock to null"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation({}), "Cannot lock to a non-Array object"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(["Foobar", 42]), "Cannot lock to a number"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(["Foobar", null]), "Cannot lock to null"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); + + ok(!window.screen.mozLockOrientation(["Foobar", undefined]), "Cannot lock to undefined"); + is(window.screen.mozOrientation, initialOrientation, "Orientation is unchanged"); +} catch (e) { + ok(false, "Got unexpected exception: " + e); +} finally { + window.screen.removeEventListener("mozorientationchange", unexpectedEvent); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_script_loader_crossorigin_data_url.html b/dom/base/test/test_script_loader_crossorigin_data_url.html new file mode 100644 index 0000000000..cfbb90c8df --- /dev/null +++ b/dom/base/test/test_script_loader_crossorigin_data_url.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for handling of 'crossorigin' attribute on script with data: URL</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> + // We're going to mess with window.onerror. + setup({ allow_uncaught_exception: true }); +</script> +<!-- First check that data: scripts with @crossorigin run at all --> +<script> + var ran = false; +</script> +<script crossorigin src="data:application/javascript,ran = true"></script> +<script> +test(function() { + assert_true(ran); +}, "script@crossorigin with data: src should have run"); +</script> +<!-- Then check that their syntax errors are not sanitized --> +<script> +var errorFired = false; +ran = false; +window.onerror = function(message, uri, line) { + errorFired = true; + test(function() { + assert_equals(line, 3); + }, "Should have a useful line number for exception in script@crossorigin with data: src"); +} +</script> +<script crossorigin src="data:application/javascript,var%20a;%0aran=true%0anoSuchFunctionHere()"></script> +<script> + test(function() { + assert_true(ran, "Script with error should have run"); + assert_true(errorFired, "Script with error should have fired onerror"); + }, "Should run and correctly fire onerror"); +</script> diff --git a/dom/base/test/test_sendQueryContentAndSelectionSetEvent.html b/dom/base/test/test_sendQueryContentAndSelectionSetEvent.html new file mode 100644 index 0000000000..369ed1c9da --- /dev/null +++ b/dom/base/test/test_sendQueryContentAndSelectionSetEvent.html @@ -0,0 +1,250 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for nsIDOMWindowUtils.sendQueryContentEvent() and .sendSelectionSetEvent()</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<div id="editor" contenteditable>abc<br>def</div> +<pre id="test"> +<script type="application/javascript"> + +var editor = document.getElementById("editor"); + +SimpleTest.waitForExplicitFinish(); + +const kIsWin = navigator.platform.indexOf("Win") == 0; +const kIsMac = navigator.platform.indexOf("Mac") == 0; + +const kLineBreak = kIsWin ? "\r\n" : "\n"; + +var gUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindowUtils); + +function escape(aStr) +{ + var result = aStr.replace("\n", "\\n"); + return result.replace("\r", "\\r"); +} + +function runTests() +{ + editor.focus(); + + // NOTE: For compatibility, calling without flags should work as with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK. + + // QueryTextContent + var expectedStr = escape(("abc" + kLineBreak + "def").substr(2, 4)); + var result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_CONTENT, 2, 4, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + is(escape(result.text), expectedStr, + "sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) got unexpected string"); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_CONTENT, 2, 4, 0, 0); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_TEXT_CONTENT) should succeed"); + is(escape(result.text), expectedStr, + "sendQueryContentEvent(QUERY_TEXT_CONTENT) should return same string as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + + expectedStr = escape(("abc\ndef").substr(2, 4)); + result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_CONTENT, 2, 4, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed"); + is(escape(result.text), expectedStr, + "sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) got unexpected string"); + + // QueryCaretRect + window.getSelection().collapse(editor.firstChild, 0); + + var caretNative = gUtils.sendQueryContentEvent(gUtils.QUERY_CARET_RECT, 6, 0, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK); + ok(caretNative.succeeded, + "sendQueryContentEvent(QUERY_CARET_RECT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + var caretXP = gUtils.sendQueryContentEvent(gUtils.QUERY_CARET_RECT, 6 - kLineBreak.length + 1, 0, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); + ok(caretXP.succeeded, + "sendQueryContentEvent(QUERY_CARET_RECT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed"); + + is(caretXP.top, caretNative.top, + "The caret top should be same"); + is(caretXP.left, caretNative.left, + "The caret left should be same"); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_CARET_RECT, 6, 0, 0, 0); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_CARET_RECT) should succeed"); + is(result.top, caretNative.top, + "sendQueryContentEvent(QUERY_CARET_RECT) should return same top as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.left, caretNative.left, + "sendQueryContentEvent(QUERY_CARET_RECT) should return same left as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + + // QueryTextRect + var textRectNative = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 6, 1, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK); + ok(textRectNative.succeeded, + "sendQueryContentEvent(QUERY_TEXT_RECT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + var textRectXP = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 6 - kLineBreak.length + 1, 1, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); + ok(textRectXP.succeeded, + "sendQueryContentEvent(QUERY_TEXT_RECT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed"); + + is(textRectXP.top, textRectNative.top, + "The text top should be same"); + is(textRectXP.left, textRectNative.left, + "The text left should be same"); + is(textRectXP.height, textRectNative.height, + "The text height should be same"); + is(textRectXP.width, textRectNative.width, + "The text width should be same"); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 6, 1, 0, 0); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_TEXT_RECT) should succeed"); + is(result.top, textRectNative.top, + "sendQueryContentEvent(QUERY_TEXT_RECT) should return same top as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.left, textRectNative.left, + "sendQueryContentEvent(QUERY_TEXT_RECT) should return same left as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.height, textRectNative.height, + "sendQueryContentEvent(QUERY_TEXT_RECT) should return same height as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.width, textRectNative.width, + "sendQueryContentEvent(QUERY_TEXT_RECT) should return same width as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + + // QueryTextRectArray + var textRectArray = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT_ARRAY, 1, 2, 0, 0); + ok(textRectArray.succeeded, + "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should succeed"); + var textRect = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 1, 2, 0, 0); + ok(textRect.succeeded, + "sendQueryContentEvent(QUERY_TEXT_RECT) should succeed"); + var left = {}; + var top = {}; + var width = {}; + var height = {}; + var left2 = {}; + var top2 = {}; + var width2 = {}; + var height2 = {}; + textRectArray.getCharacterRect(0, left, top, width, height); + ok(textRect.top, top.value, + "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same top that returns QUERY_TEXT_RECT"); + ok(textRect.left, left.value, + "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same left that returns QUERY_TEXT_RECT"); + textRectArray.getCharacterRect(1, left2, top2, width2, height2); + ok(textRect.width, width.value + width2.value, + "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same width that QUERY_TEXT_RECT is returned for offset 1 and 2"); + ok(textRect.height, height.value, + "sendQueryContentEvent(QUERY_TEXT_RECT_ARRAY) should return same height that returns QUERY_TEXT_RECT"); + + // QueryCharacterAtOffset + result = gUtils.sendQueryContentEvent(gUtils.QUERY_CHARACTER_AT_POINT, 0, 0, textRectNative.left + 1, textRectNative.top + 1, + gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_CHARACTER_AT_POINT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + is(result.top, textRectNative.top, + "The character top is wrong"); + is(result.left, textRectNative.left, + "The character left is wrong"); + is(result.height, textRectNative.height, + "The character height is wrong"); + is(result.width, textRectNative.width, + "The character width is wrong"); + is(result.offset, 6, + "The character offset is wrong"); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_CHARACTER_AT_POINT, 0, 0, textRectNative.left + 1, textRectNative.top + 1); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_CHARACTER_AT_POINT) should succeed"); + is(result.top, textRectNative.top, + "The character top should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.left, textRectNative.left, + "The character left should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.height, textRectNative.height, + "The character height should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.width, textRectNative.width, + "The character width should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + is(result.offset, 6, + "The character offset should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK"); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_CHARACTER_AT_POINT, 0, 0, textRectXP.left + 1, textRectXP.top + 1, + gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_CHARACTER_AT_POINT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed"); + is(result.top, textRectXP.top, + "The character top is wrong"); + is(result.left, textRectXP.left, + "The character left is wrong"); + is(result.height, textRectXP.height, + "The character height is wrong"); + is(result.width, textRectXP.width, + "The character width is wrong"); + is(result.offset, 6 - kLineBreak.length + 1, + "The character offset is wrong"); + + // SelectionSet and QuerySelectedText + var selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK); + ok(selectionSet, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + expectedStr = escape(("abc" + kLineBreak + "def").substr(0, 6)); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + ok(!result.reversed, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK) should set non-reversed selection"); + is(escape(result.text), expectedStr, + "sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) got unexpected string"); + + selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_XP_LINE_BREAK); + ok(selectionSet, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK) should succeed"); + expectedStr = escape(("abc\ndef").substr(0, 6)); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed"); + ok(!result.reversed, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK) should set non-reversed selection"); + is(escape(result.text), expectedStr, + "sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) got unexpected string"); + + var selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK | gUtils.SELECTION_SET_FLAG_REVERSE); + ok(selectionSet, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed"); + ok(result.reversed, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK | SELECTION_SET_FLAG_REVERSE) should set reversed selection"); + + selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_XP_LINE_BREAK | gUtils.SELECTION_SET_FLAG_REVERSE); + ok(selectionSet, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK | SELECTION_SET_FLAG_REVERSE) should succeed"); + + result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0, + gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK); + ok(result.succeeded, + "sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed"); + ok(result.reversed, + "sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK | SELECTION_SET_FLAG_REVERSE) should set reversed selection"); + + SimpleTest.finish(); +} + +SimpleTest.waitForFocus(runTests); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_setInterval_uncatchable_exception.html b/dom/base/test/test_setInterval_uncatchable_exception.html new file mode 100644 index 0000000000..70a1d96c08 --- /dev/null +++ b/dom/base/test/test_setInterval_uncatchable_exception.html @@ -0,0 +1,55 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1252268 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1252268</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1252268">Mozilla Bug 1252268</a> + +<script type="text/javascript"> + function go() { + SimpleTest.requestFlakyTimeout("I'm smarter than the test harness"); + + var ranOnce = false; + var finished = false; + + var interval = setInterval(function () { + if (ranOnce) { + ok(false, "Don't execute me again!"); + clearInterval(interval); + if (!finished) { + finished = true; + SimpleTest.finish(); + } + } else { + ranOnce = true; + ok(true, "Ran the first time"); + try { + TestFunctions.throwUncatchableException(); + ok(false, "How did we get here!"); + } catch (e) { + ok(false, "How did we get here!?"); + } + } + }, 100); + + setTimeout(function() { + if (!finished) { + finished = true; + SimpleTest.finish(); + } + }, 1000); + } + + SimpleTest.waitForExplicitFinish(); + SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go); +</script> + +</body> +</html> diff --git a/dom/base/test/test_setTimeoutWith0.html b/dom/base/test/test_setTimeoutWith0.html new file mode 100644 index 0000000000..71e653da70 --- /dev/null +++ b/dom/base/test/test_setTimeoutWith0.html @@ -0,0 +1,22 @@ +<html> +<head> + <title>Test for setTimeout and strings containing 0</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script> + +var x = 0; +setTimeout("x++; '\x00'; x++;"); +setTimeout(function() { + is(x, 2, "We want to see 2 here"); + SimpleTest.finish(); +}); + +SimpleTest.waitForExplicitFinish(); +</script> +</body> +</html> + + diff --git a/dom/base/test/test_settimeout_extra_arguments.html b/dom/base/test/test_settimeout_extra_arguments.html new file mode 100644 index 0000000000..b790eff069 --- /dev/null +++ b/dom/base/test/test_settimeout_extra_arguments.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for setTimeout with a string argument and more than 2 arguments</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> + t1 = async_test("setTimeout with more than 2 arguments, first argument a string, should work"); + t2 = async_test("setInterval with more than 2 arguments, first argument a string, should work"); + setTimeout("t1.done()", 0, {}); + var interval = setInterval("clearInterval(interval); t2.done()", 0, {}); +</script> diff --git a/dom/base/test/test_settimeout_inner.html b/dom/base/test/test_settimeout_inner.html new file mode 100644 index 0000000000..b0e6a9d4e0 --- /dev/null +++ b/dom/base/test/test_settimeout_inner.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=936129 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 936129</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 936129 **/ + SimpleTest.waitForExplicitFinish(); + + function test1Done() + { + ok(true, "Bareword setTimeout should work after calling document.open()."); + + var iframe = document.getElementById("testFrame"); + iframe.onload = function () { + window.runTest2 = iframe.contentWindow.runTest2; + iframe.onload = function () { + window.runTest2(); + setTimeout(allDone); + } + iframe.src = "about:blank"; + } + iframe.src = "data:text/html,<script>function runTest2() { setTimeout('parent.test2Done()'); };<" + "/script>"; + } + window.test2DoneCalled = false; + function test2Done() + { + window.test2DoneCalled = true; + } + function allDone() + { + ok(!window.test2DoneCalled, "Bareword setTimeout should be a noop after the document for the window context that it's called on isn't active anymore."); + + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=936129">Mozilla Bug 936129</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe id="testFrame" src="data:text/html,<script>window.onload = function runTest1() { document.open(); setTimeout('parent.test1Done();'); document.close(); }</script>"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_setting_opener.html b/dom/base/test/test_setting_opener.html new file mode 100644 index 0000000000..babdf85705 --- /dev/null +++ b/dom/base/test/test_setting_opener.html @@ -0,0 +1,125 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=868996 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 868996</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 868996 **/ + SimpleTest.waitForExplicitFinish(); + + var sb1, sb2; + var Cu = SpecialPowers.Cu; + + function testOpenerSet() { + // Use setTimeout to make the relevant onerror run in this window + var win = window.open("data:text/html,<script>opener.setTimeout(opener.basicOpenerTest, 0, this)</" + "script>"); + // A sandbox for the window + sb1 = new Cu.Sandbox(win, {wantXrays: true }) + sb1.win = win + // And a sandbox using the expanded principal. + sb2 = new Cu.Sandbox([win], {wantXrays: true }) + sb2.win = win + } + + function evalsb(str, sb) { + // Have to unwrap() to get objects we care about + return SpecialPowers.unwrap(Cu.evalInSandbox(str, sb)); + } + + function basicOpenerTest(win) { + is(win.opener, window, "Opening a window should give it the right opener"); + is(evalsb("win.opener", sb1), window, + "Reading opener in sandbox 1 should work"); + is(evalsb("win.opener", sb2), window, + "Reading opener in sandbox 2 should work"); + + win.opener = $("x").contentWindow; + evalsb("win.opener = win.opener.document.getElementById('y').contentWindow", sb1); + evalsb("win.opener = win.opener.document.getElementById('z').contentWindow", sb2); + + is(win.opener, $("x").contentWindow, "Should be able to set an opener to a different window"); + is(evalsb("win.opener", sb1), $("y").contentWindow, + "Should be able to set the opener to a different window in a sandbox one"); + is(evalsb("win.opener", sb2), $("z").contentWindow, + "Should be able to set the opener to a different window in a sandbox two"); + + win.location = "data:text/html,<script>opener.setTimeout(opener.continueOpenerTest, 0, this);</" + "script>"; + } + + function continueOpenerTest(win) { + is(win.opener, window, "Navigating a window should have reset the opener we stashed on it temporarily"); + is(evalsb("win.opener", sb1), window, + "Navigating a window should have reset the opener in sb1"); + is(evalsb("win.opener", sb2), window, + "Navigating a window should have reset the opener in sb2"); + + win.opener = 5; + evalsb("win.opener = 5", sb1); + evalsb("win.opener = 5", sb2); + is(win.opener, 5, "Should be able to set an opener to a primitive"); + is(evalsb("win.opener", sb1), 5, + "Should be able to set the opener to a primitive in a sandbox one"); + is(evalsb("win.opener", sb2), 5, + "Should be able to set the opener to a primitive in a sandbox two"); + win.location = "data:text/html,<script>opener.setTimeout(opener.continueOpenerTest2, 0, this);</" + "script>"; + } + + function continueOpenerTest2(win) { + is(win.opener, window, + "Navigating a window again should have reset the opener we stashed on it temporarily"); + is(evalsb("win.opener", sb1), window, + "Navigating a window again should have reset the opener in sb1"); + is(evalsb("win.opener", sb2), window, + "Navigating a window again should have reset the opener in sb2"); + + win.opener = null; + is(win.opener, null, "Should be able to set the opener to null"); + is(evalsb("win.opener", sb1), null, + "Setting the opener to null should be visible in sb1"); + is(evalsb("win.opener", sb2), null, + "Setting the opener to null should be visible in sb2"); + + win.location = "data:text/html,Loaded"; + // Now poll for that load, since we have no way for the window to + // communicate with us now + setTimeout(checkForLoad, 0, win); + } + + function checkForLoad(win) { + if (!win.document.documentElement || + win.document.documentElement.textContent != "Loaded") { + setTimeout(checkForLoad, 0, win); + return; + } + + is(win.opener, null, "Null opener should persist across navigations"); + is(evalsb("win.opener", sb1), null, + "Null opener should persist across navigations in sb1"); + is(evalsb("win.opener", sb2), null, + "Null opener should persist across navigations in sb2"); + + win.close(); + SimpleTest.finish(); + } + + addLoadEvent(testOpenerSet); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868996">Mozilla Bug 868996</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe id="x"></iframe> +<iframe id="y"></iframe> +<iframe id="z"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_simplecontentpolicy.html b/dom/base/test/test_simplecontentpolicy.html new file mode 100644 index 0000000000..9fa5dd3fdb --- /dev/null +++ b/dom/base/test/test_simplecontentpolicy.html @@ -0,0 +1,149 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for nsISimpleContentPolicy</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1128798">Mozilla Bug 1128798</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var lastContentType = -1; +const testURL = window.location.href + "/this/is/the/test/url"; +const Cc = SpecialPowers.Cc; +const Ci = SpecialPowers.Ci; + +var beaconUrl = "http://mochi.test:8888/tests/dom/tests/mochitest/beacon/beacon-handler.sjs"; + +var chromeURL = SimpleTest.getTestFileURL("file_simplecontentpolicy.js"); +var script = SpecialPowers.loadChromeScript(chromeURL); + +// Try creating different request types. Most of these are not +// top-level because they run in the test iframe. +var tests = [["SCRIPT", false], + ["IMAGE", false], + ["STYLESHEET", false], + ["OBJECT", false], + ["DOCUMENT", true], + ["SUBDOCUMENT", false], + ["XBL", false], + ["XMLHTTPREQUEST", false], + ["BEACON", false]]; +var curTest = -1; + +var div; + +SimpleTest.waitForExplicitFinish(); + +script.addMessageListener("ready", function(msg) { + SpecialPowers.pushPrefEnv({'set': [["beacon.enabled", true]]}, runNextTest); +}); + +script.addMessageListener("shouldLoad", function(msg) { + var isTopLevel = tests[curTest][1]; + var type = "TYPE_" + tests[curTest][0]; + is(msg.contentType, Ci.nsIContentPolicy[type], "Content policies triggered for " + type); + is(msg.isTopLevel, isTopLevel, "isTopLevel is set correctly"); + + if (tests[curTest] == "XBL") { + //XXX Removing binding to work-around a memory leak (bugs 478528, 499735). + div.style.MozBinding = ""; + } + + runNextTest(); +}); + +function runNextTest() { + curTest++; + if (curTest < tests.length) { + var method = "request_" + tests[curTest][0].toLowerCase(); + try { + window[method](); + } catch(e) {} + } + else { + script.sendAsyncMessage("finished"); + + SimpleTest.finish(); + } +} + +// Request creating functions + +function request_script() { + var content = $("content"); + +Math.sin(1); + var script = document.createElement("script"); + script.setAttribute("type", "text/javascript") + script.setAttribute("src", testURL) + content.appendChild(script); +} + +function request_image() { + var content = $("content"); + + var image = new Image(); + image.src = testURL; +} + +function request_stylesheet() { + var content = $("content"); + + var stylesheet = document.createElement("link"); + stylesheet.setAttribute("rel", "stylesheet"); + stylesheet.setAttribute("type", "text/css"); + stylesheet.setAttribute("href", testURL); + content.appendChild(stylesheet); +} + +function request_object() { + var content = $("content"); + + var object = document.createElement("embed"); + object.setAttribute("src", testURL); + content.appendChild(object); +} + +function request_document() { + top.location.href = testURL; +} + +function request_subdocument() { + var content = $("content"); + + var frame = document.createElement("iframe"); + frame.setAttribute("src", testURL); + content.appendChild(frame); +} + +function request_xbl() { + var content = $("content"); + + div = document.createElement("div"); + div.style.MozBinding = "url(" + testURL + ")"; + $('test').appendChild(div); + div.offsetLeft; // Flush styles. +} + +function request_xmlhttprequest() { + var request = new XMLHttpRequest(); + request.open("GET", testURL, false); + request.send(null); +} + +function request_beacon() { + navigator.sendBeacon(testURL, "bacon would have been a better name than beacon"); +} + +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_text_wholeText.html b/dom/base/test/test_text_wholeText.html new file mode 100644 index 0000000000..31fa0f0766 --- /dev/null +++ b/dom/base/test/test_text_wholeText.html @@ -0,0 +1,232 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=421765 +--> +<head> + <title>Text.wholeText tests</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=421765">Mozilla Bug 421765</a> +<p id="display"></p> +<div id="content" style="display: none"></div> + +<iframe id="xmlDocument" src="wholeTexty-helper.xml"></iframe> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +/** Test for Bug 421765 **/ + +SimpleTest.waitForExplicitFinish(); + +var xmlDoc; + +function text(t) { return document.createTextNode(t); } +function element() { return document.createElement("div"); } +function cdata(t) +{ + xmlDoc = $("xmlDocument").contentDocument; + // document.createCDATASection isn't implemented; clone for the win + var node = xmlDoc.documentElement.firstChild.cloneNode(false); + is(node.nodeType, Node.CDATA_SECTION_NODE, + "er, why isn't this a CDATA section node?"); + node.data = t; + return node; +} + + +function firstTests() +{ + var outer = element(); + var first = text("first"); + var second = element(); + second.appendChild(text("element contents")); + outer.appendChild(first); + outer.appendChild(second); + + is(first.wholeText, "first", "wrong wholeText for first"); + + var insertedText = text("-continued"); + outer.insertBefore(insertedText, second); + + is(first.wholeText, "first-continued", + "wrong wholeText for first after insertedText insertion"); + is(insertedText.wholeText, "first-continued", + "wrong wholeText for insertedText after insertedText insertion"); + + var cdataNode = cdata("zero-") + outer.insertBefore(cdataNode, first); + + is(first.wholeText, "zero-first-continued", + "wrong wholeText for first after cdataNode insertion"); + is(cdataNode.wholeText, "zero-first-continued", + "wrong wholeText for cdataNode after cdataNode insertion"); + is(insertedText.wholeText, "zero-first-continued", + "wrong wholeText for insertedText after cdataNode insertion"); + + outer.insertBefore(element(), first); + + is(first.wholeText, "first-continued", + "wrong wholeText for first after element insertion"); + is(cdataNode.wholeText, "zero-", + "wrong wholeText for cdataNode after element insertion"); + is(insertedText.wholeText, "first-continued", + "wrong wholeText for insertedText after element insertion"); + + var cdataNode2 = cdata("-interrupted"); + outer.insertBefore(cdataNode2, insertedText); + + is(first.wholeText, "first-interrupted-continued", + "wrong wholeText for first after cdataNode2 insertion"); + is(cdataNode2.wholeText, "first-interrupted-continued", + "wrong wholeText for cdataNode2 after cdataNode2 insertion"); + is(insertedText.wholeText, "first-interrupted-continued", + "wrong wholeText for insertedText after cdataNode2 insertion"); +} + +function middleTests() +{ + var outer = element(); + var first = element(); + var last = element(); + var middle = text("middle"); + first.appendChild(text("first element contents")); + last.appendChild(text("last element contents")); + outer.appendChild(first); + outer.appendChild(middle); + outer.appendChild(last); + + is(middle.wholeText, "middle", "wrong wholeText for middle"); + + var beforeMiddle = text("before-"); + outer.insertBefore(beforeMiddle, middle); + + is(middle.wholeText, "before-middle", + "wrong wholeText for middle after beforeMiddle insertion"); + is(beforeMiddle.wholeText, "before-middle", + "wrong wholeText for beforeMiddle after beforeMiddle insertion"); + + var midElement = element(); + midElement.appendChild(text("middle element")); + outer.insertBefore(midElement, middle); + + is(middle.wholeText, "middle", + "wrong wholeText for middle after midElement insertion"); + is(beforeMiddle.wholeText, "before-", + "wrong wholeText for beforeMiddle after midElement insertion"); + + var cdataNode = cdata("after"); + outer.insertBefore(cdataNode, midElement); + + is(cdataNode.wholeText, "before-after", + "wrong wholeText for cdataNode after cdataNode insertion"); + is(beforeMiddle.wholeText, "before-after", + "wrong wholeText for beforeMiddle after cdataNode insertion"); + is(middle.wholeText, "middle", + "wrong wholeText for middle after cdataNode insertion"); + + var cdataNode2 = cdata("before-"); + outer.insertBefore(cdataNode2, middle); + + is(cdataNode.wholeText, "before-after", + "wrong wholeText for cdataNode after cdataNode2 insertion"); + is(beforeMiddle.wholeText, "before-after", + "wrong wholeText for beforeMiddle after cdataNode2 insertion"); + is(cdataNode2.wholeText, "before-middle", + "wrong wholeText for middle after cdataNode2 insertion"); + is(middle.wholeText, "before-middle", + "wrong wholeText for middle after cdataNode2 insertion"); +} + +function lastTests() +{ + var outer = element(); + var first = element(); + var second = text("second"); + first.appendChild(text("element contents")); + outer.appendChild(first); + outer.appendChild(second); + + is(second.wholeText, "second", "wrong wholeText for second"); + + var insertedText = text("before-"); + outer.insertBefore(insertedText, second); + + is(second.wholeText, "before-second", + "wrong wholeText for second after insertedText insertion"); + is(insertedText.wholeText, "before-second", + "wrong wholeText for insertedText after insertedText insertion"); + + var cdataNode = cdata("zero-") + outer.insertBefore(cdataNode, insertedText); + + is(cdataNode.wholeText, "zero-before-second", + "wrong wholeText for cdataNode after cdataNode insertion"); + is(second.wholeText, "zero-before-second", + "wrong wholeText for second after cdataNode insertion"); + is(insertedText.wholeText, "zero-before-second", + "wrong wholeText for insertedText after cdataNode insertion"); + + outer.insertBefore(element(), second); + + is(second.wholeText, "second", + "wrong wholeText for second after element insertion"); + is(cdataNode.wholeText, "zero-before-", + "wrong wholeText for cdataNode after element insertion"); + is(insertedText.wholeText, "zero-before-", + "wrong wholeText for insertedText after element insertion"); + + var cdataNode2 = cdata("interrupted-"); + outer.insertBefore(cdataNode2, insertedText); + + is(second.wholeText, "second", + "wrong wholeText for second after cdataNode2 insertion"); + is(cdataNode2.wholeText, "zero-interrupted-before-", + "wrong wholeText for cdataNode2 after cdataNode2 insertion"); + is(insertedText.wholeText, "zero-interrupted-before-", + "wrong wholeText for insertedText after cdataNode2 insertion"); +} + +function noParentTests() +{ + var textNode = text("foobar"); + is(textNode.wholeText, textNode.data, + "orphaned textNode should have wholeText == data"); + is(textNode.wholeText, "foobar", + "orphaned textNode should have wholeText == 'foobar'"); + + var cdataSection = cdata("baz"); + is(cdataSection.wholeText, cdataSection.data, + "orphaned cdatasection should have wholeText == data"); + is(cdataSection.wholeText, "baz", + "orphaned cdatasection should have wholeText == data"); +} + +function tests() +{ + try + { + firstTests(); + middleTests(); + lastTests(); + noParentTests(); + } + catch (e) + { + ok(false, "error thrown: " + e); + } + finally + { + SimpleTest.finish(); + } +} + +window.addEventListener("load", tests, false); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_textnode_normalize_in_selection.html b/dom/base/test/test_textnode_normalize_in_selection.html new file mode 100644 index 0000000000..f879732146 --- /dev/null +++ b/dom/base/test/test_textnode_normalize_in_selection.html @@ -0,0 +1,201 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=804784 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 804784</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=804784">Mozilla Bug 804784</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 804784 **/ + +var sel = document.getSelection(); +var flush = true; +var dry = true; +var run = ""; +var empty_range; +var empty_first_text_range; +var empty_last_text_range; +var full_range; + +function check(range, expected, test) +{ + is(""+range, expected, test); + is(""+empty_range, "", "empty range test after: "+test); + is(""+empty_first_text_range, "", "empty first text range test after: "+test); + if (empty_last_text_range) is(""+empty_last_text_range, "", "empty last text range test after: "+test); + is(""+full_range, full_range.startContainer.textContent, "full range test after: "+test); +} + +function newDiv() +{ + var div = document.createElement('div'); + for (var i = 0; i < arguments.length; ++i) { + div.appendChild(document.createTextNode(arguments[i])); + } + document.body.appendChild(div) + empty_range = document.createRange(); + empty_range.setStart(div,0); + empty_range.setEnd(div,0); + var firstTextNode = div.childNodes[0]; + var lastTextNode = div.childNodes[div.childNodes.length - 1]; + empty_first_text_range = document.createRange(); + empty_first_text_range.setStart(firstTextNode,0); + empty_first_text_range.setEnd(firstTextNode,0); + empty_last_text_range = null; + if (firstTextNode != lastTextNode) { + empty_last_text_range = document.createRange(); + empty_last_text_range.setStart(lastTextNode,0); + empty_last_text_range.setEnd(lastTextNode,0); + } + full_range = document.createRange(); + full_range.setStart(div,0); + full_range.setEnd(div,div.childNodes.length); + return div; +} + +function selEnd(div,child,index,s) +{ + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(start, index); + r.setEnd(div, div.childNodes.length); + if (!dry) div.normalize(); + check(r,s,run+" selEnd "+child+","+index); +} + +function selStart(div,child,index,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(div, 0); + r.setEnd(start, index); + if (!dry) div.normalize(); + check(r,s,run+" selStart "+child+","+index); +} + +function selMiddleStart(div,child,index,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(div, 1); + r.setEnd(start, index); + div.normalize(); + check(r,s,run+" selMiddleStart "+child+","+index); +} + +function selMiddleEnd(div,child,index,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(start, index); + r.setEnd(div, 2); + if (!dry) div.normalize(); + check(r,s,run+" selMiddleEnd "+child+","+index); +} + +function mergeBefore(div,child,index,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(div, 1); + r.setEnd(start, index); + if (!dry) div.normalize(); + check(r,s,run+" mergeBefore "+child+","+index); +} + +function runTests(s) +{ + run = s+":"; + selEnd(newDiv('111'), 0,0,'111'); + selEnd(newDiv('111'), 0,1,'11'); + selEnd(newDiv('111'), 0,2,'1'); + selEnd(newDiv(''), 0,0,''); + selEnd(newDiv('',''), 1,0,''); + selEnd(newDiv('','',''), 1,0,''); + selEnd(newDiv('111','222'), 0,1,'11222'); + selEnd(newDiv('111','222'), 0,2,'1222'); + selEnd(newDiv('111','222'), 1,1,'22'); + selEnd(newDiv('','222'), 1,2,'2'); + selEnd(newDiv('111',''), 0,1,'11'); + selEnd(newDiv('111','222'), 1,2,'2'); + selEnd(newDiv('111','222','333'), 1,1,'22333'); + selEnd(newDiv('111','222','333'), 1,2,'2333'); + selEnd(newDiv('111','','333'), 0,2,'1333'); + selEnd(newDiv('111','','333'), 1,0,'333'); + selEnd(newDiv('111','','333'), 2,0,'333'); + + selStart(newDiv('111'), 0,0,''); + selStart(newDiv('111'), 0,1,'1'); + selStart(newDiv('111'), 0,2,'11'); + selStart(newDiv(''), 0,0,''); + selStart(newDiv('111','222'), 0,1,'1'); + selStart(newDiv('111','222'), 0,2,'11'); + selStart(newDiv('111','222'), 1,1,'1112'); + selStart(newDiv('111','222'), 1,2,'11122'); + selStart(newDiv('111',''), 1,0,'111'); + selStart(newDiv('111',''), 0,2,'11'); + selStart(newDiv('111','222','333'), 1,1,'1112'); + selStart(newDiv('111','222','333'), 1,2,'11122'); + selStart(newDiv('111','222','333'), 1,2,'11122'); + selStart(newDiv('111','','333'), 1,0,'111'); + + selMiddleStart(newDiv('111','222','333'), 1,1,'2'); + selMiddleStart(newDiv('111','222','333'), 1,2,'22'); + selMiddleStart(newDiv('111','222','333'), 2,1,'2223'); + selMiddleStart(newDiv('111','222','333'), 2,2,'22233'); + selMiddleStart(newDiv('111','','333'), 2,2,'33'); + selMiddleStart(newDiv('111','222',''), 2,0,'222'); + + selMiddleEnd(newDiv('111','222','333'), 0,1,'11222'); + selMiddleEnd(newDiv('111','222','333'), 0,2,'1222'); + selMiddleEnd(newDiv('111','222','333'), 1,1,'22'); + selMiddleEnd(newDiv('111','222','333'), 1,2,'2'); + selMiddleEnd(newDiv('111','','333'), 1,0,''); + selMiddleEnd(newDiv('','222','333'), 0,0,'222'); + + mergeBefore(newDiv('111','222'), 1,1,'2'); + mergeBefore(newDiv('111','222','333'), 1,2,'22'); + mergeBefore(newDiv('111','222','333'), 2,1,'2223'); + mergeBefore(newDiv('111','222','333'), 2,2,'22233'); + mergeBefore(newDiv('111','','333'), 2,0,''); + mergeBefore(newDiv('111','','333'), 2,2,'33'); +} + +function boom() +{ + runTests("dry run"); // this is to verify the result strings without normalize() + dry = false; + flush = false; + runTests("no flush"); + flush = true; + runTests("flush"); +} + +boom(); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_textnode_split_in_selection.html b/dom/base/test/test_textnode_split_in_selection.html new file mode 100644 index 0000000000..e9bcba2ea6 --- /dev/null +++ b/dom/base/test/test_textnode_split_in_selection.html @@ -0,0 +1,221 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=803924 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 803924</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=803924">Mozilla Bug 803924</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 803924 **/ + +var sel = document.getSelection(); +var flush = true; +var dry = true; +var run = ""; +var empty_range; +var empty_first_text_range; +var empty_last_text_range; +var full_range; + +function check(range, expected, test) +{ + is(""+range, expected, test); + is(""+empty_range, "", "empty range test after: "+test); + is(""+empty_first_text_range, "", "empty first text range test after: "+test); + if (empty_last_text_range) is(""+empty_last_text_range, "", "empty last text range test after: "+test); + is(""+full_range, full_range.startContainer.textContent, "full range test after: "+test); +} + +function newDiv() +{ + var div = document.createElement('div'); + for (var i = 0; i < arguments.length; ++i) { + div.appendChild(document.createTextNode(arguments[i])); + } + document.body.appendChild(div) + empty_range = document.createRange(); + empty_range.setStart(div,0); + empty_range.setEnd(div,0); + var firstTextNode = div.childNodes[0]; + var lastTextNode = div.childNodes[div.childNodes.length - 1]; + empty_first_text_range = document.createRange(); + empty_first_text_range.setStart(firstTextNode,0); + empty_first_text_range.setEnd(firstTextNode,0); + empty_last_text_range = null; + if (firstTextNode != lastTextNode) { + empty_last_text_range = document.createRange(); + empty_last_text_range.setStart(lastTextNode,0); + empty_last_text_range.setEnd(lastTextNode,0); + } + full_range = document.createRange(); + full_range.setStart(div,0); + full_range.setEnd(div,div.childNodes.length); + return div; +} + +function selEnd(div,child,index,split,s) +{ + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(start, index); + r.setEnd(div, div.childNodes.length); + if (!dry) start.splitText(split); + check(r,s,run+" selEnd "+child+","+index+","+split); +} + +function selStart(div,child,index,split,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(div, 0); + r.setEnd(start, index); + if (!dry) start.splitText(split); + check(r,s,run+" selStart "+child+","+index+","+split); +} + +function selMiddleStart(div,child,index,split,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(div, 1); + r.setEnd(start, index); + if (!dry) start.splitText(split); + check(r,s,run+" selMiddleStart "+child+","+index+","+split); +} + +function selMiddleEnd(div,child,index,split,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(start, index); + r.setEnd(div, 2); + if (!dry) start.splitText(split); + check(r,s,run+" selMiddleEnd "+child+","+index+","+split); +} + +function splitBefore(div,child,index,split,s) +{ + if (flush) document.body.getClientRects(); + var start = div.childNodes[child]; + var r = document.createRange(); + sel.addRange(r); + r.setStart(div, 1); + r.setEnd(start, index); + if (!dry) div.childNodes[0].splitText(split); + check(r,s,run+" splitBefore "+child+","+index+","+split); +} + +function runTests(s) +{ + run = s+":"; + selEnd(newDiv('111'), 0,0,0,'111'); + selEnd(newDiv('111'), 0,0,1,'111'); + selEnd(newDiv('111'), 0,0,3,'111'); + selEnd(newDiv(''), 0,0,0,''); + selEnd(newDiv('111'), 0,1,0,'11'); + selEnd(newDiv('111'), 0,2,1,'1'); + selEnd(newDiv('111'), 0,1,3,'11'); + selEnd(newDiv('111','222'), 0,1,0,'11222'); + selEnd(newDiv('111','222'), 0,2,1,'1222'); + selEnd(newDiv('111','222'), 0,1,3,'11222'); + selEnd(newDiv('111','222'), 1,1,0,'22'); + selEnd(newDiv('111','222'), 1,2,1,'2'); + selEnd(newDiv('','222'), 1,1,1,'22'); + selEnd(newDiv('','222'), 0,0,0,'222'); + selEnd(newDiv('111',''), 0,1,0,'11'); + selEnd(newDiv('111','222'), 1,1,3,'22'); + selEnd(newDiv('111','222','333'), 1,1,0,'22333'); + selEnd(newDiv('111','222','333'), 1,2,1,'2333'); + selEnd(newDiv('111','222','333'), 1,1,3,'22333'); + selEnd(newDiv('111','222',''), 1,1,3,'22'); + selEnd(newDiv('111','','333'), 0,1,3,'11333'); + + selStart(newDiv('111'), 0,0,0,''); + selStart(newDiv('111'), 0,0,1,''); + selStart(newDiv('111'), 0,0,3,''); + selStart(newDiv('111'), 0,1,0,'1'); + selStart(newDiv('111'), 0,2,1,'11'); + selStart(newDiv('111'), 0,1,3,'1'); + selStart(newDiv(''), 0,0,0,''); + selStart(newDiv('111','222'), 0,1,0,'1'); + selStart(newDiv('111','222'), 0,2,1,'11'); + selStart(newDiv('111','222'), 0,1,3,'1'); + selStart(newDiv('111','222'), 1,1,0,'1112'); + selStart(newDiv('111','222'), 1,2,1,'11122'); + selStart(newDiv('111','222'), 1,1,3,'1112'); + selStart(newDiv('','222'), 1,1,2,'2'); + selStart(newDiv('','222'), 0,0,0,''); + selStart(newDiv('111',''), 1,0,0,'111'); + selStart(newDiv('111','222','333'), 1,1,0,'1112'); + selStart(newDiv('111','222','333'), 1,2,1,'11122'); + selStart(newDiv('111','222','333'), 1,1,3,'1112'); + selStart(newDiv('111','','333'), 1,0,0,'111'); + selStart(newDiv('111','222',''), 1,1,3,'1112'); + + selMiddleStart(newDiv('111','222','333'), 1,1,0,'2'); + selMiddleStart(newDiv('111','222','333'), 1,2,1,'22'); + selMiddleStart(newDiv('111','222','333'), 1,1,3,'2'); + selMiddleStart(newDiv('111','222','333'), 2,1,0,'2223'); + selMiddleStart(newDiv('111','222','333'), 2,2,1,'22233'); + selMiddleStart(newDiv('111','222','333'), 2,1,3,'2223'); + selMiddleStart(newDiv('111','','333'), 2,1,2,'3'); + selMiddleStart(newDiv('111','','333'), 1,0,0,''); + + selMiddleEnd(newDiv('111','222','333'), 0,1,0,'11222'); + selMiddleEnd(newDiv('111','222','333'), 0,2,1,'1222'); + selMiddleEnd(newDiv('111','222','333'), 0,1,3,'11222'); + selMiddleEnd(newDiv('111','222','333'), 1,1,0,'22'); + selMiddleEnd(newDiv('111','222','333'), 1,2,1,'2'); + selMiddleEnd(newDiv('111','222','333'), 1,1,3,'22'); + selMiddleEnd(newDiv('111','','333'), 0,1,2,'11'); + selMiddleEnd(newDiv('111','','333'), 0,1,3,'11'); + selMiddleEnd(newDiv('111','','333'), 1,0,0,''); + + splitBefore(newDiv('111','222','333'), 1,1,0,'2'); + splitBefore(newDiv('111','222','333'), 1,2,1,'22'); + splitBefore(newDiv('111','222','333'), 1,1,3,'2'); + splitBefore(newDiv('111','222','333'), 2,1,0,'2223'); + splitBefore(newDiv('111','222','333'), 2,2,1,'22233'); + splitBefore(newDiv('111','222','333'), 2,1,3,'2223'); + splitBefore(newDiv('','222','333'), 1,1,0,'2'); + splitBefore(newDiv('','','333'), 1,0,0,''); + splitBefore(newDiv('','222',''), 2,0,0,'222'); + splitBefore(newDiv('111','','333'), 2,1,2,'3'); +} + +function boom() +{ + runTests("dry run"); // this is to verify the result strings without splitText() + dry = false; + flush = false; + runTests("no flush"); + flush = true; + runTests("flush"); +} + +boom(); + + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_timer_flood.html b/dom/base/test/test_timer_flood.html new file mode 100644 index 0000000000..b74b04cf29 --- /dev/null +++ b/dom/base/test/test_timer_flood.html @@ -0,0 +1,116 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Test Behavior During Timer Flood</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +function onLoad() { + return new Promise(resolve => { + addEventListener('load', resolve, { once: true }); + }); +} + +// Create a frame that executes a timer flood. The frame signals +// that is ready once the flood has had a chance to warm up. +function withFloodFrame() { + return new Promise(resolve => { + let frame = document.createElement('iframe'); + addEventListener('message', function onMsg(evt) { + if (evt.data === 'STARTED') { + removeEventListener('message', onMsg); + resolve(frame); + } + }); + frame.src = 'file_timer_flood.html'; + document.body.appendChild(frame); + }); +} + +// Test that we can load documents during a timer flood. +function testFrameLoad() { + return new Promise(resolve => { + let frame = document.createElement('iframe'); + frame.addEventListener('load', _ => { + frame.remove(); + resolve(); + }, { once: true }); + document.body.appendChild(frame); + }); +} + +// Test that we can perform network requests while a timer flood +// is occuring. +function testFetch(url) { + return fetch(url).then(response => { + return response.text(); + }); +} + +// Test that we can run animations for 5 seconds while a timer +// flood is occuring. +function testRequestAnimationFrame() { + return new Promise(resolve => { + let remainingFrames = 5 * 60; + function nextFrame() { + remainingFrames -= 1; + if (remainingFrames > 0) { + requestAnimationFrame(nextFrame); + } else { + resolve(); + } + }; + requestAnimationFrame(nextFrame); + }); +} + +let floodFrame; + +onLoad().then(_ => { + // Start a timer flood in a frame. + return withFloodFrame(); +}).then(frame => { + floodFrame = frame; + + // Next we are going to start a bunch of asynchronous work that we + // expect to complete in spite of the timer flood. The type of work + // is a bit arbitrary, but is chosen to reflect the kinds of things + // we would like the browser to be able to do even when pages are + // abusing timers. Feel free to add more types of work here, but + // think carefully before removing anything. + let tests = []; + + // Verify we can perform a variety of work while the timer flood + // is running. + for (let i = 0; i < 20; ++i) { + tests.push(testFrameLoad()); + tests.push(testFetch('file_timer_flood.html')); + } + // Verify that animations still work while the timer flood is running. + // Note that we do one long run of animations instead of parallel runs + // like the other activities because of the way requestAnimationFrame() + // is scheduled. Parallel animations would not result in any additional + // runnables be placed on the event queue. + tests.push(testRequestAnimationFrame()); + + // Wait for all tests to finish. If we do not handle the timer flood + // well then this will likely time out. + return Promise.all(tests); +}).then(_ => { + ok(true, 'completed tests without timing out'); + floodFrame.remove(); + SimpleTest.finish(); +}); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_title.html b/dom/base/test/test_title.html new file mode 100644 index 0000000000..8d735b453c --- /dev/null +++ b/dom/base/test/test_title.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<html> + +<head> + <title>Test for titles</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + <style type="text/css"> + </style> +</head> + +<body onload="runTests()"> + +<p id="display"></p> +<div style="display:none;"> + <iframe id="html1" src="data:text/html,<html><head><title id='t'>Test</title></head></html>"></iframe> + <iframe id="html2" src="data:text/html,<html><head><title id='t'>Test</title><title>Foo</title></head></html>"></iframe> + <iframe id="html3" src="data:text/html,<html></html>"></iframe> + <iframe id="xhtml1" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'><body><title id='t'>Test</title></body></html>"></iframe> + <iframe id="xhtml2" src="data:text/xml,<title xmlns='http://www.w3.org/1999/xhtml'>Test</title>"></iframe> + <iframe id="xhtml3" src="data:text/xml,<title xmlns='http://www.w3.org/1999/xhtml'>Te<div>bogus</div>st</title>"></iframe> + <iframe id="xhtml4" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'/>"></iframe> + <iframe id="xhtml5" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'><head/></html>"></iframe> + <iframe id="xhtml6" src="data:text/xml,<html xmlns='http://www.w3.org/1999/xhtml'><head><style/></head></html>"></iframe> + <iframe id="xul1" src="data:application/vnd.mozilla.xul+xml,<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"></iframe> + <iframe id="xul2" src="data:application/vnd.mozilla.xul+xml,<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul' title='Test'/>"></iframe> + <iframe id="svg1" src="data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><title id='t'>Test</title></svg>"></iframe> + <iframe id="svg2" src="data:text/xml,<svg xmlns='http://www.w3.org/2000/svg'><title id='t'>Test</title></svg>"></iframe> +</div> + +<pre id="test"> +<script> +SimpleTest.waitForExplicitFinish(); + +function runTests() { + function testStatic(id, expect, description) { + is(document.getElementById(id).contentDocument.title, expect, description); + } + + testStatic("html1", "Test", "HTML <title>"); + testStatic("html2", "Test", "choose the first HTML <title>"); + testStatic("html3", "", "No title"); + testStatic("xhtml1", "Test", "XHTML <title> in body"); + testStatic("xhtml2", "Test", "XHTML <title> as root element"); + testStatic("xhtml3", "Test", "XHTML <title> containing an element"); + testStatic("xul1", "Test", "XUL <window> title attribute"); + testStatic("svg1", "Test", "SVG <title>"); + + SimpleTest.finish(); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_treewalker_nextsibling.xml b/dom/base/test/test_treewalker_nextsibling.xml new file mode 100644 index 0000000000..a10ab31a05 --- /dev/null +++ b/dom/base/test/test_treewalker_nextsibling.xml @@ -0,0 +1,97 @@ +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css" ?> +<root> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js" xmlns="http://www.w3.org/1999/xhtml"/> + + <body xmlns="http://www.w3.org/1999/xhtml"> + <p id="display"></p> + <div id="content" style="display: none;"></div> + <textarea id="test" style="height: 300px; max-width: 800px; overflow: scroll;" + rows="10" cols="160" readonly="readonly"/> + </body> + +<pre id="test" xmlns="http://www.w3.org/1999/xhtml"> +<script class="testbody" type="text/javascript" xmlns="http://www.w3.org/1999/xhtml"> +<![CDATA[ +var passedNodes = new WeakMap(); +function setPass(aNode) { + passedNodes.set(aNode, true); +} + +SimpleTest.waitForExplicitFinish(); + +window.addEventListener("load", function() { + const nsIDOMNodeFilter = SpecialPowers.Ci.nsIDOMNodeFilter; + var walker = document.createTreeWalker( + document, + nsIDOMNodeFilter.SHOW_TEXT | nsIDOMNodeFilter.SHOW_DOCUMENT, + null + ); + setPass(walker.firstChild()); + while (walker.nextSibling()) { + setPass(walker.currentNode); + } + +/* +From http://www.w3.org/TR/2000/REC-DOM-Level-2-Traversal-Range-20001113/traversal.html#Traversal-TreeWalker +Omitting nodes from the logical view of a subtree can result in a structure that +is substantially different from the same subtree in the complete, unfiltered +document. Nodes that are siblings in the TreeWalker view may be children of +different, widely separated nodes in the original view. For instance, consider a +NodeFilter that skips all nodes except for Text nodes and the root node of a +document. In the logical view that results, all text nodes will be siblings and +appear as direct children of the root node, no matter how deeply nested the +structure of the original document. +*/ + + walker2 = document.createTreeWalker(document, nsIDOMNodeFilter.SHOW_TEXT, null); + while (walker2.nextNode()) { + var cNode = walker2.currentNode; + ok(passedNodes.get(cNode), "Every text node should appear: " + walker2.currentNode.nodeValue); + walker.currentNode = cNode; + var parent = walker.parentNode(); + is(parent, document, "parent of text node should be document"); + + // Check nextSibling's previousSibling. + walker.currentNode = cNode; + if (walker.nextSibling()) { + is(cNode, walker.previousSibling(), "nextSibling.previousSibling should be consistent"); + } + + // Check previousSibling's nextSibling. + walker.currentNode = cNode; + if (walker.previousSibling()) { + is(cNode, walker.nextSibling(), "previousSibling.nextSibling should be consistent"); + } + } + SimpleTest.finish(); +}, true); +]]> +</script> +</pre> + + <test> + zero + <one> + one-A + <two> + two-A + </two> + <two> + two-B + </two> + one-B + </one> + <one> + one-C + <two> + two-D + </two> + <two> + two-E + </two> + one-F + </one> + zero + </test> +</root> + diff --git a/dom/base/test/test_user_select.html b/dom/base/test/test_user_select.html new file mode 100644 index 0000000000..c2b1175974 --- /dev/null +++ b/dom/base/test/test_user_select.html @@ -0,0 +1,341 @@ +<!DOCTYPE> +<html> +<head> +<title>-moz-user-select selection tests</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<style type="text/css"> +@font-face { + font-family: Ahem; + src: url("Ahem.ttf"); +} +body { font-family: Ahem; font-size: 20px; } +s, .non-selectable { -moz-user-select: none; } +n { display: none; } +a { position:absolute; bottom: 0; right:0; } +.text { -moz-user-select: text; } +</style> + +</head> +<body> + +<div id="test1">aaaaaaa<s>bbbbbbbb</s>ccccccc</div> +<div id="test2"><s>aaaaaaa</s>bbbbbbbbccccccc</div> +<div id="test3">aaaaaaabbbbbbbb<s>ccccccc</s></div> +<div id="test4">aaaaaaa<x><s>bbbbbbbb</s></x>ccccccc</div> +<div id="test5"><x><s>aaaaaaa</s></x>bbbbbbbbccccccc</div> +<div id="test6">aaaaaaabbbbbbbb<x><s>ccccccc</s></x></div> +<div id="test7">aaaaaaa<x><s><n>bbbb</n>bbbb</s></x>ccccccc</div> +<div id="test8"><x><s>aa<n>aaa</n>aa</s></x>bbbbbbbbccccccc</div> +<div id="test9">aaaaaaabbbbbbbb<x><s>cc<n>ccccc</n></s></x></div> +<div id="testA">aaaaaaa<n>bbb<s>bbbbb</s></n>ccccccc</div> +<div id="testB"><n><s>aaaa</s>aaa</n>bbbbbbbbccccccc</div> +<div id="testC">aaaaaaabbbbbbbb<n>cc<s>c</s>cccc</n></div> +<div id="testE">aaa<s id="testEc1">aaaa<a class="text">bbbb</a>dd<a>cccc</a>ddddddd</s>eeee</div> +<div id="testF">aaaa +<div class="non-selectable">x</div> +<div class="non-selectable">x</div> +<div class="non-selectable">x</div> +bbbb</div> +<div id="testG" style="white-space:pre">aaaa +<div class="non-selectable">x</div> +<div class="non-selectable">x</div> +<div class="non-selectable">x</div> +bbbb</div> +<div id="testH" style="white-space:pre">aaaa +<div class="non-selectable">x</div><input> +bbbbbbb</div> + +<iframe id="testD" src="data:text/html,<body>aaaa<span style='-moz-user-select:none'>bbbb</span>cccc"></iframe> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + +function test() +{ + function clear(w) + { + var sel = (w ? w : window).getSelection(); + sel.removeAllRanges(); + } + function doneTest(e) + { + // We hide the elements we're done with so that later tests + // are inside the rather narrow iframe mochitest gives us. + // It matters for synthesizeMouse event tests. + e.style.display = 'none'; + e.offsetHeight; + } + + function dragSelect(e, x1, x2, x3) + { + dir = x2 > x1 ? 1 : -1; + synthesizeMouse(e, x1, 5, { type: "mousedown" }); + synthesizeMouse(e, x1 + dir, 5, { type: "mousemove" }); + if (x3) + synthesizeMouse(e, x3, 5, { type: "mousemove" }); + synthesizeMouse(e, x2 - dir, 5, { type: "mousemove" }); + synthesizeMouse(e, x2, 5, { type: "mouseup" }); + } + + function shiftClick(e, x) + { + synthesizeMouse(e, x, 5, { type: "mousedown", shiftKey: true }); + synthesizeMouse(e, x, 5, { type: "mouseup", shiftKey: true }); + } + + function init(arr, e) + { + clear(); + var sel = window.getSelection(); + for (i = 0; i < arr.length; ++i) { + var data = arr[i]; + var r = new Range() + r.setStart(node(e, data[0]), data[1]); + r.setEnd(node(e, data[2]), data[3]); + sel.addRange(r); + } + } + + function NL(s) { return s.replace(/(\r\n|\n\r|\r)/g, '\n'); } + + function checkText(text, e) + { + var sel = window.getSelection(); + is(NL(sel.toString()), text, e.id + ": selected text") + } + + function checkRangeText(text, index) + { + var r = window.getSelection().getRangeAt(index); + is(NL(r.toString()), text, e.id + ": range["+index+"].toString()") + } + + function node(e, arg) + { + if (typeof arg == "number") + return arg == -1 ? e : e.childNodes[arg]; + return arg; + } + + function checkRangeCount(n, e) + { + var sel = window.getSelection(); + is(sel.rangeCount, n, e.id + ": Selection range count"); + } + + function checkRange(i, expected, e) { + var sel = window.getSelection(); + var r = sel.getRangeAt(i); + is(r.startContainer, node(e, expected[0]), e.id + ": range["+i+"].startContainer"); + is(r.startOffset, expected[1], e.id + ": range["+i+"].startOffset"); + is(r.endContainer, node(e, expected[2]), e.id + ": range["+i+"].endContainer"); + is(r.endOffset, expected[3], e.id + ": range["+i+"].endOffset"); + } + + function checkRanges(arr, e) + { + checkRangeCount(arr.length, e); + for (i = 0; i < arr.length; ++i) { + var expected = arr[i]; + checkRange(i, expected, e); + } + } + + // ====================================================== + // ================== dragSelect tests ================== + // ====================================================== + + var e = document.getElementById('test1'); + dragSelect(e, 20, 340); + checkText('aaaaaacc', e); + checkRanges([[0,1,-1,1], [2,0,2,2]], e); + + clear(); + dragSelect(e, 20, 260, 120); + checkText('aaaaa', e); + checkRanges([[0,1,0,6]], e); + doneTest(e); + + clear(); + e = document.getElementById('test2'); + dragSelect(e, 20, 340); + checkText('', e); + checkRanges([], e); + + clear(); + dragSelect(e, 340, 20, 140); + checkText('bbbbbbbbcc', e); + checkRanges([[1,0,1,10]], e); + // #test2 is used again below + + clear(); + e = document.getElementById('test3'); + dragSelect(e, 20, 340, 295); + checkText('aaaaaabbbbbbbb', e); + checkRanges([[0,1,0,15]], e); + // #test3 is used again below + + clear(); + e = document.getElementById('test4'); + dragSelect(e, 20, 340); + checkText('aaaaaacc', e); + checkRanges([[0,1,1,0], [2,0,2,2]], e); + doneTest(e); + + clear(); + e = document.getElementById('test5'); + dragSelect(e, 340, 20, 140); + checkText('bbbbbbbbcc', e); + checkRanges([[1,0,1,10]], e); + doneTest(e); + + clear(); + e = document.getElementById('test6'); + dragSelect(e, 20, 340, 295); + checkText('aaaaaabbbbbbbb', e); + checkRanges([[0,1,0,15]], e); + doneTest(e); + + clear(); + e = document.getElementById('test7'); + dragSelect(e, 20, 340); + checkText('aaaaaacccccc', e); + checkRanges([[0,1,1,0], [2,0,2,6]], e); + doneTest(e); + + clear(); + e = document.getElementById('test8'); + dragSelect(e, 340, 20, 140); + checkText('bbbbbccccc', e); + checkRanges([[1,3,1,13]], e); + doneTest(e); + + clear(); + e = document.getElementById('test9'); + dragSelect(e, 20, 340, 295); + checkText('aaaaaabbbbbbbb', e); + checkRanges([[0,1,0,15]], e); + doneTest(e); + + clear(); + e = document.getElementById('testA'); + dragSelect(e, 20, 340); + checkText('aaaaaaccccccc', e); + checkRanges([[0,1,2,7]], e); + checkRangeText('aaaaaabbbbbbbbccccccc', 0); + doneTest(e); + + clear(); + e = document.getElementById('testB'); + dragSelect(e, 340, 20, 140); + checkText('bbbbbbbccccccc', e); + checkRanges([[1,1,1,15]], e); + doneTest(e); + + clear(); + e = document.getElementById('testE'); + dragSelect(e, 20, 360, 295); + checkText('aa\nbbbb\nee', e); + checkRangeCount(3, e); + checkRange(0, [0,1,-1,1], e); + checkRange(1, [1,0,-1,2], e.children[0]); + checkRange(2, [2,0,2,2], e); + doneTest(e); + + // ====================================================== + // ================== shift+click tests ================= + // ====================================================== + + // test extending a selection that starts in a -moz-user-select:none node + clear(); + e = document.getElementById('test2'); + init([[0,0,0,1]], e); + checkRangeText('aaaaaaa', 0); + checkText('', e); + shiftClick(e, 340); + checkRangeText('bbbbbbbbcc', 0); + checkText('bbbbbbbbcc', e); + checkRanges([[-1,1,1,10]], e); + doneTest(e); + + // test extending a selection that end in a -moz-user-select:none node + clear(); + e = document.getElementById('test3'); + init([[1,0,1,1]], e); + checkRangeText('ccccccc', 0); + checkText('', e); + shiftClick(e, 20); + checkRangeText('aaaaaabbbbbbbb', 0); + checkText('aaaaaabbbbbbbb', e); + checkRanges([[0,1,-1,1]], e); + doneTest(e); + + clear(); + e = document.getElementById('testF'); + synthesizeMouse(e, 1, 1, {}); + synthesizeMouse(e, 400, 100, { shiftKey: true }); + checkText("aaaa bbbb", e); + checkRanges([[0,0,-1,1],[6,0,6,5]], e); + doneTest(e); + + clear(); + e = document.getElementById('testG'); + synthesizeMouse(e, 1, 1, {}); + synthesizeMouse(e, 400, 180, { shiftKey: true }); + checkText("aaaa bbbb", e); // XXX this doesn't seem right - bug 1247799 + checkRanges([[0,0,-1,1],[2,0,-1,3],[4,0,-1,5],[6,0,6,5]], e); + doneTest(e); + + clear(); + e = document.getElementById('testH'); + synthesizeMouse(e, 1, 1, {}); + synthesizeMouse(e, 30, 90, { shiftKey: true }); + synthesizeMouse(e, 50, 90, { shiftKey: true }); + synthesizeMouse(e, 70, 90, { shiftKey: true }); + checkText("aaaa bbb", e); + checkRanges([[0,0,-1,1],[-1,2,3,4]], e); + + doneTest(e); + // ====================================================== + // ==================== Script tests ==================== + // ====================================================== + + clear(); + e = document.getElementById('testD'); + clear(e.contentWindow); + sel = e.contentWindow.getSelection(); + sel.selectAllChildren(e.contentDocument.body); + is(window.getSelection().rangeCount, 0, "testD: no selection in outer window"); + is(sel.toString(), 'aaaacccc', "testD: scripted selection"); + is(sel.rangeCount, 1, "testD: scripted selection isn't filtered"); + is(sel.getRangeAt(0).toString(), 'aaaabbbbcccc', "testD: scripted selection isn't filtered"); + + // ====================================================== + // ================== Kbd command tests ================= + // ====================================================== + + clear(); + e = document.getElementById('testD'); + clear(e.contentWindow); + e.contentWindow.focus(); + synthesizeKey("a", { accelKey:true }, e.contentWindow); + sel = e.contentWindow.getSelection(); + is(window.getSelection().rangeCount, 0, "testD: no selection in outer window"); + is(sel.toString(), 'aaaacccc', "testD: kbd selection"); + is(sel.rangeCount, 2, "testD: kbd selection is filtered"); + is(sel.getRangeAt(0).toString(), 'aaaa', "testD: kbd selection is filtered"); + is(sel.getRangeAt(1).toString(), 'cccc', "testD: kbd selection is filtered"); + doneTest(e); + + clear(); + SimpleTest.finish(); +} +window.onload = function() { setTimeout(test, 0); }; +SimpleTest.waitForExplicitFinish(); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_viewport_scroll.html b/dom/base/test/test_viewport_scroll.html new file mode 100644 index 0000000000..9b812360b2 --- /dev/null +++ b/dom/base/test/test_viewport_scroll.html @@ -0,0 +1,89 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for mapping of scrollTop/scrollLeft to viewport</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body onload="doTest()"> +<p id="display"></p> + +<iframe id="quirks"></iframe> +<iframe id="standards"></iframe> +<iframe id="xml"></iframe> + +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +var quirks = document.getElementById("quirks"); +var standards = document.getElementById("standards"); +var xml = document.getElementById("xml"); + +quirks.src = "data:text/html,<html><body style='height:2000px; width:2000px;'>"; +standards.src = "data:text/html,<!DOCTYPE HTML><html><body style='height:2000px; width:2000px;'>"; +xml.src = "data:text/xml,<?xml-stylesheet href='data:text/css,html { display:block; height:2000px; width:2000px; }'?><foo><html></html></foo>"; + +function subtest(winProp, elemProp, win, correctElement, elemToSet, otherElem1, otherElem2) { + win.scrollTo(50, 50); + elemToSet[elemProp] = 100; + if (elemToSet == correctElement) { + is(win[winProp], 100, "Setting " + elemToSet.name + "." + elemProp + " should scroll"); + is(elemToSet[elemProp], 100, "Reading back " + elemToSet.name + "." + elemProp + " after scrolling"); + } else { + is(win[winProp], 50, "Setting " + elemToSet.name + "." + elemProp + " should not scroll"); + is(elemToSet[elemProp], 0, "Reading back " + elemToSet.name + "." + elemProp + " after not scrolling"); + } + if (otherElem1 == correctElement) { + is(otherElem1[elemProp], 50, "Reading back " + otherElem1.name + "." + elemProp + " (correct element) after not scrolling"); + } else { + is(otherElem1[elemProp], 0, "Reading back " + otherElem1.name + "." + elemProp + " (irrelevant element)"); + } + if (otherElem2 == correctElement) { + is(otherElem2[elemProp], 50, "Reading back " + otherElem2.name + "." + elemProp + " (correct element) after not scrolling"); + } else { + is(otherElem2[elemProp], 0, "Reading back " + otherElem2.name + "." + elemProp + " (irrelevant element)"); + } +} + +function testScroll(winProp, elemProp, win, elemToSet, otherElem1, otherElem2) { + subtest(winProp, elemProp, win, elemToSet, elemToSet, otherElem1, otherElem2); + subtest(winProp, elemProp, win, elemToSet, otherElem1, elemToSet, otherElem2); + subtest(winProp, elemProp, win, elemToSet, otherElem2, elemToSet, otherElem1); +} + +function doTest() { + var quirksRoot = quirks.contentDocument.documentElement; + quirksRoot.name = "quirks HTML"; + var quirksBody = quirks.contentDocument.body; + quirksBody.name = "quirks BODY"; + var quirksBody2 = quirks.contentDocument.createElement("body"); + quirksBody2.name = "quirks other BODY"; + quirksRoot.appendChild(quirksBody2); + testScroll("scrollX", "scrollLeft", quirks.contentWindow, quirksBody, quirksRoot, quirksBody2); + testScroll("scrollY", "scrollTop", quirks.contentWindow, quirksBody, quirksRoot, quirksBody2); + + var standardsRoot = standards.contentDocument.documentElement; + standardsRoot.name = "standards HTML"; + var standardsBody = standards.contentDocument.body; + standardsBody.name = "standards BODY"; + var standardsBody2 = standards.contentDocument.createElement("body"); + standardsBody2.name = "standards other BODY"; + standardsRoot.appendChild(standardsBody2); + testScroll("scrollX", "scrollLeft", standards.contentWindow, standardsRoot, standardsBody, standardsBody2); + testScroll("scrollY", "scrollTop", standards.contentWindow, standardsRoot, standardsBody, standardsBody2); + + var xmlRoot = xml.contentDocument.documentElement; + xmlRoot.name = "XML root"; + var xmlOther = xmlRoot.firstChild; + xmlOther.name = "XML other"; + testScroll("scrollX", "scrollLeft", xml.contentWindow, xmlRoot, xmlOther, xmlOther); + testScroll("scrollY", "scrollTop", xml.contentWindow, xmlRoot, xmlOther, xmlOther); + + SimpleTest.finish(); +} +</script> + +</pre> +</body> +</html> diff --git a/dom/base/test/test_viewsource_forbidden_in_object.html b/dom/base/test/test_viewsource_forbidden_in_object.html new file mode 100644 index 0000000000..67ad367efd --- /dev/null +++ b/dom/base/test/test_viewsource_forbidden_in_object.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=973837 +--> +<head> +<meta charset="utf-8"> +<title>Tests for Bug 973837</title> +<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<script> + SimpleTest.waitForExplicitFinish(); + + const OBJLC = SpecialPowers.Ci.nsIObjectLoadingContent; + + function runObjectURITest(testCase) { + var testObject = document.getElementById("testObject"); + testObject.data = testCase.URI; + + testObject instanceof OBJLC; + testObject = SpecialPowers.wrap(testObject); + + is(testObject.displayedType, OBJLC.TYPE_NULL, testCase.desc + + " testObject.displayedType should be TYPE_NULL (4)"); + runNextTest(); + } + + var testCaseIndex = -1; + testCases = [ + { + desc: "Test 1: view-source should not be allowed in an object.", + URI: "view-source:file_general_document.html" + }, + { + desc: "Test 2: feed:view-source should not be allowed in an object.", + URI: "feed:view-source:file_general_document.html" + }, + { + desc: "Test 3: jar:view-source should not be allowed in an object", + URI: "jar:view-source:file_general_document.html/!/" + }, + { + desc: "Test 4: pcast:view-source should not be allowed in an object", + URI: "pcast:view-source:file_general_document.html" + }, + { + desc: "Test 5: pcast:feed:view-source should not be allowed in an object", + URI: "pcast:feed:view-source:file_general_document.html" + } + ]; + + function runNextTest() { + ++testCaseIndex; + if (testCaseIndex == testCases.length) { + SimpleTest.finish(); + return; + } + + runObjectURITest(testCases[testCaseIndex]); + } + + addLoadEvent(runNextTest); +</script> +</head> + +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=973837">Mozilla Bug 973837</a> +<p id="display"></p> + +<object id="testObject"></object> + +</body> +</html> diff --git a/dom/base/test/test_w3element_traversal.html b/dom/base/test/test_w3element_traversal.html new file mode 100644 index 0000000000..fdd4ac03c0 --- /dev/null +++ b/dom/base/test/test_w3element_traversal.html @@ -0,0 +1,148 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>W3 Tests for Element Traversal - HTML</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + + <p id="parentEl_count"> + <span id="first_element_child_count"> + <span></span> + <span></span> + </span> + <span id="middle_element_child_count"></span> + <span id="last_element_child_count"></span> + </p> + + + <p id="parentEl_nochild"> + </p> + + <p id="parentEl_null"> + </p> + + <p id="parentEl_dynamicadd"> + <span id="first_emement_child_add"></span> + </p> + + <p id="parentEl_dynamicremove"> + <span id="first_emement_child_remove"></span> + <span id="last_emement_child_remove"></span> + </p> + + + <p id="parentEl_fec"> + <span id="first_element_child_fec"></span> + </p> + + <p id="parentEl_lec"> + <span id="first_element_child_lec"></span> + <span id="last_element_child_lec"></span> + </p> + + <p id="parentEl_namespace"> + <pickle:span id="first_element_child_namespace"></pickle:span> + </p> + + <p id="parentEl_nes"> + <span id="first_element_child_nes"></span> + <span id="last_element_child_nes"></span> + </p> + + <p id="parentEl_pes"> + <span id="first_element_child_pes"></span> + <span id="middle_element_child_pes"></span> + <span id="last_element_child_pes"></span> + </p> + + <p id="parentEl_sibnull"> + <span id="first_element_child_sibnull"></span> + </p> + +<pre id="test"> +<script class="testbody" type="text/javascript"> + + + +function runTest() { + + //from et-childElementCount.html + var parentEl = document.getElementById("parentEl_count"); + is(parentEl.childElementCount && 3, parentEl.childElementCount, "Child Element Count is mismatched"); + + //from et-childElementCount-nochild.html + var parentEl_nochild = document.getElementById("parentEl_nochild"); + is(parentEl_nochild.childElementCount, 0, "Child Element count is not 0"); + + //from et-childElementCount-null.html + parentEl = document.getElementById("parentEl_null"); + is(null == parentEl.firstElementChild, null == parentEl.lastElementChild, "firstElementChild or lastElementChild is not null"); + + //from et-dynamic-add.html + parentEl = document.getElementById("parentEl_dynamicadd"); + var newChild = document.createElement("span") + parentEl.appendChild( newChild ); + is(parentEl.childElementCount && 2, parentEl.childElementCount, "failed to add span element"); + + //from et-dynamic-remove.html + parentEl = document.getElementById("parentEl_dynamicremove"); + var lec = parentEl.lastElementChild; + parentEl.removeChild( lec ); + is(parentEl.childElementCount && 1, parentEl.childElementCount, "failed to remove span element"); + + //from et-firstElementChild.html + parentEl = document.getElementById("parentEl_fec"); + var fec = parentEl.firstElementChild; + is(fec.nodeType, 1, "failed to get firstElementChild"); + is(fec.getAttribute("id"), "first_element_child_fec", "failed to get firstElementChild"); + isnot(fec, null, "failed to get firstElementChild"); + + //from et-lastElementChild.html + parentEl = document.getElementById("parentEl_lec"); + var lec = parentEl.lastElementChild; + is(lec.nodeType, 1, "failed to get lastElementChild"); + is(lec.getAttribute("id"), "last_element_child_lec", "failed to get lastElementChild"); + isnot(lec, null, "failed to get lastElementChild"); + + //from et-namespace.html + parentEl = document.getElementById("parentEl_namespace"); + var fec = parentEl.firstElementChild; + isnot(fec, null, "failed to get firstElementChild in namespace"); + is(fec.getAttribute("id"), "first_element_child_namespace", "failed to get firstElementChild in namespace"); + + //from et-nextElementSibling.html + parentEl = document.getElementById("parentEl_nes"); + var fec = parentEl.firstElementChild; + var nes = fec.nextElementSibling; + is(nes.nodeType, 1, "failed to get nextElementSibling"); + is(nes.getAttribute("id"), "last_element_child_nes", "failed to get nextElementSibling"); + isnot(nes, null, "failed to get nextElementSibling"); + + //from et-previousElementSibling.html + var lec = document.getElementById("last_element_child_pes"); + var pes = lec.previousElementSibling; + is(pes.nodeType, 1, "failed to get previousElementSibling"); + is(pes.getAttribute("id"), "middle_element_child_pes", "failed to get previousElementSibling"); + isnot(pes, null, "failed to get previousElementSibling"); + + //from et-siblingElement-null.html + var fec = document.getElementById("first_element_child_sibnull"); + var pes = fec.previousElementSibling; + var nes = fec.nextElementSibling; + is(pes, null, "got unexpected previousElementSibling"); + is(nes, null, "got unexpected nextElementSibling"); + +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); +addLoadEvent(SimpleTest.finish) +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_w3element_traversal.xhtml b/dom/base/test/test_w3element_traversal.xhtml new file mode 100644 index 0000000000..28ef465115 --- /dev/null +++ b/dom/base/test/test_w3element_traversal.xhtml @@ -0,0 +1,149 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:pickle="http://ns.example.org/pickle" lang="en"> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> + <title>W3 Tests for Element Traversal - XHTML</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + + <p id="parentEl_count"> + <span id="first_element_child_count"> + <span></span> + <span></span> + </span> + <span id="middle_element_child_count"></span> + <span id="last_element_child_count"></span> + </p> + + + <p id="parentEl_nochild"> + </p> + + <p id="parentEl_null"> + </p> + + <p id="parentEl_dynamicadd"> + <span id="first_emement_child_add"></span> + </p> + + <p id="parentEl_dynamicremove"> + <span id="first_emement_child_remove"></span> + <span id="last_emement_child_remove"></span> + </p> + + + <p id="parentEl_fec"> + <span id="first_element_child_fec"></span> + </p> + + <p id="parentEl_lec"> + <span id="first_element_child_lec"></span> + <span id="last_element_child_lec"></span> + </p> + + <div id="parentEl_namespace"> + <pickle:dill /> + </div> + + <p id="parentEl_nes"> + <span id="first_element_child_nes"></span> + <span id="last_element_child_nes"></span> + </p> + + <p id="parentEl_pes"> + <span id="first_element_child_pes"></span> + <span id="middle_element_child_pes"></span> + <span id="last_element_child_pes"></span> + </p> + + <p id="parentEl_sibnull"> + <span id="first_element_child_sibnull"></span> + </p> + +<pre id="test"> +<script class="testbody" type="text/javascript"><![CDATA[ + + + +function runTest() { + + //from et-childElementCount.html + var parentEl = document.getElementById("parentEl_count"); + is(parentEl.childElementCount && 3, parentEl.childElementCount, "Child Element Count is mismatched"); + + //from et-childElementCount-nochild.html + var parentEl_nochild = document.getElementById("parentEl_nochild"); + is(parentEl_nochild.childElementCount, 0, "Child Element count is not 0"); + + //from et-childElementCount-null.html + parentEl = document.getElementById("parentEl_null"); + is(null == parentEl.firstElementChild, null == parentEl.lastElementChild, "firstElementChild or lastElementChild is not null"); + + //from et-dynamic-add.html + parentEl = document.getElementById("parentEl_dynamicadd"); + var newChild = document.createElement("span") + parentEl.appendChild( newChild ); + is(parentEl.childElementCount && 2, parentEl.childElementCount, "failed to add span element"); + + //from et-dynamic-remove.html + parentEl = document.getElementById("parentEl_dynamicremove"); + var lec = parentEl.lastElementChild; + parentEl.removeChild( lec ); + is(parentEl.childElementCount && 1, parentEl.childElementCount, "failed to remove span element"); + + //from et-firstElementChild.html + parentEl = document.getElementById("parentEl_fec"); + var fec = parentEl.firstElementChild; + is(fec.nodeType, 1, "failed to get firstElementChild"); + is(fec.getAttribute("id"), "first_element_child_fec", "failed to get firstElementChild"); + isnot(fec, null, "failed to get firstElementChild"); + + //from et-lastElementChild.html + parentEl = document.getElementById("parentEl_lec"); + var lec = parentEl.lastElementChild; + is(lec.nodeType, 1, "failed to get lastElementChild"); + is(lec.getAttribute("id"), "last_element_child_lec", "failed to get lastElementChild"); + isnot(lec, null, "failed to get lastElementChild"); + + //from et-namespace.html + parentEl = document.getElementById("parentEl_namespace"); + var nChild = parentEl.firstElementChild; + is(nChild && "dill", nChild.localName, "failed to get a namespace element"); + + + //from et-nextElementSibling.html + parentEl = document.getElementById("parentEl_nes"); + var fec = parentEl.firstElementChild; + var nes = fec.nextElementSibling; + is(nes.nodeType, 1, "failed to get nextElementSibling"); + is(nes.getAttribute("id"), "last_element_child_nes", "failed to get nextElementSibling"); + isnot(nes, null, "failed to get nextElementSibling"); + + //from et-previousElementSibling.html + var lec = document.getElementById("last_element_child_pes"); + var pes = lec.previousElementSibling; + is(pes.nodeType, 1, "failed to get previousElementSibling"); + is(pes.getAttribute("id"), "middle_element_child_pes", "failed to get previousElementSibling"); + isnot(pes, null, "failed to get previousElementSibling"); + + //from et-siblingElement-null.html + var fec = document.getElementById("first_element_child_sibnull"); + var pes = fec.previousElementSibling; + var nes = fec.nextElementSibling; + is(pes, null, "got unexpected previousElementSibling"); + is(nes, null, "got unexpected nextElementSibling"); + +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(runTest); +addLoadEvent(SimpleTest.finish) +]]></script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_w3element_traversal_svg.html b/dom/base/test/test_w3element_traversal_svg.html new file mode 100644 index 0000000000..7a1407434a --- /dev/null +++ b/dom/base/test/test_w3element_traversal_svg.html @@ -0,0 +1,107 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Test for ElementTraversal via SVG</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<p id="display"></p> +<div id="content" style="display: none"></div> + +<iframe id="svg" src="w3element_traversal.svg"></iframe> + +<pre id="test"> +<script class="testbody" type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +function run() +{ + var doc = $("svg").contentDocument; + + //et-namespace.svg + var parentEl = doc.getElementById("parentEl_namespace"); + var nChild = parentEl.firstElementChild; + is(nChild && "dill", nChild.localName, "failed to get child with namespace") + + //et-previousElementSibling.svg + var lec = doc.getElementById("last_element_child_pes"); + var pes = lec.previousElementSibling; + isnot(pes, null, "previousElementSibling is null"); + is(pes.nodeType, 1, "previousElementSibling returned the wrong node type"); + is(pes.getAttribute("id"), "middle_element_child_pes", "previousElementSibling returned the wrong child"); + + //et-sibling_null.svg + var fec = doc.getElementById("first_element_child_sibnull"); + var pes = fec.previousElementSibling; + var nes = fec.nextElementSibling; + is(pes, null, "previousElementSibling is not null"); + is(nes, null, "nextElementSibling is not null"); + + //et-nextElementSibling.svg + fec = doc.getElementById("first_element_child_nes"); + var nes = fec.nextElementSibling; + isnot(nes, null, "nextElementSibling returned NULL"); + is(nes.nodeType, 1, "nextElementSibling returned wrong node type"); + is(nes.getAttribute("id"), "last_element_child_nes", "nextElementSibling returned wrong node id"); + + //et-lastElementChild.svg + var parentEl = doc.getElementById("parentEl_lec"); + var lec = parentEl.lastElementChild; + isnot(lec, null, "lastElementChild returned null"); + is(lec.nodeType, 1, "lastElementChild returned wrong nodeType"); + is(lec.getAttribute("id"), "last_element_child_lec", "lastElementChild returned wrong id"); + + //et-firstElementChild.svg + var parentEl = doc.getElementById("parentEl_fec"); + var fec = parentEl.firstElementChild; + isnot(fec, null, "firstElementChild returned null"); + is(fec.nodeType, 1, "firstElementChild returned wrong nodeType"); + is(fec.getAttribute("id"), "first_element_child_fec", "firstElementChild returned wrong id"); + + //et-entity.svg + var parentEl = doc.getElementById("parentEl_entity"); + var fec = parentEl.firstElementChild; + isnot(fec, null, "firstElementChild returned null"); + is(fec.nodeType, 1, "firstElementChild returned wrong nodeType"); + is(fec.getAttribute("id"), "first_element_child_entity", "firstElementChild returned wrong id"); + + //et-dynamic-remove.svg + var parentEl = doc.getElementById("parentEl_dynremove"); + var lec = parentEl.lastElementChild; + parentEl.removeChild( lec ); + is(parentEl.childElementCount && 1, parentEl.childElementCount, "failed to removeChild"); + + //et-dynamic-add.svg + var parentEl = doc.getElementById("parentEl_dynadd"); + var newChild = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + parentEl.appendChild( newChild ); + is(parentEl.childElementCount && 2, parentEl.childElementCount, "failed to appendChild"); + + //et-childElement-null.svg + var parentEl = doc.getElementById("parentEl_null"); + var fec = parentEl.firstElementChild; + var lec = parentEl.lastElementChild; + is(fec, null, "expected null from firstElementChild"); + is(lec, null, "expected null from lastElementChild"); + + + //et-childElementCount.svg + var parentEl = doc.getElementById("parentEl_count"); + is(parentEl.childElementCount && 3, parentEl.childElementCount, "got wrong childElementCount"); + + //et-childElementCount-nochild.svg + var parentEl = doc.getElementById("parentEl_nochild"); + is(0, parentEl.childElementCount, "got wrong childElementCount"); + + + SimpleTest.finish(); +} + +window.addEventListener("load", run, false); +</script> +</pre> +</body> +</html> + diff --git a/dom/base/test/test_warning_for_blocked_cross_site_request.html b/dom/base/test/test_warning_for_blocked_cross_site_request.html new file mode 100644 index 0000000000..590506d2ee --- /dev/null +++ b/dom/base/test/test_warning_for_blocked_cross_site_request.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=713980 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 713980</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + + <!-- Load a cross-origin webfont without CORS (common pain point --> + <style> + @font-face { + font-family: "bad_cross_origin_webfont"; + src: url('http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=font_bad&type=application/octet-stream'); + } + div#bad_webfont { font-family: "bad_cross_origin_webfont"; } + </style> +</head> +<body> +<pre id="test"> + +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); + +var tests = { + font : { + uri_test : "font_bad", + result : null + }, + xhr : { + uri_test : "http://invalid", + result : null + }, +} + +function testsComplete() { + for (var testName in tests) { + var test = tests[testName]; + if (test.result == null) + return false; + } + return true; +} + +SpecialPowers.registerConsoleListener(function CORSMsgListener(aMsg) { + if (!/Cross-Origin Request Blocked/.test(aMsg.message)) + return; + + for (var testName in tests) { + var test = tests[testName]; + if (test.result != null) + continue; + + var testRegexp = new RegExp(test.uri_test); + if (testRegexp.test(aMsg.message)) { + test.result = true; + ok(true, "Got \"Cross-site request blocked\" warning message for " + testName); + ok(aMsg.category == "CORS", "Got warning message with category \"" + aMsg.category + "\", expected \"CORS\""); + // Got the message we wanted - make sure it is destined for a valid inner window + ok(aMsg.windowID != 0, "Valid (non-zero) windowID for the cross-site request blocked message."); + break; + } + } + + if (testsComplete()) { + SimpleTest.executeSoon(cleanup); + } +}); + +function cleanup() { + SpecialPowers.postConsoleSentinel(); + SimpleTest.finish(); +} + +// Send a cross-origin XHR request without CORS +var xhr = new XMLHttpRequest(); +xhr.open("GET", "http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?allowOrigin=http://invalid", true); +xhr.send(null); + +// Create a div that triggers a cross-origin webfont request +// We do this in Javascript in order to guarantee the console listener has +// already been registered; otherwise, there could be a race. +var badDiv = document.createElement('div'); +badDiv.setAttribute('id', 'bad_webfont'); +document.body.appendChild(badDiv); +</script> + +</pre> +</body> +</html> diff --git a/dom/base/test/test_webSocket_sandbox.html b/dom/base/test/test_webSocket_sandbox.html new file mode 100644 index 0000000000..b343fa784f --- /dev/null +++ b/dom/base/test/test_webSocket_sandbox.html @@ -0,0 +1,34 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Bug 1252751</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<div id="container"></div> +<iframe id="frame"></iframe> +<script type="application/javascript;version=1.8"> +var urls = [ "https://example.com/tests/dom/base/test/iframe_webSocket_sandbox.html", + "https://example.com/tests/dom/base/test/iframe_webSocket_sandbox.html?nested", + "https://example.com/tests/dom/base/test/iframe_webSocket_sandbox.html?popup" ]; + +onmessage = function(e) { + is(e.data, "WS Throws!", "ws://URI cannot be used by a https iframe"); + runTest(); +} + +function runTest() { + if (!urls.length) { + SimpleTest.finish(); + return; + } + + document.getElementById("frame").src = urls.shift(); +} + +SimpleTest.waitForExplicitFinish(); +runTest(); +</script> +</body> +</html> diff --git a/dom/base/test/test_webaudioNotification.html b/dom/base/test/test_webaudioNotification.html new file mode 100644 index 0000000000..d010e916bf --- /dev/null +++ b/dom/base/test/test_webaudioNotification.html @@ -0,0 +1,81 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> +<iframe></iframe> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; +var iframe = null; + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + SimpleTest.executeSoon(runTest); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var tests = [ + function() { + iframe = document.querySelector("iframe"); + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + iframe.src = "file_webaudioLoop.html"; + expectedNotification = 'active'; + }, + + function() { + expectedNotification = 'inactive-pause'; + iframe.contentWindow.suspendAC(); + }, + + function() { + expectedNotification = 'active'; + iframe.contentWindow.resumeAC(); + }, + + function() { + expectedNotification = 'inactive-pause'; + iframe.contentWindow.closeAC(); + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +onload = runTest; + +</script> +</body> +</html> + diff --git a/dom/base/test/test_webaudioNotificationStopOnNavigation.html b/dom/base/test/test_webaudioNotificationStopOnNavigation.html new file mode 100644 index 0000000000..237d674026 --- /dev/null +++ b/dom/base/test/test_webaudioNotificationStopOnNavigation.html @@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for audio controller in windows</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<pre id="test"> +</pre> +<iframe></iframe> + +<script type="application/javascript"> + +SimpleTest.waitForExplicitFinish(); + +var expectedNotification = null; +var iframe = null; + +var observer = { + observe: function(subject, topic, data) { + is(topic, "audio-playback", "audio-playback received"); + is(data, expectedNotification, "This is the right notification"); + runTest(); + } +}; + +var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] + .getService(SpecialPowers.Ci.nsIObserverService); + +var tests = [ + function() { + iframe = document.querySelector("iframe"); + observerService.addObserver(observer, "audio-playback", false); + ok(true, "Observer set"); + runTest(); + }, + + function() { + expectedNotification = 'active'; + iframe.src = "file_webaudioLoop2.html"; + }, + + function() { + expectedNotification = 'inactive-pause'; + iframe.src = "data:text/html,page without audio"; + }, + + function() { + observerService.removeObserver(observer, "audio-playback"); + ok(true, "Observer removed"); + runTest(); + } +]; + +function runTest() { + if (!tests.length) { + SimpleTest.finish(); + return; + } + + var test = tests.shift(); + test(); +} + +onload = runTest; + +</script> +</body> +</html> + diff --git a/dom/base/test/test_websocket1.html b/dom/base/test/test_websocket1.html new file mode 100644 index 0000000000..1894f5314f --- /dev/null +++ b/dom/base/test/test_websocket1.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta> + <title>WebSocket test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="websocket_helpers.js"></script> + <script type="text/javascript" src="websocket_tests.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="testWebSocket()"> +<script class="testbody" type="text/javascript"> + +var tests = [ + test1, // client tries to connect to a http scheme location; + test2, // assure serialization of the connections; + test3, // client tries to connect to an non-existent ws server; + test4, // client tries to connect using a relative url; + test5, // client uses an invalid protocol value; + test6, // counter and encoding check; + test7, // onmessage event origin property check + test8, // client calls close() and the server sends the close frame (with no + // code or reason) in acknowledgement; + test9, // client closes the connection before the ws connection is established; + test10, // client sends a message before the ws connection is established; +]; + +function testWebSocket() { + doTest(); +} + +SimpleTest.requestFlakyTimeout("The web socket tests are really fragile, but avoiding timeouts might be hard, since it's testing stuff on the network. " + + "Expect all sorts of flakiness in this test..."); +SimpleTest.waitForExplicitFinish(); + +</script> + +<div id="feedback"> +</div> + +</body> +</html> diff --git a/dom/base/test/test_websocket2.html b/dom/base/test/test_websocket2.html new file mode 100644 index 0000000000..5711057cf4 --- /dev/null +++ b/dom/base/test/test_websocket2.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta> + <title>WebSocket test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="websocket_helpers.js"></script> + <script type="text/javascript" src="websocket_tests.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="testWebSocket()"> +<script class="testbody" type="text/javascript"> + +var tests = [ + test11, // a simple hello echo; + test12, // client sends a message containing unpaired surrogates + test13, //server sends an invalid message; + test14, // server sends the close frame, it doesn't close the tcp connection + // and it keeps sending normal ws messages; + test15, // server closes the tcp connection, but it doesn't send the close + // frame; + test16, // client calls close() and tries to send a message; + test17, // see bug 572975 - all event listeners set + test18, // client tries to connect to an http resource; + test19, // server closes the tcp connection before establishing the ws + // connection; + test20, // see bug 572975 - only on error and onclose event listeners set +]; + +function testWebSocket() { + doTest(); +} + +SimpleTest.requestFlakyTimeout("The web socket tests are really fragile, but avoiding timeouts might be hard, since it's testing stuff on the network. " + + "Expect all sorts of flakiness in this test..."); +SimpleTest.waitForExplicitFinish(); + +</script> + +<div id="feedback"> +</div> + +</body> +</html> diff --git a/dom/base/test/test_websocket3.html b/dom/base/test/test_websocket3.html new file mode 100644 index 0000000000..57482dae7f --- /dev/null +++ b/dom/base/test/test_websocket3.html @@ -0,0 +1,44 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta> + <title>WebSocket test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="websocket_helpers.js"></script> + <script type="text/javascript" src="websocket_tests.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="testWebSocket()"> +<script class="testbody" type="text/javascript"> + +var tests = [ + test21, // see bug 572975 - same as test 17, but delete strong event listeners + // when receiving the message event; + test22, // server takes too long to establish the ws connection; + test23, // should detect WebSocket on window object; + test24, // server rejects sub-protocol string + test25, // ctor with valid empty sub-protocol array + test26, // ctor with invalid sub-protocol array containing 1 empty element + test27, // ctor with invalid sub-protocol array containing an empty element in + // list + test28, // ctor using valid 1 element sub-protocol array + test29, // ctor using all valid 5 element sub-protocol array + test30, // ctor using valid 1 element sub-protocol array with element server + // will reject +]; + +function testWebSocket() { + doTest(); +} + +SimpleTest.requestFlakyTimeout("The web socket tests are really fragile, but avoiding timeouts might be hard, since it's testing stuff on the network. " + + "Expect all sorts of flakiness in this test..."); +SimpleTest.waitForExplicitFinish(); + +</script> + +<div id="feedback"> +</div> + +</body> +</html> diff --git a/dom/base/test/test_websocket4.html b/dom/base/test/test_websocket4.html new file mode 100644 index 0000000000..4bc700fb81 --- /dev/null +++ b/dom/base/test/test_websocket4.html @@ -0,0 +1,42 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta> + <title>WebSocket test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="websocket_helpers.js"></script> + <script type="text/javascript" src="websocket_tests.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="testWebSocket()"> +<script class="testbody" type="text/javascript"> + +var tests = [ + test31, // ctor using valid 2 element sub-protocol array with 1 element server + // will reject and one server will accept + test32, // ctor using invalid sub-protocol array that contains duplicate items + test33, // test for sending/receiving custom close code (but no close reason) + test34, // test for receiving custom close code and reason + test35, // test for sending custom close code and reason + test36, // negative test for sending out of range close code + test37, // negative test for too long of a close reason + test38, // ensure extensions attribute is defined + test39, // a basic wss:// connectivity test + test40, // negative test for wss:// with no cert +]; + +function testWebSocket() { + doTest(); +} + +SimpleTest.requestFlakyTimeout("The web socket tests are really fragile, but avoiding timeouts might be hard, since it's testing stuff on the network. " + + "Expect all sorts of flakiness in this test..."); +SimpleTest.waitForExplicitFinish(); + +</script> + +<div id="feedback"> +</div> + +</body> +</html> diff --git a/dom/base/test/test_websocket5.html b/dom/base/test/test_websocket5.html new file mode 100644 index 0000000000..70a9488211 --- /dev/null +++ b/dom/base/test/test_websocket5.html @@ -0,0 +1,40 @@ +<!DOCTYPE HTML> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"></meta> + <title>WebSocket test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" src="websocket_helpers.js"></script> + <script type="text/javascript" src="websocket_tests.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="testWebSocket()"> +<script class="testbody" type="text/javascript"> + +var tests = [ + test41, // HSTS + test42, // non-char utf-8 sequences + test43, // Test setting binaryType attribute + test44, // Test sending/receving binary ArrayBuffer + test45, // Test sending/receving binary Blob + test46, // Test that we don't dispatch incoming msgs once in CLOSING state + test47, // Make sure onerror/onclose aren't called during close() + test48, // see bug 1227136 - client calls close() from onopen() and waits + // until WebSocketChannel::mSocketIn is nulled out on socket thread +]; + +function testWebSocket() { + doTest(); +} + +SimpleTest.requestFlakyTimeout("The web socket tests are really fragile, but avoiding timeouts might be hard, since it's testing stuff on the network. " + + "Expect all sorts of flakiness in this test..."); +SimpleTest.waitForExplicitFinish(); + +</script> + +<div id="feedback"> +</div> + +</body> +</html> diff --git a/dom/base/test/test_websocket_basic.html b/dom/base/test/test_websocket_basic.html new file mode 100644 index 0000000000..e3269382e6 --- /dev/null +++ b/dom/base/test/test_websocket_basic.html @@ -0,0 +1,255 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Basic WebSocket test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> + +<body onload="testWebSocket()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=472529">Mozilla Bug 472529</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +const kUrl = "ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic"; + +var gTestElement; +var ws; + +function forcegc() { + SpecialPowers.forceGC(); + SpecialPowers.gc(); +} + +function testWebSocket() { + gTestElement = document.getElementById("test"); + + SimpleTest.executeSoon(testWebSocket1); +} + +/** + * Sends message keywords, then receives their values. + */ +function testWebSocket1() { + gTestElement.textContent = "Running testWebSocket1()"; + + var results = ["test", + "/tests/dom/base/test/file_websocket_basic", + "http://mochi.test:8888", + "end"]; + + ws = new WebSocket(kUrl, "test"); + is(ws.url, kUrl, "[1] WebSocket.url"); + ws.onopen = function(e) { + const params = ["protocol", "resource", "origin", "end"]; + + gTestElement.textContent += "\nSending :"; + for (var i = 0; i < params.length; ++i) { + gTestElement.textContent += " " + params[i]; + ws.send(params[i]); + } + + // Set this before onmessage() is called, so it is displayed once only. + gTestElement.textContent += "\nReceived:"; + }; + ws.onclose = function(e) { + is(results.length, 0, "[1] Number of unreceived messages"); + ok(e.wasClean, "[1] Connection closed cleanly"); + + SimpleTest.executeSoon(testWebSocket2); + }; + ws.onerror = function(e) { + ok(false, "[1] onerror() should not have been called!"); + gTestElement.textContent += "\nonerror() should not have been called!"; + SimpleTest.executeSoon(SimpleTest.finish); + }; + ws.onmessage = function(e) { + is(e.data, results[0], "[1] Received message"); + gTestElement.textContent += " " + e.data; + results.shift(); + }; +} + +/** + * Sends 1000+1 test messages, then receives them. + */ +function testWebSocket2() { + gTestElement.textContent = "Running testWebSocket2()"; + + const displayInterval = 100; + const testCount = 1000; + const testMessage = "test message 2."; + + var messageCount = 0; + + ws = new WebSocket(kUrl, "test"); + ws.onopen = function(e) { + gTestElement.textContent += "\nSending :"; + for (var i = 1; i <= testCount; ++i) { + if (i % displayInterval == 1) { + gTestElement.textContent += " " + i; + } + ws.send(testMessage + i); + } + gTestElement.textContent += " end"; + ws.send("end"); + + // Set this before onmessage() is called, so it is displayed once only. + gTestElement.textContent += "\nReceived:"; + }; + ws.onclose = function(e) { + is(messageCount, testCount + 1, "[2] Number of received messages"); + ok(e.wasClean, "[2] Connection closed cleanly"); + + SimpleTest.executeSoon(testWebSocket3); + }; + ws.onerror = function(e) { + ok(false, "[2] onerror() should not have been called!"); + gTestElement.textContent += "\nonerror() should not have been called!"; + SimpleTest.executeSoon(SimpleTest.finish); + }; + ws.onmessage = function(e) { + ++messageCount; + if (messageCount > testCount) + is(e.data, "end", "[2] Received message"); + else + is(e.data, testMessage + messageCount, "[2] Received message"); + if (messageCount % displayInterval == 1) { + gTestElement.textContent += " " + messageCount; + } + }; +} + +/** + * Sends testcount+1 test messages, then receives them, calling forcegc() at each step. + */ +function testWebSocket3() { + gTestElement.textContent = "Running testWebSocket3() [can take a little while]"; + + const displayInterval = 10; + const testCount = 10; + const testMessage = "test message 3."; + + var messageCount = 0; + + ws = new WebSocket(kUrl, "test"); + // Set this before onopen() is called, + // otherwise its display would be delayed by forcegc() calls... + gTestElement.textContent += "\nSending :"; + ws.onopen = function(e) { + for (var i = 1; i <= testCount; ++i) { + forcegc(); + if (i % displayInterval == 1) { + // Actual display is delayed by forcegc() calls... + gTestElement.textContent += " " + i; + } + ws.send(testMessage + i); + } + forcegc(); + gTestElement.textContent += " end"; + ws.send("end"); + + // Set this before onmessage() is called, so it is displayed once only. + gTestElement.textContent += "\nReceived:"; + }; + ws.onclose = function(e) { + is(messageCount, testCount + 1, "[3] Number of received messages"); + ok(e.wasClean, "[3] Connection closed cleanly"); + + SimpleTest.executeSoon(testWebSocket4); + }; + ws.onerror = function(e) { + ok(false, "[3] onerror() should not have been called!"); + gTestElement.textContent += "\nonerror() should not have been called!"; + SimpleTest.executeSoon(SimpleTest.finish); + }; + ws.onmessage = function(e) { + forcegc(); + ++messageCount; + if (messageCount > testCount) + is(e.data, "end", "[3] Received message"); + else + is(e.data, testMessage + messageCount, "[3] Received message"); + if (messageCount % displayInterval == 1) { + // Actual display is delayed by forcegc() call(s)... + gTestElement.textContent += " " + messageCount; + } + }; +} + +/** + * Sends a huge test message, then receives it, then closes the WebSocket from client-side. + */ +function testWebSocket4() { + gTestElement.textContent = "Running testWebSocket4()"; + + // String length = 13 + ((10,000 - 1) * 26) + 11 = 259,998 = almost 254 KiB. + const longString = "messageStart " + new Array(10000).join(" -huge WebSocket message- ") + " messageEnd"; + + ws = new WebSocket(kUrl, "test"); + ws.onopen = function(e) { + is(this, ws, "[4, onopen()] 'this' should point to the WebSocket."); + gTestElement.textContent += "\nSending the huge message"; + ws.send(longString); + }; + ws.onclose = function(e) { + is(this, ws, "[4, onclose()] 'this' should point to the WebSocket."); + ok(e.wasClean, "[4] Connection closed cleanly"); + + SimpleTest.executeSoon(testWebSocket5); + }; + ws.onerror = function(e) { + is(this, ws, "[4, onerror()] 'this' should point to the WebSocket."); + ok(false, "[4, onerror()] should not have been called!"); + gTestElement.textContent += "\nonerror() should not have been called!"; + SimpleTest.executeSoon(SimpleTest.finish); + }; + ws.onmessage = function(e) { + is(this, ws, "[4, onmessage()] 'this' should point to the WebSocket."); + // Do not use |is(e.data, longString, "...");| that results in a _very_ long line. + is(e.data.length, longString.length, "[4] Length of received message"); + ok(e.data == longString, "[4] Content of received message"); + gTestElement.textContent += "\nReceived the huge message"; + this.close(); + }; +} + +/** + * Closes the WebSocket from client-side, then sends a test message that should be buffered. + */ +function testWebSocket5() { + gTestElement.textContent = "Running testWebSocket5()"; + + ws = new WebSocket(kUrl, "test"); + ws.onopen = function(e) { + is(this.bufferedAmount, 0, "[5] Length of empty buffer before closing"); + this.close(); + }; + ws.onclose = function(e) { + ok(e.wasClean, "[5] Connection closed cleanly"); + is(this.bufferedAmount, 0, "[5] Length of empty buffer after closing"); + + var msg = "test message to be buffered"; + this.send(msg); + is(this.bufferedAmount, msg.length, "[5] Length of buffered message sent after closing"); + + gTestElement.textContent += "\ntestWebSocket5() completed"; + + SimpleTest.executeSoon(SimpleTest.finish); + }; + ws.onerror = function(e) { + ok(false, "[5] onerror() should not have been called!"); + gTestElement.textContent += "\nonerror() should not have been called!"; + SimpleTest.executeSoon(SimpleTest.finish); + }; +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_websocket_frame.html b/dom/base/test/test_websocket_frame.html new file mode 100644 index 0000000000..59ab859077 --- /dev/null +++ b/dom/base/test/test_websocket_frame.html @@ -0,0 +1,166 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Basic websocket frame interception test</title> + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> +</head> +<body> +<script class="testbody" type="text/javascript"> + +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +const URI = "ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic"; + +var frameReceivedCounter = 0; +var frameSentCounter = 0; +var webSocketCreatedCounter = 0; +var webSocketOpenedCounter = 0; +var webSocketMessageAvailableCounter = 0; +var webSocketClosedCounter = 0; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +var tests = [ + { payload: "Hello world!" }, + { payload: (function() { var buffer = ""; for (var i = 0; i < 120; ++i) buffer += i; return buffer; }()) }, +] + +var innerId = + window.top.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID; +ok(innerId, "We have a valid innerWindowID: " + innerId); + +var service = Cc["@mozilla.org/websocketevent/service;1"] + .getService(Ci.nsIWebSocketEventService); +ok(!!service, "We have the nsIWebSocketEventService"); + +var listener = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebSocketEventListener]), + + webSocketCreated: function(aWebSocketSerialID, aURI, aProtocols) { + info("WebSocketCreated"); + + is(aURI, URI, "URI matches"); + is(aProtocols, "frame", "Protocol matches"); + + webSocketCreatedCounter++; + }, + + webSocketOpened: function(aWebSocketSerialID, aEffectiveURI, aProtocols, aExtensions) { + info("WebSocketOpened"); + + is(aEffectiveURI, URI, "EffectiveURI matches"); + is(aProtocols, "frame", "Protocol matches"); + is(aExtensions, "permessage-deflate", "No extensions"); + + webSocketOpenedCounter++; + }, + + webSocketMessageAvailable: function(aWebSocketSerialID, aData, aMessageType) { + info("WebSocketMessageAvailable"); + + if (tests.length) { + is(aData, tests[0].payload, "Message matches!"); + is(aMessageType, Ci.nsIWebSocketEventListener.TYPE_STRING, "The type is 'string'"); + + webSocketMessageAvailableCounter++; + + tests.shift(); + if (tests.length) { + ws.send(tests[0].payload); + } else { + ws.send("end"); + } + } + }, + + webSocketClosed: function(aWebSocketSerialID, aWasClean, + aCode, aReason) { + info("WebSocketClosed"); + + ok(aWasClean, "The socket is closed in a clean state"); + is(aCode, 1000, "Exit code 1000"); + ok(!aReason.length, "No reason"); + + webSocketClosedCounter++; + checkListener(); + }, + + frameReceived: function(aWebSocketSerialID, aFrame) { + ok(!!aFrame, "We have received a frame"); + + if (tests.length) { + ok(aFrame.timeStamp, "Checking timeStamp: " + aFrame.timeStamp); + is(aFrame.finBit, true, "Checking finBit"); + is(aFrame.rsvBit1, true, "Checking rsvBit1"); + is(aFrame.rsvBit2, false, "Checking rsvBit2"); + is(aFrame.rsvBit3, false, "Checking rsvBit3"); + is(aFrame.opCode, aFrame.OPCODE_TEXT, "Checking opCode"); + is(aFrame.maskBit, false, "Checking maskBit"); + is(aFrame.mask, 0, "Checking mask"); + is(aFrame.payload, tests[0].payload, "Checking payload: " + aFrame.payload); + } + + frameReceivedCounter++; + }, + + frameSent: function(aWebSocketSerialID, aFrame) { + ok(!!aFrame, "We have sent a frame"); + + if (tests.length) { + ok(aFrame.timeStamp, "Checking timeStamp: " + aFrame.timeStamp); + is(aFrame.finBit, true, "Checking finBit"); + is(aFrame.rsvBit1, true, "Checking rsvBit1"); + is(aFrame.rsvBit2, false, "Checking rsvBit2"); + is(aFrame.rsvBit3, false, "Checking rsvBit3"); + is(aFrame.opCode, aFrame.OPCODE_TEXT, "Checking opCode"); + is(aFrame.maskBit, true, "Checking maskBit"); + ok(!!aFrame.mask, "Checking mask: " + aFrame.mask); + is(aFrame.payload, tests[0].payload, "Checking payload: " + aFrame.payload); + } + + frameSentCounter++; + } +}; + +service.addListener(innerId, listener); +ok(true, "Listener added"); + +function checkListener() { + service.removeListener(innerId, listener); + + ok(frameReceivedCounter, "We received some frames!"); + ok(frameSentCounter, "We sent some frames!"); + ok(webSocketCreatedCounter, "We have a create notification"); + ok(webSocketOpenedCounter, "We have a open notification"); + ok(webSocketMessageAvailableCounter, "We have a messageAvailable notification"); + ok(webSocketClosedCounter, "We have a close notification"); + SimpleTest.finish(); +} + +var ws = new WebSocket(URI, "frame"); +ws.onopen = function(e) { + info("onopen"); + + ws.send(tests[0].payload); +} + +ws.onclose = function(e) { + info("onclose"); +} + +ws.onmessage = function(e) { + info("onmessage"); + if (tests.length) { + is(e.data, tests[0].payload, "Wrong data"); + } +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> diff --git a/dom/base/test/test_websocket_hello.html b/dom/base/test/test_websocket_hello.html new file mode 100644 index 0000000000..c1874ab985 --- /dev/null +++ b/dom/base/test/test_websocket_hello.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +--> +<head> + <title>Basic websocket test</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="testWebSocket()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=472529">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var ws; + +function testWebSocket () { + ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/file_websocket_hello"); + ws.onopen = function(e) { + ws.send("data"); + } + ws.onclose = function(e) { + } + ws.onerror = function(e) { + ok(false, "onerror called!"); + SimpleTest.finish(); + } + ws.onmessage = function(e) { + is(e.data, "Hello world!", "Wrong data"); + ws.close(); + SimpleTest.finish(); + } +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +<div> + + +</div> + + +</body> +</html> diff --git a/dom/base/test/test_websocket_permessage_deflate.html b/dom/base/test/test_websocket_permessage_deflate.html new file mode 100644 index 0000000000..5c40600c48 --- /dev/null +++ b/dom/base/test/test_websocket_permessage_deflate.html @@ -0,0 +1,110 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Basic test of permessage compression websocket extension</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="loadDeflate()"> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=792831">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> + +var ws; +var textMessage = "This is a text message"; +var binaryMessage = "This is a binary message"; +var testIdx = 0; +var sendText = true; + +tests = [ + // enable PMCE + [ true, true, "ws://mochi.test:8888/tests/dom/base/test/file_websocket_permessage_deflate" ], + // disable PMCE + [ false, false, "ws://mochi.test:8888/tests/dom/base/test/file_websocket_permessage_deflate_disabled" ], + // server rejects offered PMCE + [ true, false, "ws://mochi.test:8888/tests/dom/base/test/file_websocket_permessage_deflate_rejected" ], + // server returns parameters in the handshake + [ true, true, "ws://mochi.test:8888/tests/dom/base/test/file_websocket_permessage_deflate_params" ] +] + +function ab2str(buf) { + return String.fromCharCode.apply(null, new Uint16Array(buf)); +} + +function str2ab(str) { + var buf = new ArrayBuffer(str.length*2); + var bufView = new Uint16Array(buf); + for (var i=0, strLen=str.length; i<strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; +} + +function sendMessage() { + if (sendText) { + ws.send(textMessage); + } else { + ws.binaryType = "arraybuffer"; + ws.send(str2ab(binaryMessage)); + } +} + +function testDeflate() { + ws = new WebSocket(tests[testIdx][2]); + + ws.onopen = function(e) { + if (tests[testIdx][1]) { + is(ws.extensions, "permessage-deflate", "permessage-deflate not negotiated!"); + } else { + is(ws.extensions, "", "permessage-deflate should not be negotiated!"); + } + + sendMessage(); + } + + ws.onclose = function(e) { + if (!e.wasClean) { + ok(false, "Connection should be closed cleanly!"); + SimpleTest.finish(); + } + } + + ws.onerror = function(e) { + ok(false, "onerror called!"); + SimpleTest.finish(); + } + + ws.onmessage = function(e) { + if (sendText) { + is(e.data, textMessage, "Text message not received successfully!"); + sendText = false; + sendMessage(); + } else { + ok(e.data instanceof ArrayBuffer, "Should receive an arraybuffer!"); + is(ab2str(e.data), binaryMessage, "Binary message not received successfully!"); + ws.close(); + + sendText = true; + testIdx++; + if (testIdx < tests.length) { + loadDeflate(); + } else { + SimpleTest.finish(); + } + } + } +} + +function loadDeflate() { + SpecialPowers.pushPrefEnv({"set":[['network.websocket.extensions.permessage-deflate', tests[testIdx][0]]]}, testDeflate); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_constructor.html b/dom/base/test/test_window_constructor.html new file mode 100644 index 0000000000..7020438394 --- /dev/null +++ b/dom/base/test/test_window_constructor.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=824217 +--> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 824217</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622491">Mozilla Bug 824217</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<iframe name="constructor" src="about:blank"></iframe> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +function run() +{ + // Ideally we'd test that this property lives on the right place in the + // [[Prototype]] chain, with the right attributes there, but we don't + // implement this right yet, so just test the value's what's expected. + is(window.constructor, Window, + "should have gotten Window, not the constructor frame"); + SimpleTest.finish(); +} + +window.addEventListener("load", run, false); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_cross_origin_props.html b/dom/base/test/test_window_cross_origin_props.html new file mode 100644 index 0000000000..d16a103fb6 --- /dev/null +++ b/dom/base/test/test_window_cross_origin_props.html @@ -0,0 +1,101 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=946067 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 946067</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 946067 **/ + SimpleTest.waitForExplicitFinish(); + + function doGet(prop, thisObj) { + return Object.getOwnPropertyDescriptor(window, prop).get.call(thisObj); + } + + function doSet(prop, thisObj, value) { + return Object.getOwnPropertyDescriptor(window, prop).set.call(thisObj, value); + } + + window.onload = function() { + frames[0].focus(); + is(document.activeElement.id, "x", "Should have focused first subframe"); + frames[0].blur(); + window.focus.call(frames[1]); + is(document.activeElement.id, "y", "Should have focused second subframe"); + window.blur.call(frames[1]); + + frames[0].close(); + is(frames[0].closed, false, "Subframe is not closed"); + window.close.call(frames[0]); + is(doGet("closed", frames[0]), false, "Subframe is still not closed"); + + is(frames[0].frames, frames[0], "window.frames === window"); + is(doGet("frames", frames[0]), frames[0], + "Really, window.frames === window"); + + try { + frames[0].frames = 1; + ok(false, "Should throw when setting .frames"); + } catch (e) { + ok(true, "Should throw when setting .frames"); + } + try { + doSet("frames", frames[0], 1); + ok(false, "Should still throw when setting .frames"); + } catch (e) { + ok(true, "Should still throw when setting .frames"); + } + + // Just check whether we can get the location without throwing: + is(frames[0].location, doGet("location", frames[0]), + "Should be same Location object"); + + is(frames[0].length, 0, "404 page has no subframes"); + is(doGet("length", frames[0]), 0, "404 page has no subframes"); + + is(frames[0].opener, null, "subframe has no opener"); + is(doGet("opener", frames[0]), null, "subframe still has no opener"); + + is(frames[0].parent, window, "subframe has us as parent"); + is(doGet("parent", frames[0]), window, "subframe still has us as parent"); + + // Check that postMessage doesn't throw + frames[0].postMessage(null, "*"); + + is(frames[0].self, frames[0], "self should work"); + is(doGet("self", frames[0]), frames[0], "self should still work"); + + is(frames[0].top, window.top, "Our subframe's top should be our top"); + is(doGet("top", frames[0]), window.top, + "Our subframe's top should still be our top"); + + is(frames[0].window, frames[0], "window getter should work"); + is(doGet("window", frames[0]), frames[0], "window getter should still work"); + isnot(Object.getOwnPropertyDescriptor(window, "window").get, undefined, + "Should have a getter here"); + + // Finally, check that we can set the location + frames[0].location = "about:blank"; + doSet("location", frames[1], "about:blank"); + + SimpleTest.finish(); + } + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946067">Mozilla Bug 946067</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> + <iframe id="x" src="http://www.example.com/nosuchpageIhope"></iframe> + <iframe id="y" src="http://www.example.com/nosuchpageIhope"></iframe> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_define_nonconfigurable.html b/dom/base/test/test_window_define_nonconfigurable.html new file mode 100644 index 0000000000..ad1cf76878 --- /dev/null +++ b/dom/base/test/test_window_define_nonconfigurable.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1107443 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1107443</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1107443 **/ + try { + Object.defineProperty(window, "nosuchprop", { value: 5, configurable: false }); + throw "didn't throw"; + } catch (e) { + is(e instanceof TypeError, true, + "defineProperty(window) with a non-configurable property should " + + "throw a TypeError, instead got: " + e); + is(Object.getOwnPropertyDescriptor(window, "nosuchprop"), undefined, + 'Window should not have property after an attempt to define it failed'); + } + + Object.defineProperty(window, "nosuchprop", { value: 6 }); + var desc = Object.getOwnPropertyDescriptor(window, "nosuchprop"); + is(typeof(desc), "object", "Should have a property now"); + todo_is(desc.configurable, true, "Property should be configurable"); + is(desc.writable, false, "Property should be readonly"); + is(desc.value, 6, "Property should have the right value"); + + Object.defineProperty(window, "nosuchprop2", { value: 7, configurable: true }); + desc = Object.getOwnPropertyDescriptor(window, "nosuchprop2"); + is(typeof(desc), "object", "Should have a property now"); + is(desc.configurable, true, "Property should be configurable"); + is(desc.writable, false, "Property should be readonly"); + is(desc.value, 7, "Property should have the right value"); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1107443">Mozilla Bug 1107443</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_define_symbol.html b/dom/base/test/test_window_define_symbol.html new file mode 100644 index 0000000000..95ea9e6eed --- /dev/null +++ b/dom/base/test/test_window_define_symbol.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1082672 +--> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 1082672 part 2</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1082672">Mozilla Bug 1082672</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script type="application/javascript"> +if (typeof Symbol === "function") { + var sym = Symbol("ponies"); + Object.defineProperty(window, sym, {configurable: true, value: 3}); + is(window[sym], 3); +} else { + ok(true, "no Symbols in this build"); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_element_enumeration.html b/dom/base/test/test_window_element_enumeration.html new file mode 100644 index 0000000000..f8ea6728ca --- /dev/null +++ b/dom/base/test/test_window_element_enumeration.html @@ -0,0 +1,70 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=959992 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 959992</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=959992">Mozilla Bug 959992</a> +<p id="display"></p> +<div id="content" style="display: none"> + <img id="one" name="two"> + <div id="three" name="four"></div> + <div id=""></div> + <img name=""> +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 959992 **/ + var names1 = Object.getOwnPropertyNames(window); + var names2 = []; + var gsp = Object.getPrototypeOf(Window.prototype); + var names3 = Object.getOwnPropertyNames(gsp); + for (var i in window) { + names2.push(i); + } + + is(names1.indexOf(""), -1, + "Element with empty id/name should not be in our own prop list"); + is(names2.indexOf(""), -1, + "Element with empty id/name name should not be in our enumeration list"); + is(names3.indexOf(""), -1, + "Element with empty id/name should not be in GSP own prop list"); + + is(names1.indexOf("one"), -1, + "<img> with id should not be in our own prop list"); + is(names2.indexOf("one"), -1, + "<img> with id should not be in our enumeration list"); + isnot(names3.indexOf("one"), -1, + "<img> with id should be in GSP own prop list"); + + is(names1.indexOf("two"), -1, + "<img> with name should not be in our own prop list"); + is(names2.indexOf("two"), -1, + "<img> with name should not be in our enumeration list"); + isnot(names3.indexOf("two"), -1, + "<img> with name should be in GSP own prop list"); + + is(names1.indexOf("three"), -1, + "<div> with id should not be in our own prop list"); + is(names2.indexOf("three"), -1, + "<div> with id should not be in our enumeration list"); + todo_isnot(names3.indexOf("three"), -1, + "<div> with id should be in GSP own prop list"); + + is(names1.indexOf("four"), -1, + "<div> with name should not be in our own prop list"); + is(names2.indexOf("four"), -1, + "<div> with name should not be in our enumeration list"); + is(names3.indexOf("four"), -1, + "<div> with name should not be in GSP own prop list"); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_enumeration.html b/dom/base/test/test_window_enumeration.html new file mode 100644 index 0000000000..c2377426c4 --- /dev/null +++ b/dom/base/test/test_window_enumeration.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=807222 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 807222</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=807222">Mozilla Bug 807222</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 807222 **/ +var expectedProps = [ "Image", "Audio", "Option", + "PerformanceTiming", "CSS2Properties", "SVGElement" ]; +var actualProps = Object.getOwnPropertyNames(window); + +for (var i = 0; i < expectedProps.length; ++i) { + isnot(actualProps.indexOf(expectedProps[i]), -1, + "getOwnPropertyNames should include " + expectedProps[i]); +} +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_extensible.html b/dom/base/test/test_window_extensible.html new file mode 100644 index 0000000000..5f9f092918 --- /dev/null +++ b/dom/base/test/test_window_extensible.html @@ -0,0 +1,46 @@ +<!DOCTYPE html> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=856384 +--> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 856384</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=856384">Mozilla Bug 856384</a> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<iframe name="constructor" src="about:blank"></iframe> +<pre id="test"> +<script type="application/javascript"> +SimpleTest.waitForExplicitFinish(); + +function run() +{ + is(Object.isExtensible(window), true, "Windows are extensible by default"); + + try + { + Object.preventExtensions(window); + throw "didn't throw"; + } + catch (e) + { + is(e instanceof TypeError, true, + "preventExtensions(window) should throw a TypeError, instead got: " + e); + is(Object.isExtensible(window), true, + 'Windows are extensible after an extensibility "change" attempt'); + } + + SimpleTest.finish(); +} + +window.addEventListener("load", run, false); +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_indexing.html b/dom/base/test/test_window_indexing.html new file mode 100644 index 0000000000..c7450adda5 --- /dev/null +++ b/dom/base/test/test_window_indexing.html @@ -0,0 +1,139 @@ + +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=823228 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 823228</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=823228">Mozilla Bug 823228</a> +<p id="display"></p> +<div id="content" style="display: none"> + <iframe name="x" id="x"></iframe> + <iframe name="y" id="y"></iframe> +</div> +<pre id="test"> +</pre> + <script type="application/javascript"> + + /** Test for Bug 823228 **/ + is(window, window.frames, "These better be equal"); + ok("0" in window, "We have a subframe"); + ok("1" in window, "We have two subframes"); + ok(!("2" in window), "But we don't have three subframes"); + window[2] = "myString"; + ok(!("2" in window), "Should not be able to set indexed expando"); + Object.getPrototypeOf(window)[3] = "Hey there"; + ok("3" in window, "Should be walking up the proto chain"); + + is(window[0].name, "x", "First frame is x"); + is(window[1].name, "y", "Second frame is y"); + is(window[2], undefined, "We should still not have our expando"); + is(window[3], "Hey there", "We should still have our prop on the proto chain"); + + var x = $("x"); + var y = $("y"); + + is(x.contentWindow, window[0], "First frame should have correct window"); + is(y.contentWindow, window[1], "Second frame should have correct window"); + + // set() hook test + throws(TypeError, function () { + "use strict"; + window[1] = "FAIL strict"; + }); + + // set() hook test + window[1] = "FAIL"; + is(window[1].name, "y", "Second frame is still y"); + y.parentNode.removeChild(y); + ok(!("1" in window), "We no longer have two subframes"); + is(window[1], undefined, "We should not have a value here"); + + // defineProperty() hook test + function throws(errorCtor, f) { + try { + f(); + } catch (exc) { + if (!(exc instanceof errorCtor)) + throw exc; + return; + } + throw new Error("expected " + errCtor.name + ", no exception thrown: " + f); + } + + x.parentNode.appendChild(y); + throws(TypeError, function () { + Object.defineProperty(window, "1", { value: "FAIL2", configurable: true, + writable: true }); + }); + y.parentNode.removeChild(y); + ok(!("1" in window), "We no longer have two subframes, again"); + is(window[1], undefined, "We should not have a value here either"); + + // More set() hook test + throws(TypeError, function () { + "use strict"; + window[1] = "FAIL3 strict"; + }); + window[1] = "FAIL3"; + ok(!("1" in window), "We shouldn't allow indexed expandos"); + is(window[1], undefined, "We should not have a value for an indexed expando"); + var desc = Object.getOwnPropertyDescriptor(window, "1"); + is(desc, undefined, "We really really shouldn't have indexed expandos"); + + x.parentNode.appendChild(y); + is(window[1], y.contentWindow, "Second frame should now be visible"); + desc = Object.getOwnPropertyDescriptor(window, "1"); + ok(desc.configurable, "Subframe should be configurable"); + ok(desc.enumerable, "Subframe should be configurable"); + ok(!desc.writable, "Subframe should not be writable"); + is(desc.value, y.contentWindow, "Subframe should have correct value"); + + y.parentNode.removeChild(y); + is(window[1], undefined, "And now we should be back to no [1] property"); + + // And more defineProperty() + throws(TypeError, function () { + Object.defineProperty(window, "1", { value: "FAIL2", configurable: true, + writable: true }); + }); + ok(!("1" in window), "Defining indexed properties really just shouldn't work"); + is(window[1], undefined, "Defining past end of list should not work"); + + // Enumeration tests + x.parentNode.appendChild(y); + + var names = Object.getOwnPropertyNames(window); + is(names[0], "0", "Must start with 0"); + is(names[1], "1", "Must continue with 1"); + is(names.indexOf("2"), -1, "And 2, an attempted expando, should not be in there"); + is(names.indexOf("3"), -1, "But no 3; that's on the proto"); + + names = []; + for (var name in window) { + names.push(name); + } + is(names[0], "0", "Enumeration must start with 0"); + is(names[1], "1", "Enumeration must continue with 1"); + is(names.indexOf("2"), -1, "Enumeration: but no expando 2"); + isnot(names.indexOf("3"), -1, "Enumeration: and then 3, defined on the proto"); + is(names.indexOf("4"), -1, "But no 4 around"); + + // Delete tests + is(delete window[1], false, "Deleting supported index should return false"); + is(window[1], y.contentWindow, "Shouldn't be able to delete a supported index"); + y.parentNode.removeChild(y); + is(window[1], undefined, + "And now we should have no property here"); + is(delete window[1], true, "Deleting unsupported index should return true"); + is(window[1], undefined, + "And we shouldn't have things magically appear due to delete"); + </script> +</body> +</html> diff --git a/dom/base/test/test_window_named_frame_enumeration.html b/dom/base/test/test_window_named_frame_enumeration.html new file mode 100644 index 0000000000..4d3335db40 --- /dev/null +++ b/dom/base/test/test_window_named_frame_enumeration.html @@ -0,0 +1,96 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1019417 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1019417</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + + /** Test for Bug 1019417 **/ + SimpleTest.waitForExplicitFinish(); + addLoadEvent(function() { + var names1 = Object.getOwnPropertyNames(window); + var names2 = []; + var gsp = Object.getPrototypeOf(Window.prototype); + var names3 = Object.getOwnPropertyNames(gsp); + for (var i in window) { + names2.push(i); + } + + is(names1.indexOf(""), -1, + "Frame with no name or empty name should not be in our own prop list"); + is(names2.indexOf(""), -1, + "Frame with no name or empty name should not be in our enumeration list"); + is(names3.indexOf(""), -1, + "Frame with no name or empty name should not be in GSP own prop list"); + is(names1.indexOf("x"), -1, + "Frame with about:blank loaded should not be in our own prop list"); + is(names2.indexOf("x"), -1, + "Frame with about:blank loaded should not be in our enumeration list"); + isnot(names3.indexOf("x"), -1, + "Frame with about:blank loaded should be in GSP own prop list"); + is(names1.indexOf("y"), -1, + "Frame with same-origin loaded should not be in our own prop list"); + is(names2.indexOf("y"), -1, + "Frame with same-origin loaded should not be in our enumeration list"); + isnot(names3.indexOf("y"), -1, + "Frame with same-origin loaded should be in GSP own prop list"); + is(names1.indexOf("z"), -1, + "Frame with cross-origin loaded should not be in our own prop list"); + is(names2.indexOf("z"), -1, + "Frame with cross-origin loaded should not be in our enumeration list"); + isnot(names3.indexOf("z"), -1, + "Frame with cross-origin loaded should be in GSP own prop list"); + is(names1.indexOf("sameorigin"), -1, + "Frame with same-origin changed name should not be in our own prop list"); + is(names2.indexOf("sameorigin"), -1, + "Frame with same-origin changed name should not be in our enumeration list"); + isnot(names3.indexOf("sameorigin"), -1, + "Frame with same-origin changed name should be in GSP own prop list"); + is(names1.indexOf("crossorigin"), -1, + "Frame with cross-origin changed name should not be in our own prop list"); + is(names2.indexOf("crossorigin"), -1, + "Frame with cross-origin changed name should not be in our enumeration list"); + is(names3.indexOf("crossorigin"), -1, + "Frame with cross-origin changed name should not be in GSP own prop list"); + + is(Object.getOwnPropertyDescriptor(gsp, ""), undefined, + "Should not have empty string as a named frame"); + isnot(Object.getOwnPropertyDescriptor(gsp, "x"), undefined, + "Should have about:blank subframe as a named frame"); + isnot(Object.getOwnPropertyDescriptor(gsp, "y"), undefined, + "Should have same-origin subframe as a named frame"); + isnot(Object.getOwnPropertyDescriptor(gsp, "z"), undefined, + "Should have cross-origin subframe as a named frame"); + isnot(Object.getOwnPropertyDescriptor(gsp, "sameorigin"), undefined, + "Should have same-origin changed name as a named frame"); + is(Object.getOwnPropertyDescriptor(gsp, "crossorigin"), undefined, + "Should not have cross-origin-origin changed name as a named frame"); + SimpleTest.finish(); + }); + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1019417">Mozilla Bug 1019417</a> +<p id="display"></p> +<div id="content" style="display: none"> +<iframe></iframe> +<iframe name=""></iframe> +<iframe name="x"></iframe> +<iframe name="y" + src="http://mochi.test:8888/tests/dom/base/test/file_empty.html"></iframe> +<iframe name="z" + src="http://example.com/tests/dom/base/test/file_empty.html"></iframe> +<iframe name="v" + src="http://mochi.test:8888/tests/dom/base/test/file_setname.html?sameorigin"></iframe> +<iframe name="w" + src="http://example.com/tests/dom/base/test/file_setname.html?crossorigin"></iframe> +</div> +<pre id="test"> +</pre> +</body> +</html> diff --git a/dom/base/test/test_window_orientation.html b/dom/base/test/test_window_orientation.html new file mode 100644 index 0000000000..4921a95cd3 --- /dev/null +++ b/dom/base/test/test_window_orientation.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Test for window.orientation</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="orientationcommon.js"></script> +<div id="log"></div> +<script> +async_test(function(t) { + var originalOrientation = screen.orientation.type; + var alternateOrientation = originalOrientation == "portrait-primary" ? + "landscape-primary" : "portrait-primary"; + + var originalWindowOrientation = window.orientation; + window.onorientationchange = function() { + t.step(function() { assert_not_equals(window.orientation, originalWindowOrientation); }); + + var p2 = specialPowersUnlock(); + p2.then(function() { + t.done(); + }).catch(t.step_func(function(err) { + assert_unreached("Error unlocking orientation: " + err); + t.done(); + })); + } + + var p1 = specialPowersLock(alternateOrientation); + p1.catch(t.step_func(function(err) { + assert_unreached("Error locking orientation: " + err); + t.done(); + })); +}, "Test window.orientation and orientationchange."); +</script> diff --git a/dom/base/test/test_window_proto.html b/dom/base/test/test_window_proto.html new file mode 100644 index 0000000000..944f953bc4 --- /dev/null +++ b/dom/base/test/test_window_proto.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Test for ...</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> +test(function() { + assert_throws(new TypeError, function() { + Object.setPrototypeOf(window, Object.create(window)); + }, "Setting prototype via setPrototypeOf"); + + assert_throws(new TypeError, function() { + window.__proto__ = Object.create(window); + }, "Setting prototype via __proto__"); +}, "Setting the prototype of a window to something that has the window on its proto chain should throw"); +</script> diff --git a/dom/base/test/test_writable-replaceable.html b/dom/base/test/test_writable-replaceable.html new file mode 100644 index 0000000000..20aad7aef8 --- /dev/null +++ b/dom/base/test/test_writable-replaceable.html @@ -0,0 +1,49 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <title>Test for Bug 823283</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=823283">Mozilla Bug 823283</a> +<p id="display"></p> +<div id="content" style="display: none"></div> +<pre id="test"> +<script type="application/javascript"> +/** Test for Bug 823283 **/ + +function createTest(prop, typeStr, valCode, replaceable) +{ + var newType = replaceable ? typeof(valCode) : typeStr; + var code = + 'is(typeof ' + prop + ', "' + typeStr + '", "' + prop + ': bad unqualified before-state");\n' + + 'is(typeof window.' + prop + ', "' + typeStr + '", "' + prop + ': bad qualified before-state");\n' + + '\n' + + prop + ' = ' + valCode + ';\n' + + '\n' + + 'is(typeof ' + prop + ', "' + newType + '", "' + prop + ': bad unqualified after-state");\n' + + 'is(typeof window.' + prop + ', "' + newType + '", "' + prop + ': bad qualified after-state");'; + + return Function(code); +} + +[ + ["innerHeight", "number", '"123"', true], + ["innerWidth", "number", '"456"', true], + ["outerHeight", "number", '"654"', true], + ["outerWidth", "number", '"321"', true], + ["screenX", "number", '"17"', true], + ["screenY", "number", '"42"', true], + ["status", "string", '{}', false], + ["name", "string", '{}', false], +].forEach(function(args) +{ + createTest.apply(null, args)(); +}); + +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_x-frame-options.html b/dom/base/test/test_x-frame-options.html new file mode 100644 index 0000000000..8e24d8a78e --- /dev/null +++ b/dom/base/test/test_x-frame-options.html @@ -0,0 +1,156 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Test for X-Frame-Options response header</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> + +<iframe style="width:100%;height:300px;" id="harness"></iframe> +<script class="testbody" type="text/javascript"> + +var path = "/tests/dom/base/test/"; + +var testFramesLoaded = function() { + var harness = SpecialPowers.wrap(document).getElementById("harness"); + + // iframe from same origin, no X-F-O header - should load + var frame = harness.contentDocument.getElementById("control1"); + var test1 = frame.contentDocument.getElementById("test").textContent; + is(test1, "control1", "test control1"); + + // iframe from different origin, no X-F-O header - should load + frame = harness.contentDocument.getElementById("control2"); + var test2 = frame.contentDocument.getElementById("test").textContent; + is(test2, "control2", "test control2"); + + // iframe from same origin, X-F-O: DENY - should not load + frame = harness.contentDocument.getElementById("deny"); + var test3 = frame.contentDocument.getElementById("test"); + is(test3, null, "test deny"); + + // iframe from same origin, X-F-O: SAMEORIGIN - should load + frame = harness.contentDocument.getElementById("sameorigin1"); + var test4 = frame.contentDocument.getElementById("test").textContent; + is(test4, "sameorigin1", "test sameorigin1"); + + // iframe from different origin, X-F-O: SAMEORIGIN - should not load + frame = harness.contentDocument.getElementById("sameorigin2"); + var test5 = frame.contentDocument.getElementById("test"); + is(test5, null, "test sameorigin2"); + + // iframe from different origin, X-F-O: SAMEORIGIN, SAMEORIGIN - should not load + frame = harness.contentDocument.getElementById("sameorigin5"); + var test6 = frame.contentDocument.getElementById("test"); + is(test6, null, "test sameorigin5"); + + // iframe from same origin, X-F-O: SAMEORIGIN, SAMEORIGIN - should load + frame = harness.contentDocument.getElementById("sameorigin6"); + var test7 = frame.contentDocument.getElementById("test").textContent; + is(test7, "sameorigin6", "test sameorigin6"); + + // iframe from same origin, X-F-O: SAMEORIGIN,SAMEORIGIN, SAMEORIGIN - should load + frame = harness.contentDocument.getElementById("sameorigin7"); + var test8 = frame.contentDocument.getElementById("test").textContent; + is(test8, "sameorigin7", "test sameorigin7"); + + // iframe from same origin, X-F-O: SAMEORIGIN,SAMEORIGIN, SAMEORIGIN - should not load + frame = harness.contentDocument.getElementById("sameorigin8"); + var test9 = frame.contentDocument.getElementById("test"); + is(test9, null, "test sameorigin8"); + + // iframe from same origin, X-F-O: DENY,SAMEORIGIN - should not load + frame = harness.contentDocument.getElementById("mixedpolicy"); + var test10 = frame.contentDocument.getElementById("test"); + is(test10, null, "test mixedpolicy"); + + // iframe from different origin, allow-from: this origin - should load + frame = harness.contentDocument.getElementById("allow-from-allow"); + var test11 = frame.contentDocument.getElementById("test").textContent; + is(test11, "allow-from-allow", "test allow-from-allow"); + + // iframe from different origin, with allow-from: other - should not load + frame = harness.contentDocument.getElementById("allow-from-deny"); + var test12 = frame.contentDocument.getElementById("test"); + is(test12, null, "test allow-from-deny"); + + // iframe from different origin, X-F-O: SAMEORIGIN, multipart - should not load + frame = harness.contentDocument.getElementById("sameorigin-multipart"); + var test13 = frame.contentDocument.getElementById("test"); + is(test13, null, "test sameorigin-multipart"); + + // iframe from same origin, X-F-O: SAMEORIGIN, multipart - should load + frame = harness.contentDocument.getElementById("sameorigin-multipart2"); + var test14 = frame.contentDocument.getElementById("test").textContent; + is(test14, "sameorigin-multipart2", "test sameorigin-multipart2"); + + + // frames from bug 836132 tests + { + frame = harness.contentDocument.getElementById("allow-from-allow-1"); + var theTestResult = frame.contentDocument.getElementById("test"); + isnot(theTestResult, null, "test afa1 should have been allowed"); + if(theTestResult) { + is(theTestResult.textContent, "allow-from-allow-1", "test allow-from-allow-1"); + } + } + for (var i = 1; i<=14; i++) { + frame = harness.contentDocument.getElementById("allow-from-deny-" + i); + var theTestResult = frame.contentDocument.getElementById("test"); + is(theTestResult, null, "test allow-from-deny-" + i); + } + + // call tests to check principal comparison, e.g. a document can open a window + // to a data: or javascript: document which frames an + // X-Frame-Options: SAMEORIGIN document and the frame should load + testFrameInJSURI(); +} + +// test that a document can be framed under a javascript: URL opened by the +// same site as the frame +var testFrameInJSURI = function() { + var html = '<iframe id="sameorigin3" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin3&xfo=sameorigin"></iframe>'; + var win = window.open(); + win.onload = function() { + var test = win.document.getElementById("sameorigin3") + .contentDocument.getElementById("test"); + ok(test != null, "frame under javascript: URL should have loaded."); + win.close(); + + // run last test + testFrameInDataURI(); + } + win.location.href = "javascript:document.write('"+html+"');document.close();"; +} + +// test that a document can be framed under a data: URL opened by the +// same site as the frame +var testFrameInDataURI = function() { + var html = '<iframe id="sameorigin4" src="http://mochi.test:8888/tests/dom/base/test/file_x-frame-options_page.sjs?testid=sameorigin4&xfo=sameorigin"></iframe>'; + var win = window.open(); + win.onload = function() { + var test = win.document.getElementById("sameorigin4") + .contentDocument.getElementById("test"); + ok(test != null, "frame under data: URL should have loaded."); + win.close(); + + SimpleTest.finish(); + } + win.location.href = "data:text/html,"+html; +} + +SimpleTest.waitForExplicitFinish(); + +// load the test harness +document.getElementById("harness").src = "file_x-frame-options_main.html"; + +</script> +</pre> + +</body> +</html> diff --git a/dom/base/test/test_xbl_userdata.xhtml b/dom/base/test/test_xbl_userdata.xhtml new file mode 100644 index 0000000000..8522988537 --- /dev/null +++ b/dom/base/test/test_xbl_userdata.xhtml @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>Test for getUserData/setUserData support in XBL</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +<style type="text/css"> +#t { +-moz-binding: url(#xbl); +} +</style> + +<bindings xmlns="http://www.mozilla.org/xbl"> +<binding id="xbl" inheritstyle="false"> +<implementation><constructor><![CDATA[ + this.textContent = !!(this.getUserData && this.setUserData); +]]></constructor></implementation> +</binding> +</bindings> + +</head> +<body> +<p id="display"></p> + +<pre id="test"> +<script class="testbody"> +<![CDATA[ +"use strict"; + +var url = 'data:text/html;charset=utf-8,' + + encodeURIComponent('<div id=t style="-moz-binding:url(' + location + '#xbl)"></div>'); + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(test1); + +function test1() { + var iframe = document.createElement('iframe'); + iframe.src = url; + iframe.onload = function() { + var t = iframe.contentWindow.t; + is(!!(t.getUserData || t.setUserData), false, + "getUserData and setUserData should not be visible from the regular content"); + is(t.textContent, "true", + "getUserData and setUserData should be visible from XBL"); + document.body.removeChild(iframe); + SimpleTest.finish(); + }; + document.body.appendChild(iframe); +} + +]]> +</script> +</pre> +</body> +</html> diff --git a/dom/base/test/test_youtube_flash_embed.html b/dom/base/test/test_youtube_flash_embed.html new file mode 100644 index 0000000000..9b7f25d0fe --- /dev/null +++ b/dom/base/test/test_youtube_flash_embed.html @@ -0,0 +1,36 @@ +<!DOCTYPE HTML> +<html> + <!-- + https://bugzilla.mozilla.org/show_bug.cgi?id=1240471 + --> + <head> + <meta charset="utf-8"> + <title>Test for Bug 1240471</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript"> + SimpleTest.waitForExplicitFinish(); + let path = location.pathname.substring(0, location.pathname.lastIndexOf('/')) + '/file_youtube_flash_embed.html'; + onmessage = function(e) { + let msg = JSON.parse(e.data); + if (msg.fn == "finish") { + SimpleTest.finish(); + return; + } + self[msg.fn].apply(null, msg.args); + } + function onLoad() { + SpecialPowers.pushPrefEnv({ + "set": [["full-screen-api.unprefix.enabled", true]] + }, function() { + // The test file must be loaded into youtube.com domain + // because it needs unprivileged access to fullscreenEnabled. + ifr.src = "https://mochitest.youtube.com" + path; + }); + } + </script> + </head> + <body onload="onLoad()"> + <iframe id="ifr" allowfullscreen></iframe> + </body> +</html> diff --git a/dom/base/test/unit/1_original.xml b/dom/base/test/unit/1_original.xml new file mode 100644 index 0000000000..4b7915159d --- /dev/null +++ b/dom/base/test/unit/1_original.xml @@ -0,0 +1,3 @@ +<?xml version="1.0"?> + +<foo /> <!-- é -->
\ No newline at end of file diff --git a/dom/base/test/unit/1_result.xml b/dom/base/test/unit/1_result.xml new file mode 100644 index 0000000000..61d4458be9 --- /dev/null +++ b/dom/base/test/unit/1_result.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="UTF-8"?> +<foo/> +<!-- é -->
\ No newline at end of file diff --git a/dom/base/test/unit/2_original.xml b/dom/base/test/unit/2_original.xml new file mode 100644 index 0000000000..a6b9e340ba --- /dev/null +++ b/dom/base/test/unit/2_original.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC + "-//MOZ//WHATEVER//EN" + "http://mozilla.org/ns/foo"> +<foo xmlns="htp://mozilla.org/ns"> + <baz /><!-- a comment --> <bar> <robots> & <aliens> +<mozilla> a a a a a éèàùûî</mozilla> + <firefox>Lorem ip<!-- aaa -->sum dolor sit amet, consectetuer adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nam tellus massa, fringilla aliquam, fermentum sit amet, posuere ac, est. Duis tristique egestas ligula. Mauris quis felis. Fusce a ipsum non lacus posuere aliquet. Sed fermentum posuere nulla. Donec tempor. Donec sollicitudin tortor lacinia libero ullamcorper laoreet. Cras quis nisi at odio consectetuer molestie.</firefox> + <?xml-foo "hey" ?> +</bar> + <!-- a comment + on several lines--> + <?xml-foo "another pi on two lines" + example="hello"?> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/2_result_1.xml b/dom/base/test/unit/2_result_1.xml new file mode 100644 index 0000000000..16eeb817ff --- /dev/null +++ b/dom/base/test/unit/2_result_1.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="htp://mozilla.org/ns"> + <baz/><!-- a comment --> <bar> <robots> & <aliens> +<mozilla> a a a a a éèàùûî</mozilla> + <firefox>Lorem ip<!-- aaa -->sum dolor sit amet, consectetuer adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nam tellus massa, fringilla aliquam, fermentum sit amet, posuere ac, est. Duis tristique egestas ligula. Mauris quis felis. Fusce a ipsum non lacus posuere aliquet. Sed fermentum posuere nulla. Donec tempor. Donec sollicitudin tortor lacinia libero ullamcorper laoreet. Cras quis nisi at odio consectetuer molestie.</firefox> + <?xml-foo "hey" ?> +</bar> + <!-- a comment + on several lines--> + <?xml-foo "another pi on two lines" + example="hello"?> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/2_result_2.xml b/dom/base/test/unit/2_result_2.xml new file mode 100644 index 0000000000..c3eeadb58f --- /dev/null +++ b/dom/base/test/unit/2_result_2.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="htp://mozilla.org/ns"> + <baz/><!-- a comment --> + <bar> <robots> & <aliens> + <mozilla> a a a a a éèàùûî</mozilla> + <firefox>Lorem ip<!-- aaa -->sum dolor sit amet, consectetuer adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nam tellus massa, fringilla aliquam, fermentum sit amet, posuere ac, est. Duis tristique egestas ligula. Mauris quis felis. Fusce a ipsum non lacus posuere aliquet. Sed fermentum posuere nulla. Donec tempor. Donec sollicitudin tortor lacinia libero ullamcorper laoreet. Cras quis nisi at odio consectetuer molestie.</firefox> + <?xml-foo "hey" ?> + </bar> + <!-- a comment + on several lines--> + <?xml-foo "another pi on two lines" + example="hello"?> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/2_result_3.xml b/dom/base/test/unit/2_result_3.xml new file mode 100644 index 0000000000..906ac89ee5 --- /dev/null +++ b/dom/base/test/unit/2_result_3.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="htp://mozilla.org/ns"> + <baz/><!-- a comment --> + <bar> <robots> & <aliens> + <mozilla> a a a a a éèàùûî</mozilla> + <firefox>Lorem ip<!-- aaa -->sum dolor sit amet, consectetuer + adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis + ipsum. Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent + taciti sociosqu ad litora torquent per conubia nostra, per + inceptos hymenaeos. Nam tellus massa, fringilla aliquam, fermentum + sit amet, posuere ac, est. Duis tristique egestas ligula. Mauris + quis felis. Fusce a ipsum non lacus posuere aliquet. Sed fermentum + posuere nulla. Donec tempor. Donec sollicitudin tortor lacinia + libero ullamcorper laoreet. Cras quis nisi at odio consectetuer + molestie.</firefox> + <?xml-foo "hey" ?> + </bar> + <!-- a comment + on several lines--> + <?xml-foo "another pi on two lines" + example="hello"?> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/2_result_4.xml b/dom/base/test/unit/2_result_4.xml new file mode 100644 index 0000000000..27ed219211 --- /dev/null +++ b/dom/base/test/unit/2_result_4.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="htp://mozilla.org/ns"> + <baz/><!-- a comment --> <bar> <robots> & <aliens> +<mozilla> a a a a a éèàùûî</mozilla> + <firefox>Lorem ip<!-- aaa -->sum dolor sit amet, consectetuer +adipiscing elit. Nam eu sapien. Sed viverra lacus. Donec quis ipsum. +Nunc cursus aliquet lectus. Nunc vitae eros. Class aptent taciti +sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. +Nam tellus massa, fringilla aliquam, fermentum sit amet, posuere ac, +est. Duis tristique egestas ligula. Mauris quis felis. Fusce a ipsum non + lacus posuere aliquet. Sed fermentum posuere nulla. Donec tempor. Donec + sollicitudin tortor lacinia libero ullamcorper laoreet. Cras quis nisi +at odio consectetuer molestie.</firefox> + <?xml-foo "hey" ?> +</bar> + <!-- a comment + on several lines--> + <?xml-foo "another pi on two lines" + example="hello"?> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/3_original.xml b/dom/base/test/unit/3_original.xml new file mode 100644 index 0000000000..eb9c1bd656 --- /dev/null +++ b/dom/base/test/unit/3_original.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<foo> +Lorem ip<!-- aaa -->sum dolorsitamet, consectetuer adipiscing elit. Nameusapien. Sed viverralacus. this_is_a_very_long_long_word_which_has_a_length_higher_than_the_max_column Donecquisipsum. Nunc cursus aliquet lectus. Nunc vitae eros. +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/3_result.xml b/dom/base/test/unit/3_result.xml new file mode 100644 index 0000000000..e556c61e58 --- /dev/null +++ b/dom/base/test/unit/3_result.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<foo> + Lorem ip<!-- aaa -->sum dolorsitamet, consectetuer adipiscing elit. + Nameusapien. Sed viverralacus. + this_is_a_very_long_long_word_which_has_a_length_higher_than_the_max_column + Donecquisipsum. Nunc cursus aliquet lectus. Nunc vitae eros. +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/3_result_2.xml b/dom/base/test/unit/3_result_2.xml new file mode 100644 index 0000000000..2df257ca75 --- /dev/null +++ b/dom/base/test/unit/3_result_2.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<foo> +Lorem ip<!-- aaa -->sum dolorsitamet, consectetuer adipiscing elit. +Nameusapien. Sed viverralacus. +this_is_a_very_long_long_word_which_has_a_length_higher_than_the_max_column + Donecquisipsum. Nunc cursus aliquet lectus. Nunc vitae eros. +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/4_original.xml b/dom/base/test/unit/4_original.xml new file mode 100644 index 0000000000..4c9c61b5dd --- /dev/null +++ b/dom/base/test/unit/4_original.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="http://mozilla.org/ns" xmlns:falsexul="http://mozilla.org/ns3"> + <!-- document to test namespaces--> + <baz /> + <bar> <robots> & <aliens> + <mozilla xmlns="http://mozilla.org/ns2"> a a a <moz>a a</moz> éèàùûî</mozilla> + <firefox>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</firefox> + </bar> + + <xul xmlns="http://mozilla.org/ns3" xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description other:yes="no">xul fake</description> + </box> + </xul> + + <falsexul:xul xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description>xul fake</description> + <what xmlns="http://mozilla.org/ns/other">lorem ipsum <falsexul:label value="hello" /> the return</what> + </box> + </falsexul:xul> + + <ho:xul xmlns="http://mozilla.org/ns4" xmlns:ho="http://mozilla.org/ns4" xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description ho:foo="bar" bla="hello" other:yes="no" ho:foo2="bar2">xul fake</description> + </box> + </ho:xul> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/4_result_1.xml b/dom/base/test/unit/4_result_1.xml new file mode 100644 index 0000000000..b985da960e --- /dev/null +++ b/dom/base/test/unit/4_result_1.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="http://mozilla.org/ns" xmlns:falsexul="http://mozilla.org/ns3"> + <!-- document to test namespaces--> + <baz/> + <bar> <robots> & <aliens> + <mozilla xmlns="http://mozilla.org/ns2"> a a a <moz>a a</moz> éèàùûî</mozilla> + <firefox>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</firefox> + </bar> + + <xul xmlns="http://mozilla.org/ns3" xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description other:yes="no">xul fake</description> + </box> + </xul> + + <falsexul:xul xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description>xul fake</description> + <what xmlns="http://mozilla.org/ns/other">lorem ipsum <falsexul:label value="hello"/> the return</what> + </box> + </falsexul:xul> + + <ho:xul xmlns="http://mozilla.org/ns4" xmlns:ho="http://mozilla.org/ns4" xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description ho:foo="bar" bla="hello" other:yes="no" ho:foo2="bar2">xul fake</description> + </box> + </ho:xul> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/4_result_2.xml b/dom/base/test/unit/4_result_2.xml new file mode 100644 index 0000000000..bc408b431c --- /dev/null +++ b/dom/base/test/unit/4_result_2.xml @@ -0,0 +1,7 @@ +<falsexul:xul xmlns:falsexul="http://mozilla.org/ns3" xmlns:other="http://mozilla.org/ns/other"> + <box xmlns="http://mozilla.org/ns"> + <other:what>lorem ipsum</other:what> + <description>xul fake</description> + <what xmlns="http://mozilla.org/ns/other">lorem ipsum <falsexul:label value="hello"/> the return</what> + </box> + </falsexul:xul>
\ No newline at end of file diff --git a/dom/base/test/unit/4_result_3.xml b/dom/base/test/unit/4_result_3.xml new file mode 100644 index 0000000000..30c8b47de7 --- /dev/null +++ b/dom/base/test/unit/4_result_3.xml @@ -0,0 +1,4 @@ +<box xmlns="http://mozilla.org/ns3"> + <other:what xmlns:other="http://mozilla.org/ns/other">lorem ipsum</other:what> + <description other:yes="no" xmlns:other="http://mozilla.org/ns/other">xul fake</description> + </box>
\ No newline at end of file diff --git a/dom/base/test/unit/4_result_4.xml b/dom/base/test/unit/4_result_4.xml new file mode 100644 index 0000000000..9346d5d170 --- /dev/null +++ b/dom/base/test/unit/4_result_4.xml @@ -0,0 +1,4 @@ +<box xmlns="http://mozilla.org/ns4"> + <other:what xmlns:other="http://mozilla.org/ns/other">lorem ipsum</other:what> + <description ho:foo="bar" xmlns:ho="http://mozilla.org/ns4" bla="hello" other:yes="no" xmlns:other="http://mozilla.org/ns/other" ho:foo2="bar2">xul fake</description> + </box>
\ No newline at end of file diff --git a/dom/base/test/unit/4_result_5.xml b/dom/base/test/unit/4_result_5.xml new file mode 100644 index 0000000000..936dd950bd --- /dev/null +++ b/dom/base/test/unit/4_result_5.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="http://mozilla.org/ns" + xmlns:falsexul="http://mozilla.org/ns3"> + <!-- document to test namespaces--> + <baz/> + <bar> <robots> & + <aliens> + <mozilla + xmlns="http://mozilla.org/ns2"> a + a a + <moz>a a</moz> éèàùûî</mozilla> + <firefox>Lorem ipsum dolor sit amet, + consectetuer adipiscing elit.</firefox> + </bar> + <xul xmlns="http://mozilla.org/ns3" +xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description other:yes="no">xul + fake</description> + </box> + </xul> + <falsexul:xul +xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description>xul fake</description> + <what + xmlns="http://mozilla.org/ns/other">lorem + ipsum + <falsexul:label value="hello"/> + the return</what> + </box> + </falsexul:xul> + <ho:xul xmlns="http://mozilla.org/ns4" + xmlns:ho="http://mozilla.org/ns4" +xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description ho:foo="bar" + bla="hello" other:yes="no" + ho:foo2="bar2">xul fake</description> + </box> + </ho:xul> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/4_result_6.xml b/dom/base/test/unit/4_result_6.xml new file mode 100644 index 0000000000..e9917cfdc7 --- /dev/null +++ b/dom/base/test/unit/4_result_6.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE whatever PUBLIC "-//MOZ//WHATEVER//EN" "http://mozilla.org/ns/foo"> +<foo xmlns="http://mozilla.org/ns" +xmlns:falsexul="http://mozilla.org/ns3"> + <!-- document to test namespaces--> + <baz/> + <bar> <robots> & +<aliens> + <mozilla +xmlns="http://mozilla.org/ns2"> a a a <moz>a + a</moz> éèàùûî</mozilla> + <firefox>Lorem ipsum dolor sit +amet, consectetuer adipiscing elit.</firefox> + </bar> + + <xul xmlns="http://mozilla.org/ns3" +xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description other:yes="no">xul +fake</description> + </box> + </xul> + + <falsexul:xul +xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description>xul fake</description> + <what +xmlns="http://mozilla.org/ns/other">lorem + ipsum <falsexul:label value="hello"/> +the return</what> + </box> + </falsexul:xul> + + <ho:xul +xmlns="http://mozilla.org/ns4" +xmlns:ho="http://mozilla.org/ns4" +xmlns:other="http://mozilla.org/ns/other"> + <box> + <other:what>lorem ipsum</other:what> + <description ho:foo="bar" +bla="hello" other:yes="no" +ho:foo2="bar2">xul fake</description> + </box> + </ho:xul> +</foo>
\ No newline at end of file diff --git a/dom/base/test/unit/empty_document.xml b/dom/base/test/unit/empty_document.xml new file mode 100644 index 0000000000..ebd60b08c7 --- /dev/null +++ b/dom/base/test/unit/empty_document.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" ?> +<!-- empty document for use in tests that don't need any particular DOM --> +<root/> diff --git a/dom/base/test/unit/head_utilities.js b/dom/base/test/unit/head_utilities.js new file mode 100644 index 0000000000..d3b68520da --- /dev/null +++ b/dom/base/test/unit/head_utilities.js @@ -0,0 +1,40 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Components.utils.import("resource://testing-common/httpd.js"); +Components.utils.import("resource://gre/modules/NetUtil.jsm"); + +const nsIDocumentEncoder = Components.interfaces.nsIDocumentEncoder; +const replacementChar = Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER; + +function loadContentFile(aFile, aCharset) { + //if(aAsIso == undefined) aAsIso = false; + if(aCharset == undefined) + aCharset = 'UTF-8'; + + var file = do_get_file(aFile); + var ios = Components.classes['@mozilla.org/network/io-service;1'] + .getService(Components.interfaces.nsIIOService); + var chann = NetUtil.newChannel({ + uri: ios.newFileURI(file), + loadUsingSystemPrincipal: true + }); + chann.contentCharset = aCharset; + + /*var inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"] + .createInstance(Components.interfaces.nsIScriptableInputStream); + inputStream.init(chann.open2()); + return inputStream.read(file.fileSize); + */ + + var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"] + .createInstance(Components.interfaces.nsIConverterInputStream); + inputStream.init(chann.open2(), aCharset, 1024, replacementChar); + var str = {}, content = ''; + while (inputStream.readString(4096, str) != 0) { + content += str.value; + } + return content; +} diff --git a/dom/base/test/unit/head_xml.js b/dom/base/test/unit/head_xml.js new file mode 100644 index 0000000000..3d445b7484 --- /dev/null +++ b/dom/base/test/unit/head_xml.js @@ -0,0 +1,156 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const I = Components.interfaces; +const C = Components.classes; + +const nsILocalFile = I.nsILocalFile; +const nsIProperties = I.nsIProperties; +const nsIFileInputStream = I.nsIFileInputStream; +const nsIInputStream = I.nsIInputStream; + +const nsIDOMParser = I.nsIDOMParser; +const nsIDOMSerializer = I.nsIDOMSerializer; +const nsIDOMDocument = I.nsIDOMDocument; +const nsIDOMElement = I.nsIDOMElement; +const nsIDOMNode = I.nsIDOMNode; +const nsIDOMCharacterData = I.nsIDOMCharacterData; +const nsIDOMAttr = I.nsIDOMAttr; +const nsIDOMNodeList = I.nsIDOMNodeList; +const nsIDOMXULElement = I.nsIDOMXULElement; +const nsIDOMProcessingInstruction = I.nsIDOMProcessingInstruction; + +function DOMParser() { + var parser = C["@mozilla.org/xmlextras/domparser;1"].createInstance(nsIDOMParser); + parser.init(); + return parser; +} + +var __testsDirectory = null; + +function ParseFile(file) { + if (typeof(file) == "string") { + if (!__testsDirectory) { + __testsDirectory = do_get_cwd(); + } + var fileObj = __testsDirectory.clone(); + fileObj.append(file); + file = fileObj; + } + + do_check_eq(file instanceof nsILocalFile, true); + + var fileStr = C["@mozilla.org/network/file-input-stream;1"] + .createInstance(nsIFileInputStream); + // Init for readonly reading + fileStr.init(file, 0x01, 0o400, nsIFileInputStream.CLOSE_ON_EOF); + return ParseXML(fileStr); +} + +function ParseXML(data) { + if (typeof(data) == "string") { + return DOMParser().parseFromString(data, "application/xml"); + } + + do_check_eq(data instanceof nsIInputStream, true); + + return DOMParser().parseFromStream(data, "UTF-8", data.available(), + "application/xml"); +} + +function DOMSerializer() { + return C["@mozilla.org/xmlextras/xmlserializer;1"] + .createInstance(nsIDOMSerializer); +} + +function SerializeXML(node) { + return DOMSerializer().serializeToString(node); +} + +function roundtrip(obj) { + if (typeof(obj) == "string") { + return SerializeXML(ParseXML(obj)); + } + + do_check_eq(obj instanceof nsIDOMNode, true); + return ParseXML(SerializeXML(obj)); +} + +function do_compare_attrs(e1, e2) { + const xmlns = "http://www.w3.org/2000/xmlns/"; + + var a1 = e1.attributes; + var a2 = e2.attributes; + for (var i = 0; i < a1.length; ++i) { + var att = a1.item(i); + // Don't test for namespace decls, since those can just sorta be + // scattered about + if (att.namespaceURI != xmlns) { + var att2 = a2.getNamedItemNS(att.namespaceURI, att.localName); + if (!att2) { + do_throw("Missing attribute with namespaceURI '" + att.namespaceURI + + "' and localName '" + att.localName + "'"); + } + do_check_eq(att.QueryInterface(nsIDOMAttr).value, + att2.QueryInterface(nsIDOMAttr).value); + } + } +} + +function do_check_equiv(dom1, dom2) { + do_check_eq(dom1.nodeType, dom2.nodeType); + // There's no classinfo around, so we'll need to do some QIing to + // make sure the right interfaces are flattened as needed. + switch (dom1.nodeType) { + case nsIDOMNode.PROCESSING_INSTRUCTION_NODE: + do_check_eq(dom1.QueryInterface(nsIDOMProcessingInstruction).target, + dom2.QueryInterface(nsIDOMProcessingInstruction).target); + do_check_eq(dom1.data, dom2.data); + case nsIDOMNode.TEXT_NODE: + case nsIDOMNode.CDATA_SECTION_NODE: + case nsIDOMNode.COMMENT_NODE: + do_check_eq(dom1.QueryInterface(nsIDOMCharacterData).data, + dom2.QueryInterface(nsIDOMCharacterData).data); + break; + case nsIDOMNode.ELEMENT_NODE: + do_check_eq(dom1.namespaceURI, dom2.namespaceURI); + do_check_eq(dom1.localName, dom2.localName); + // Compare attrs in both directions -- do_compare_attrs does a + // subset check. + do_compare_attrs(dom1, dom2); + do_compare_attrs(dom2, dom1); + // Fall through + case nsIDOMNode.DOCUMENT_NODE: + do_check_eq(dom1.childNodes.length, dom2.childNodes.length); + for (var i = 0; i < dom1.childNodes.length; ++i) { + do_check_equiv(dom1.childNodes.item(i), dom2.childNodes.item(i)); + } + break; + } +} + +function do_check_serialize(dom) { + do_check_equiv(dom, roundtrip(dom)); +} + +function Pipe() { + var p = C["@mozilla.org/pipe;1"].createInstance(I.nsIPipe); + p.init(false, false, 0, 0xffffffff, null); + return p; +} + +function ScriptableInput(arg) { + if (arg instanceof I.nsIPipe) { + arg = arg.inputStream; + } + + var str = C["@mozilla.org/scriptableinputstream;1"]. + createInstance(I.nsIScriptableInputStream); + + str.init(arg); + + return str; +} diff --git a/dom/base/test/unit/isequalnode_data.xml b/dom/base/test/unit/isequalnode_data.xml new file mode 100644 index 0000000000..4b72f5d502 --- /dev/null +++ b/dom/base/test/unit/isequalnode_data.xml @@ -0,0 +1,150 @@ +<?xml version="1.0" ?> +<!DOCTYPE Test [ + <!ATTLIST test id ID #REQUIRED> +]> + +<root> + + <test id="test_setAttribute"> + <foo/> + <foo/> + </test> + + <test id="test_normalization"> + <bar/> + <bar/> + </test> + + <test id="test_whitespace"> + + <!-- + Tests here consist of isEqualNode comparisons of the first and third + (zero-indexed) child nodes of each test. + + In the typical case this means that the zeroth, second, and fourth + children are whitespace and the first and third are the nodes being + compared for equality or inequality. + + In some cases, however, where either node is a Text node, this pattern + must of necessity be violated. Examples of such tests include the + test_text# tests. + + As a result of this, BE CAREFUL NOT TO INTRODUCE STRAY WHITESPACE WHEN + EDITING THIS FILE. You have been warned. + --> + + <test id="test_pi1"> + <?pi data?> + <?pi data?> + </test> + <test id="test_pi2"> + <?pi data?> + <?pi data?> + </test> + <test id="test_pi3"> + <?pi data?> + <?pi data ?> + </test> + <test id="test_pi4"> + <?pi ?> + <?pi ?> + </test> + <test id="test_pi5"> + <?pi?> + <?pi ?> + </test> + + <test id="test_elt1"> + <foo></foo> + <foo> </foo> + </test> + <test id="test_elt2"> + <foo></foo> + <foo> +</foo> + </test> + <test id="test_elt3"> + <foo ></foo> + <foo></foo> + </test> + <test id="test_elt4"> + <bar xmlns="http://example.com/"/> + <bar/> + </test> + <test id="test_elt5"> + <bar xmlns="http://example.com/"/> + <bar xmlns="http://example.com"/> + </test> + + <test id="test_comment1"> + <!--foo--> + <!--foo--> + </test> + <test id="test_comment2"> + <!--foo--> + <!--foo --> + </test> + <test id="test_comment3"> + <!--foo--> + <!--foo +--> + </test> + <test id="test_comment4"> + <!-- +foo--> + <!-- +foo--> + </test> + + <test id="test_text1"><placeholder-dont-move/> +<placeholder-dont-move/> +<placeholder-dont-move/> + </test> + <test id="test_text2"><placeholder-dont-move/> +<placeholder-dont-move/> <placeholder-dont-move/> + </test> + <test id="test_text3"><placeholder-dont-move/> +<placeholder-dont-move/><![CDATA[ +]]> + </test> + + <test id="test_cdata1"> + <![CDATA[ ]]><placeholder-dont-move/> <placeholder-dont-move/> + </test> + <test id="test_cdata2"> + <![CDATA[ ]]> + <![CDATA[ ]]> + </test> + <test id="test_cdata3"> + <![CDATA[ ]]> + <![CDATA[ ]]> + </test> + <test id="test_cdata4"> + <![CDATA[]]> + <![CDATA[ +]]> + </test> + <test id="test_cdata5"> + <![CDATA[ ]]> + <![CDATA[ +]]> + </test> + + </test> + + <test id="test_namespaces"> + <test id="test_ns1"> + <foo xmlns:quiz="http://example.com/" + quiz:q="fun"/> + <foo xmlns:f="http://example.com/" + f:q="fun"/> + </test> + <test id="test_ns2"> + <quiz:foo xmlns:quiz="http://example.com/" + q="fun"/> + <f:foo xmlns:f="http://example.com/" + q="fun"/> + </test> + </test> + +</root> diff --git a/dom/base/test/unit/nodelist_data_1.xml b/dom/base/test/unit/nodelist_data_1.xml new file mode 100644 index 0000000000..ddde596a27 --- /dev/null +++ b/dom/base/test/unit/nodelist_data_1.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" ?> +<!DOCTYPE Test [ + <!ATTLIST test id ID #REQUIRED> + <!ATTLIST foo:test id ID #REQUIRED> + <!ATTLIST foo2:test id ID #REQUIRED> + <!ATTLIST bar:test id ID #REQUIRED> +]> + +<!-- Comment --> + +<?This-is-a-PI ?> + +<root xmlns:foo="foo" + xmlns:bar="bar" + xmlns:foo2="foo"> + + <test id="test1"> + </test> + + <test id="test2"> + <!-- Another comment --> + <test id="test3"> + </test> + + <test id="test4" xmlns="foo"> + <test id="test5"> + </test> + + <bar:test id="test6" /> + </test> + + <foo:test id="test7"> + </foo:test> + + <foo2:test id="test8"> + <?Another-PI ?> + <baz /> + </foo2:test> + + <bar:test id="test9"> + </bar:test> + </test> + + <foo:test id="test10"> + <foo2:test id="test11"> + <bar:test id="test12"> + </bar:test> + </foo2:test> + </foo:test> + + <foo2:test id="test13"> + </foo2:test> + + <bar:test id="test14"> + </bar:test> + +</root> + diff --git a/dom/base/test/unit/nodelist_data_2.xul b/dom/base/test/unit/nodelist_data_2.xul new file mode 100644 index 0000000000..247ef0353c --- /dev/null +++ b/dom/base/test/unit/nodelist_data_2.xul @@ -0,0 +1,45 @@ +<?xml version="1.0"?> +<!DOCTYPE window [ + <!ENTITY fooSet ' + <addOrRemove foo:foo="foo"/> + <addOrRemove foo:foo="bar"/> + <addOrRemove foo:bar="foo"/> + <addOrRemove foo:bar="bar"/> + <addOrRemove foo:foo="foo" foo:bar="bar"/> + <addOrRemove foo2:foo="foo"/> + <addOrRemove foo="foo"/> + <addOrRemove foo="bar"/> + <addOrRemove bar="bar" foo="foo"/> +'> +]> +<window + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:foo="foo" + xmlns:foo2="foo" + xmlns:bar="bar" + > + <vbox id="boxes"> + <groupbox id="master1" foo:foo="bar"> + &fooSet; + <groupbox foo:foo="foo"> + &fooSet; + </groupbox> + </groupbox> + <groupbox id="master2" foo:foo="foo"> + &fooSet; + <groupbox foo:foo="bar"> + &fooSet; + </groupbox> + </groupbox> + <groupbox id="master3"> + &fooSet; + <groupbox foo2:foo="foo"> + &fooSet; + </groupbox> + </groupbox> + <groupbox id="external"> + &fooSet; + </groupbox> + </vbox> +</window> diff --git a/dom/base/test/unit/test_bloburi.js b/dom/base/test/unit/test_bloburi.js new file mode 100644 index 0000000000..36e2e1eb72 --- /dev/null +++ b/dom/base/test/unit/test_bloburi.js @@ -0,0 +1,33 @@ +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cr = Components.results; + +var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); + +var uris = [ + { + uri: "blob:https://example.com/230d5d50-35f9-9745-a64a-15e47b731a81", + local: true, + }, + { + uri: "rstp://1.2.3.4/some_path?param=a", + local: false, + }, + { + uri: "moz-fonttable://something", + local: true, + } +]; + +function run_test() +{ + for (let i = 0; i < uris.length; i++) { + let uri = ios.newURI(uris[i].uri); + let handler = ios.getProtocolHandler(uri.scheme).QueryInterface(Ci.nsIProtocolHandler); + let flags = handler.protocolFlags; + + do_check_eq(Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE & flags, + (uris[i].local) ? Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE : 0); + } +} + diff --git a/dom/base/test/unit/test_bug553888.js b/dom/base/test/unit/test_bug553888.js new file mode 100644 index 0000000000..036d51211d --- /dev/null +++ b/dom/base/test/unit/test_bug553888.js @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Components.utils.import("resource://testing-common/httpd.js"); + +var server = new HttpServer(); +server.start(-1); + +const SERVER_PORT = server.identity.primaryPort; +const HTTP_BASE = "http://localhost:" + SERVER_PORT; +const redirectPath = "/redirect"; +const headerCheckPath = "/headerCheck"; +const redirectURL = HTTP_BASE + redirectPath; +const headerCheckURL = HTTP_BASE + headerCheckPath; + +function redirectHandler(metadata, response) { + response.setStatusLine(metadata.httpVersion, 302, "Found"); + response.setHeader("Location", headerCheckURL, false); +} + +function headerCheckHandler(metadata, response) { + try { + let headerValue = metadata.getHeader("X-Custom-Header"); + do_check_eq(headerValue, "present"); + } catch(e) { + do_throw("No header present after redirect"); + } + try { + metadata.getHeader("X-Unwanted-Header"); + do_throw("Unwanted header present after redirect"); + } catch (x) { + } + response.setStatusLine(metadata.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "text/plain"); + response.write(""); +} + +function run_test() { + server.registerPathHandler(redirectPath, redirectHandler); + server.registerPathHandler(headerCheckPath, headerCheckHandler); + + do_test_pending(); + var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Components.interfaces.nsIXMLHttpRequest); + request.open("GET", redirectURL, true); + request.setRequestHeader("X-Custom-Header", "present"); + request.addEventListener("readystatechange", function() { + if (request.readyState == 4) { + do_check_eq(request.status, 200); + server.stop(do_test_finished); + } + }, false); + request.send(); + try { + request.setRequestHeader("X-Unwanted-Header", "present"); + do_throw("Shouldn't be able to set a header after send"); + } catch (x) { + } +} diff --git a/dom/base/test/unit/test_bug737966.js b/dom/base/test/unit/test_bug737966.js new file mode 100644 index 0000000000..448f6fa74e --- /dev/null +++ b/dom/base/test/unit/test_bug737966.js @@ -0,0 +1,20 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* If charset parameter is invalid, the encoding should be detected as UTF-8 */ + +function run_test() +{ + let body = '<?xml version="1.0"><html>%c3%80</html>'; + let result = '<?xml version="1.0"><html>\u00c0</html>'; + + let xhr = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1']. + createInstance(Components.interfaces.nsIXMLHttpRequest); + xhr.open('GET', + 'data:text/xml;charset=abc,' + body, + false); + xhr.send(null); + + do_check_eq(xhr.responseText, result); +} diff --git a/dom/base/test/unit/test_cancelPrefetch.js b/dom/base/test/unit/test_cancelPrefetch.js new file mode 100644 index 0000000000..1a10240a90 --- /dev/null +++ b/dom/base/test/unit/test_cancelPrefetch.js @@ -0,0 +1,134 @@ +//Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); +const Cc = Components.classes; +const Ci = Components.interfaces; +var prefetch = Cc["@mozilla.org/prefetch-service;1"]. + getService(Ci.nsIPrefetchService); +var ios = Cc["@mozilla.org/network/io-service;1"]. + getService(Ci.nsIIOService); +var prefs = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + +var parser = Cc["@mozilla.org/xmlextras/domparser;1"]. + createInstance(Ci.nsIDOMParser); + +var doc; + +var docbody = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>' + + '<link id="node1"/><link id="node2"/>' + + '</body></html>'; + +var node1; +var node2; + +function run_test() { + prefs.setBoolPref("network.prefetch-next", true); + + parser.init(); + doc = parser.parseFromString(docbody, "text/html"); + + node1 = doc.getElementById("node1"); + node2 = doc.getElementById("node2"); + + run_next_test(); +} + +add_test(function test_cancel1() { + + var uri = ios.newURI("http://localhost/1", null, null); + prefetch.prefetchURI(uri, uri, node1, true); + + do_check_true(prefetch.hasMoreElements(), 'There is a request in the queue'); + + // Trying to prefetch again the same uri with the same node will fail. + var didFail = 0; + + try { + prefetch.prefetchURI(uri, uri, node1, true); + } catch(e) { + didFail = 1; + } + + do_check_true(didFail == 1, 'Prefetching the same request with the same ' + + 'node fails.'); + + do_check_true(prefetch.hasMoreElements(), 'There is still request in ' + + 'the queue'); + + prefetch.cancelPrefetchURI(uri, node1); + + do_check_false(prefetch.hasMoreElements(), 'There is no request in the ' + + 'queue'); + run_next_test(); +}); + +add_test(function test_cancel2() { + // Prefetch a uri with 2 different nodes. There should be 2 request + // in the queue and canceling one will not cancel the other. + + var uri = ios.newURI("http://localhost/1", null, null); + prefetch.prefetchURI(uri, uri, node1, true); + prefetch.prefetchURI(uri, uri, node2, true); + + do_check_true(prefetch.hasMoreElements(), 'There are requests in the queue'); + + prefetch.cancelPrefetchURI(uri, node1); + + do_check_true(prefetch.hasMoreElements(), 'There is still one more request ' + + 'in the queue'); + + prefetch.cancelPrefetchURI(uri, node2); + + do_check_false(prefetch.hasMoreElements(), 'There is no request in the queue'); + run_next_test(); +}); + +add_test(function test_cancel3() { + // Request a prefetch of a uri. Trying to cancel a prefetch for the same uri + // with a different node will fail. + var uri = ios.newURI("http://localhost/1", null, null); + prefetch.prefetchURI(uri, uri, node1, true); + + do_check_true(prefetch.hasMoreElements(), 'There is a request in the queue'); + + var didFail = 0; + + try { + prefetch.cancelPrefetchURI(uri, node2); + } catch(e) { + didFail = 1; + } + do_check_true(didFail == 1, 'Canceling the request failed'); + + do_check_true(prefetch.hasMoreElements(), 'There is still a request ' + + 'in the queue'); + + prefetch.cancelPrefetchURI(uri, node1); + do_check_false(prefetch.hasMoreElements(), 'There is no request in the queue'); + run_next_test(); +}); + +add_test(function test_cancel4() { + // Request a prefetch of a uri. Trying to cancel a prefetch for a different uri + // with the same node will fail. + var uri1 = ios.newURI("http://localhost/1", null, null); + var uri2 = ios.newURI("http://localhost/2", null, null); + prefetch.prefetchURI(uri1, uri1, node1, true); + + do_check_true(prefetch.hasMoreElements(), 'There is a request in the queue'); + + var didFail = 0; + + try { + prefetch.cancelPrefetchURI(uri2, node1); + } catch(e) { + didFail = 1; + } + do_check_true(didFail == 1, 'Canceling the request failed'); + + do_check_true(prefetch.hasMoreElements(), 'There is still a request ' + + 'in the queue'); + + prefetch.cancelPrefetchURI(uri1, node1); + do_check_false(prefetch.hasMoreElements(), 'There is no request in the queue'); + run_next_test(); +}); diff --git a/dom/base/test/unit/test_chromeutils_base64.js b/dom/base/test/unit/test_chromeutils_base64.js new file mode 100644 index 0000000000..361392c44d --- /dev/null +++ b/dom/base/test/unit/test_chromeutils_base64.js @@ -0,0 +1,105 @@ +"use strict"; + +function run_test() { + test_base64URLEncode(); + test_base64URLDecode(); +} + +// Test vectors from RFC 4648, section 10. +let textTests = { + "": "", + "f": "Zg", + "fo": "Zm8", + "foo": "Zm9v", + "foob": "Zm9vYg", + "fooba": "Zm9vYmE", + "foobar": "Zm9vYmFy", +} + +// Examples from RFC 4648, section 9. +let binaryTests = [{ + decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]), + encoded: "FPucA9l-", +}, { + decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03, 0xd9]), + encoded: "FPucA9k", +}, { + decoded: new Uint8Array([0x14, 0xfb, 0x9c, 0x03]), + encoded: "FPucAw", +}]; + +function padEncodedValue(value) { + switch (value.length % 4) { + case 0: + return value; + case 2: + return value + "=="; + case 3: + return value + "="; + default: + throw new TypeError("Invalid encoded value"); + } +} + +function testEncode(input, encoded) { + equal(ChromeUtils.base64URLEncode(input, { pad: false }), + encoded, encoded + " without padding"); + equal(ChromeUtils.base64URLEncode(input, { pad: true }), + padEncodedValue(encoded), encoded + " with padding"); +} + +function test_base64URLEncode() { + throws(_ => ChromeUtils.base64URLEncode(new Uint8Array(0)), /TypeError/, + "Should require encoding options"); + throws(_ => ChromeUtils.base64URLEncode(new Uint8Array(0), {}), /TypeError/, + "Encoding should require the padding option"); + + for (let {decoded, encoded} of binaryTests) { + testEncode(decoded, encoded); + } + + let textEncoder = new TextEncoder("utf-8"); + for (let decoded of Object.keys(textTests)) { + let input = textEncoder.encode(decoded); + testEncode(input, textTests[decoded]); + } +} + +function testDecode(input, decoded) { + let buffer = ChromeUtils.base64URLDecode(input, { padding: "reject" }); + deepEqual(new Uint8Array(buffer), decoded, input + " with padding rejected"); + + let paddedValue = padEncodedValue(input); + buffer = ChromeUtils.base64URLDecode(paddedValue, { padding: "ignore" }); + deepEqual(new Uint8Array(buffer), decoded, input + " with padding ignored"); + + if (paddedValue.length > input.length) { + throws(_ => ChromeUtils.base64URLDecode(paddedValue, { padding: "reject" }), + paddedValue + " with padding rejected should throw"); + + throws(_ => ChromeUtils.base64URLDecode(input, { padding: "require" }), + input + " with padding required should throw"); + + buffer = ChromeUtils.base64URLDecode(paddedValue, { padding: "require" }); + deepEqual(new Uint8Array(buffer), decoded, paddedValue + " with padding required"); + } +} + +function test_base64URLDecode() { + throws(_ => ChromeUtils.base64URLDecode(""), /TypeError/, + "Should require decoding options"); + throws(_ => ChromeUtils.base64URLDecode("", {}), /TypeError/, + "Decoding should require the padding option"); + throws(_ => ChromeUtils.base64URLDecode("", { padding: "chocolate" }), + "Decoding should throw for invalid padding policy"); + + for (let {decoded, encoded} of binaryTests) { + testDecode(encoded, decoded); + } + + let textEncoder = new TextEncoder("utf-8"); + for (let decoded of Object.keys(textTests)) { + let expectedBuffer = textEncoder.encode(decoded); + testDecode(textTests[decoded], expectedBuffer); + } +} diff --git a/dom/base/test/unit/test_delete_range.xml b/dom/base/test/unit/test_delete_range.xml new file mode 100644 index 0000000000..c8d50bd32a --- /dev/null +++ b/dom/base/test/unit/test_delete_range.xml @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +This file holds serialized tests for DOM Range tests on extractContents. +The <test/> elements designate individual tests. Each one has the following: + +* A <source/> element, designating the start conditions of the test, +* A <result/> element, designating what the source element should look like + after the extraction, +* An <extract/> element, designating what the extracted content should look like. + +The <split/> element designates a split between two DOM nodes. This element will +be removed before the actual test, and the two nodes on either side will not be +merged. + +The <empty-cdata/> element designates an empty character data section. Before +the test executes, this element is replaced with an actual CDATASection node. + +For the <source/> element, there are four attributes: + +* startContainer: A XPath to the startContainer of the range. +* endContainer: A XPath to the endContainer of the range. +* startOffset: The startOffset of the range. +* endOffset: The endOffset of the range. + +Note this test may need updating with a fix for bug 401276. The spec states +adjacent nodes after an extraction should be merged if possible, but using the +normalize() method, which could have unintended side effects... For now, we're +not permitting that, pending clarification. + +Please make sure the first test in this document always tests a range where the +start container and end container are the same text node, and where the start +offset and end offsets are valid and inequal. Some of the additional range +tests (after the bulk of the delete/extract tests) depend on it. + --> +<root> + <!-- Extracting from a text node. --> + <test> + <source startContainer="text()[1]" + endContainer="text()[1]" + startOffset="4" + endOffset="10">The quick fox</source> + <result>The fox</result> + <extract>quick </extract> + </test> + + <!-- Extracting from a CDATA section. --> + <test> + <source startContainer="text()[1]" + endContainer="text()[1]" + startOffset="4" + endOffset="10"><![CDATA[The quick fox]]></source> + <result><![CDATA[The fox]]></result> + <extract><![CDATA[quick ]]></extract> + </test> + + <!-- Snipping the start of a text node. --> + <test> + <source startContainer="text()[1]" + endContainer="text()[1]" + startOffset="0" + endOffset="4"><![CDATA[The quick fox]]></source> + <result><![CDATA[quick fox]]></result> + <extract><![CDATA[The ]]></extract> + </test> + + <!-- Extracting from a comment. --> + <test> + <source startContainer="comment()[1]" + endContainer="comment()[1]" + startOffset="4" + endOffset="10"><!--The quick fox--></source> + <result><!--The fox--></result> + <extract><!--quick --></extract> + </test> + + <!-- Snipping whole nodes --> + <test> + <source startContainer="." + endContainer="." + startOffset="0" + endOffset="2">Fox<fox/>Fox<bear/><!--comment--></source> + <result>Fox<bear/><!--comment--></result> + <extract>Fox<fox/></extract> + </test> + + <!-- Snipping whole nodes --> + <test> + <source startContainer="." + endContainer="." + startOffset="1" + endOffset="3">Fox<fox/>Fox<bear/><!--comment--></source> + <result>Fox<bear/><!--comment--></result> + <extract><fox/>Fox</extract> + </test> + + <!-- Snipping a mixture of nodes and portions of text --> + <test> + <source startContainer="text()[2]" + startOffset="1" + endContainer="comment()[1]" + endOffset="3">Fox<fox/>Fox<bear><?cow ?></bear><!--comment--></source> + <result>Fox<fox/>F<!--ment--></result> + <extract>ox<bear><?cow ?></bear><!--com--></extract> + </test> + + <!-- Extracting with a collapsed range from a text node. --> + <test> + <source startContainer="text()[1]" + endContainer="text()[1]" + startOffset="4" + endOffset="4">The quick fox</source> + <result>The quick fox</result> + <extract/> + </test> + + <!-- Extracting with a collapsed range from a non-text node. --> + <test> + <source startContainer="." + endContainer="." + startOffset="0" + endOffset="0">Fox<fox/>Fox<bear/><!--comment--></source> + <result>Fox<fox/>Fox<bear/><!--comment--></result> + <extract/> + </test> +</root> diff --git a/dom/base/test/unit/test_error_codes.js b/dom/base/test/unit/test_error_codes.js new file mode 100644 index 0000000000..c4f488f189 --- /dev/null +++ b/dom/base/test/unit/test_error_codes.js @@ -0,0 +1,68 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +var gExpectedStatus = null; +var gNextTestFunc = null; + +var prefs = Components.classes["@mozilla.org/preferences-service;1"]. + getService(Components.interfaces.nsIPrefBranch); + +var asyncXHR = { + load: function() { + var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Components.interfaces.nsIXMLHttpRequest); + request.open("GET", "http://localhost:4444/test_error_code.xml", true); + + var self = this; + request.addEventListener("error", function(event) { self.onError(event); }, false); + request.send(null); + }, + onError: function doAsyncRequest_onError(event) { + var request = event.target.channel.QueryInterface(Components.interfaces.nsIRequest); + do_check_eq(request.status, gExpectedStatus); + gNextTestFunc(); + } +} + +function run_test() { + do_test_pending(); + do_timeout(0, run_test_pt1); +} + +// network offline +function run_test_pt1() { + var ioService = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + + try { + ioService.manageOfflineStatus = false; + } + catch (e) { + } + ioService.offline = true; + prefs.setBoolPref("network.dns.offline-localhost", false); + + gExpectedStatus = Components.results.NS_ERROR_OFFLINE; + gNextTestFunc = run_test_pt2; + dump("Testing error returned by async XHR when the network is offline\n"); + asyncXHR.load(); +} + +// connection refused +function run_test_pt2() { + var ioService = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + ioService.offline = false; + prefs.clearUserPref("network.dns.offline-localhost"); + + gExpectedStatus = Components.results.NS_ERROR_CONNECTION_REFUSED; + gNextTestFunc = end_test; + dump("Testing error returned by aync XHR when the connection is refused\n"); + asyncXHR.load(); +} + +function end_test() { + do_test_finished(); +} diff --git a/dom/base/test/unit/test_isequalnode.js b/dom/base/test/unit/test_isequalnode.js new file mode 100644 index 0000000000..5d44b5b50c --- /dev/null +++ b/dom/base/test/unit/test_isequalnode.js @@ -0,0 +1,435 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() +{ + /* + * NOTE: [i] is not allowed in this test, since it's done via classinfo and + * we don't have that in xpcshell; the workaround is item(i). Suck. + */ + init(); + + test_isEqualNode_setAttribute(); + test_isEqualNode_clones(); + test_isEqualNode_variety(); + test_isEqualNode_normalization(); + test_isEqualNode_whitespace(); + test_isEqualNode_namespaces(); + test_isEqualNode_wholeDoc(); + + // XXX should Node.isEqualNode(null) throw or return false? + //test_isEqualNode_null(); + +} + +// TEST CODE + +var doc, root; // cache for use in all tests + +function init() +{ + doc = ParseFile("isequalnode_data.xml"); + root = doc.documentElement; +} + +function test_isEqualNode_setAttribute() +{ + // NOTE: 0, 2 are whitespace + var test1 = doc.getElementById("test_setAttribute"); + var node1 = test1.childNodes.item(1); + var node2 = test1.childNodes.item(3); + + check_eq_nodes(node1, node2); + + + el(node1).setAttribute("bar", "baz"); + check_neq_nodes(node1, node2); + + el(node2).setAttribute("bar", "baz"); + check_eq_nodes(node1, node2); + + + // the null namespace is equivalent to no namespace -- section 1.3.3 + // (XML Namespaces) of DOM 3 Core + node1.setAttributeNS(null, "quux", "17"); + check_neq_nodes(node1, node2); + + node2.setAttribute("quux", "17"); + check_eq_nodes(node1, node2); + + + node2.setAttributeNS("http://mozilla.org/", "seamonkey", "rheet"); + check_neq_nodes(node1, node2); + + node1.setAttribute("seamonkey", "rheet"); + check_neq_nodes(node1, node2); + + node1.setAttributeNS("http://mozilla.org/", "seamonkey", "rheet"); + check_neq_nodes(node1, node2); + + // this overwrites the namespaced "seamonkey" attribute added to node2 + // earlier, because this simply sets whatever attribute has the fully + // qualified name "seamonkey" (the setAttributeNS attribute string wasn't + // prefixed) -- consequently, node1 and node2 are still unequal + node2.setAttribute("seamonkey", "rheet"); + check_neq_nodes(node1, node2); +} + +function test_isEqualNode_clones() +{ + // tests all elements and attributes in the document + var all_elts = doc.getElementsByTagName("*"); + for (var i = 0; i < all_elts.length; i++) + { + var elt = el(all_elts.item(i)); + check_eq_nodes(elt, elt.cloneNode(true)); + + var attrs = elt.attributes; + for (var j = 0; j < attrs.length; j++) + { + var attr = attrs.item(j); + check_eq_nodes(attr, attr.cloneNode(true)); + } + } + + var elm = doc.createElement("foo"); + check_eq_nodes(elm, elm.cloneNode(true)); + check_eq_nodes(elm, elm.cloneNode(false)); + + elm.setAttribute("fiz", "eit"); + check_eq_nodes(elm, elm.cloneNode(true)); + check_eq_nodes(elm, elm.cloneNode(false)); + + elm.setAttributeNS("http://example.com/", "trendoid", "arthroscope"); + check_eq_nodes(elm, elm.cloneNode(true)); + check_eq_nodes(elm, elm.cloneNode(false)); + + var elm2 = elm.cloneNode(true); + check_eq_nodes(elm, elm2); + + const TEXT = "fetishist"; + + elm.textContent = TEXT; + check_neq_nodes(elm, elm2); + + check_neq_nodes(elm, elm.cloneNode(false)); + check_eq_nodes(elm, elm.cloneNode(true)); + + elm2.appendChild(doc.createTextNode(TEXT)); + check_eq_nodes(elm, elm2); + + var att = doc.createAttribute("bar"); + check_eq_nodes(att, att.cloneNode(true)); + check_eq_nodes(att, att.cloneNode(false)); +} + +function test_isEqualNode_variety() +{ + const nodes = + [ + doc.createElement("foo"), + doc.createElementNS("http://example.com/", "foo"), + doc.createElementNS("http://example.org/", "foo"), + doc.createElementNS("http://example.com/", "FOO"), + doc.createAttribute("foo", "href='biz'"), + doc.createAttributeNS("http://example.com/", "foo", "href='biz'"), + doc.createTextNode("foo"), + doc.createTextNode(" "), + doc.createTextNode(" "), + doc.createComment("foo"), + doc.createProcessingInstruction("foo", "href='biz'"), + doc.implementation.createDocumentType("foo", "href='biz'", ""), + doc.implementation.createDocument("http://example.com/", "foo", null), + doc.createDocumentFragment() + ]; + + for (var i = 0; i < nodes.length; i++) + { + for (var j = i; j < nodes.length; j++) + { + if (i == j) + check_eq_nodes(nodes[i], nodes[j]); + else + check_neq_nodes(nodes[i], nodes[j]); + } + } +} + +function test_isEqualNode_normalization() +{ + var norm = doc.getElementById("test_normalization"); + var node1 = norm.childNodes.item(1); + var node2 = norm.childNodes.item(3); + + check_eq_nodes(node1, node2); + + node1.appendChild(doc.createTextNode("")); + check_neq_nodes(node1, node2); + + node1.normalize(); + check_eq_nodes(node1, node2); + + node2.appendChild(doc.createTextNode("fun")); + node2.appendChild(doc.createTextNode("ctor")); + node1.appendChild(doc.createTextNode("functor")); + check_neq_nodes(node1, node2); + + node1.normalize(); + check_neq_nodes(node1, node2); + + node2.normalize(); + check_eq_nodes(node1, node2); + + // reset + while (node1.hasChildNodes()) + node1.removeChild(node1.childNodes.item(0)); + while (node2.hasChildNodes()) + node2.removeChild(node2.childNodes.item(0)); + + // attribute normalization testing + + var at1 = doc.createAttribute("foo"); + var at2 = doc.createAttribute("foo"); + check_eq_nodes(at1, at2); + + // Attr.appendChild isn't implemented yet (bug 56758), so don't run this yet + if (false) + { + at1.appendChild(doc.createTextNode("rasp")); + at2.appendChild(doc.createTextNode("rasp")); + check_eq_nodes(at1, at2); + + at1.appendChild(doc.createTextNode("")); + check_neq_nodes(at1, at2); + + at1.normalize(); + check_eq_nodes(at1, at2); + + at1.appendChild(doc.createTextNode("berry")); + check_neq_nodes(at1, at2); + + at2.appendChild(doc.createTextNode("ber")); + check_neq_nodes(at1, at2); + + at2.appendChild(doc.createTextNode("ry")); + check_neq_nodes(at1, at2); + + at1.normalize(); + check_neq_nodes(at1, at2); + + at2.normalize(); + check_eq_nodes(at1, at2); + } + + node1.setAttributeNode(at1); + check_neq_nodes(node1, node2); + + node2.setAttributeNode(at2); + check_eq_nodes(node1, node2); + + var n1text1 = doc.createTextNode("ratfink"); + var n1elt = doc.createElement("fruitcake"); + var n1text2 = doc.createTextNode("hydrospanner"); + + node1.appendChild(n1text1); + node1.appendChild(n1elt); + node1.appendChild(n1text2); + + check_neq_nodes(node1, node2); + + var n2text1a = doc.createTextNode("rat"); + var n2text1b = doc.createTextNode("fink"); + var n2elt = doc.createElement("fruitcake"); + var n2text2 = doc.createTextNode("hydrospanner"); + + node2.appendChild(n2text1b); + node2.appendChild(n2elt); + node2.appendChild(n2text2); + check_neq_nodes(node1, node2); + + node2.insertBefore(n2text1a, n2text1b); + check_neq_nodes(node1, node2); + + var tmp_node1 = node1.cloneNode(true); + tmp_node1.normalize(); + var tmp_node2 = node2.cloneNode(true); + tmp_node2.normalize(); + check_eq_nodes(tmp_node1, tmp_node2); + + n2elt.appendChild(doc.createTextNode("")); + check_neq_nodes(node1, node2); + + tmp_node1 = node1.cloneNode(true); + tmp_node1.normalize(); + tmp_node2 = node2.cloneNode(true); + tmp_node2.normalize(); + check_eq_nodes(tmp_node1, tmp_node2); + + var typeText1 = doc.createTextNode("type"); + n2elt.appendChild(typeText1); + tmp_node1 = node1.cloneNode(true); + tmp_node1.normalize(); + tmp_node2 = node2.cloneNode(true); + tmp_node2.normalize(); + check_neq_nodes(tmp_node1, tmp_node2); + + n1elt.appendChild(doc.createTextNode("typedef")); + tmp_node1 = node1.cloneNode(true); + tmp_node1.normalize(); + tmp_node2 = node2.cloneNode(true); + tmp_node2.normalize(); + check_neq_nodes(tmp_node1, tmp_node2); + check_neq_nodes(n1elt, n2elt); + + var typeText2 = doc.createTextNode("def"); + n2elt.appendChild(typeText2); + tmp_node1 = node1.cloneNode(true); + tmp_node1.normalize(); + tmp_node2 = node2.cloneNode(true); + tmp_node2.normalize(); + check_eq_nodes(tmp_node1, tmp_node2); + check_neq_nodes(node1, node2); + + n2elt.insertBefore(doc.createTextNode(""), typeText2); + check_neq_nodes(node1, node2); + + n2elt.insertBefore(doc.createTextNode(""), typeText2); + check_neq_nodes(node1, node2); + + n2elt.insertBefore(doc.createTextNode(""), typeText1); + check_neq_nodes(node1, node2); + + node1.normalize(); + node2.normalize(); + check_eq_nodes(node1, node2); +} + +function test_isEqualNode_whitespace() +{ + equality_check_kids("test_pi1", true); + equality_check_kids("test_pi2", true); + equality_check_kids("test_pi3", false); + equality_check_kids("test_pi4", true); + equality_check_kids("test_pi5", true); + + equality_check_kids("test_elt1", false); + equality_check_kids("test_elt2", false); + equality_check_kids("test_elt3", true); + equality_check_kids("test_elt4", false); + equality_check_kids("test_elt5", false); + + equality_check_kids("test_comment1", true); + equality_check_kids("test_comment2", false); + equality_check_kids("test_comment3", false); + equality_check_kids("test_comment4", true); + + equality_check_kids("test_text1", true); + equality_check_kids("test_text2", false); + equality_check_kids("test_text3", false); + + equality_check_kids("test_cdata1", false); + equality_check_kids("test_cdata2", true); + equality_check_kids("test_cdata3", false); + equality_check_kids("test_cdata4", false); + equality_check_kids("test_cdata5", false); +} + +function test_isEqualNode_namespaces() +{ + equality_check_kids("test_ns1", false); + equality_check_kids("test_ns2", false); + + // XXX want more tests here! +} + +function test_isEqualNode_null() +{ + check_neq_nodes(doc, null); + + var elts = doc.getElementsByTagName("*"); + for (var i = 0; i < elts.length; i++) + { + var elt = elts.item(i); + check_neq_nodes(elt, null); + + var attrs = elt.attributes; + for (var j = 0; j < attrs.length; j++) + { + var att = attrs.item(j); + check_neq_nodes(att, null); + + for (var k = 0; k < att.childNodes.length; k++) + { + check_neq_nodes(att.childNodes.item(k), null); + } + } + } +} + +function test_isEqualNode_wholeDoc() +{ + doc = ParseFile("isequalnode_data.xml"); + var doc2 = ParseFile("isequalnode_data.xml"); + var tw1 = + doc.createTreeWalker(doc, Components.interfaces.nsIDOMNodeFilter.SHOW_ALL, + null); + var tw2 = + doc2.createTreeWalker(doc2, Components.interfaces.nsIDOMNodeFilter.SHOW_ALL, + null); + do { + check_eq_nodes(tw1.currentNode, tw2.currentNode); + tw1.nextNode(); + } while(tw2.nextNode()); +} + +// UTILITY FUNCTIONS + +function n(node) { return node ? node.QueryInterface(nsIDOMNode) : null; } +function el(node) { return node ? node.QueryInterface(nsIDOMElement) : null; } +function at(node) { return node ? node.QueryInterface(nsIDOMAttr) : null; } + + +// TESTING FUNCTIONS + +/** + * Compares the first and third (zero-indexed) child nodes of the element + * (typically to allow whitespace) referenced by parentId for isEqualNode + * equality or inequality based on the value of areEqual. + * + * Note that this means that the contents of the element referenced by parentId + * are whitespace-sensitive, and a stray space introduced during an edit to the + * file could result in a correct but unexpected (in)equality failure. + */ +function equality_check_kids(parentId, areEqual) +{ + var parent = doc.getElementById(parentId); + var kid1 = parent.childNodes.item(1); + var kid2 = parent.childNodes.item(3); + + if (areEqual) + check_eq_nodes(kid1, kid2); + else + check_neq_nodes(kid1, kid2); +} + +function check_eq_nodes(n1, n2) +{ + if (n1 && !n1.isEqualNode(n2)) + do_throw(n1 + " should be equal to " + n2); + if (n2 && !n2.isEqualNode(n1)) + do_throw(n2 + " should be equal to " + n1); + if (!n1 && !n2) + do_throw("nodes both null!"); +} + +function check_neq_nodes(n1, n2) +{ + if (n1 && n1.isEqualNode(n2)) + do_throw(n1 + " should not be equal to " + n2); + if (n2 && n2.isEqualNode(n1)) + do_throw(n2 + " should not be equal to " + n1); + if (!n1 && !n2) + do_throw("n1 and n2 both null!"); +} diff --git a/dom/base/test/unit/test_nodelist.js b/dom/base/test/unit/test_nodelist.js new file mode 100644 index 0000000000..50c79da72e --- /dev/null +++ b/dom/base/test/unit/test_nodelist.js @@ -0,0 +1,394 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +function run_test() +{ + + /** + * NOTE: [i] is not allowed in this test, since it's done via classinfo and + * we don't have that in xpcshell. + */ + + test_getElementsByTagName(); + test_getElementsByTagNameNS(); + test_getElementsByAttribute(); + test_getElementsByAttributeNS(); + + // What else should we test? + // XXXbz we need more tests here to test liveness! + +} + +function test_getElementsByTagName() +{ + var doc = ParseFile("nodelist_data_1.xml"); + var root = doc.documentElement; + + // Check that getElementsByTagName returns a nodelist. + do_check_true(doc.getElementsByTagName("*") instanceof nsIDOMNodeList); + do_check_true(root.getElementsByTagName("*") instanceof nsIDOMNodeList); + + // Check that getElementsByTagName excludes the element it's called on. + do_check_eq(doc.getElementsByTagName("*").length, + root.getElementsByTagName("*").length + 1); + do_check_eq(doc.getElementById("test2").getElementsByTagName("*").length, + 8); + do_check_eq(doc.getElementById("test2").getElementsByTagName("test").length, + 3); + + // Check that the first element of getElementsByTagName on the document is + // the right thing. + do_check_eq(doc.getElementsByTagName("*").item(0), root); + + // Check that we get the right things in the right order + var numTests = doc.getElementsByTagName("test").length; + do_check_eq(numTests, 5); + + for (var i = 1; i <= numTests; ++i) { + do_check_true(doc.getElementById("test" + i) instanceof nsIDOMElement); + do_check_eq(doc.getElementById("test" + i), + doc.getElementsByTagName("test").item(i-1)); + } + + // Check that we handle tagnames containing ':' correctly + do_check_true(doc.getElementsByTagName("foo:test") + instanceof nsIDOMNodeList); + do_check_eq(doc.getElementsByTagName("foo:test").length, 2); + + do_check_true(doc.getElementsByTagName("foo2:test") + instanceof nsIDOMNodeList); + do_check_eq(doc.getElementsByTagName("foo2:test").length, 3); + + do_check_true(doc.getElementsByTagName("bar:test") + instanceof nsIDOMNodeList); + do_check_eq(doc.getElementsByTagName("bar:test").length, 4); +} + +function test_getElementsByTagNameNS() +{ + var doc = ParseFile("nodelist_data_1.xml"); + var root = doc.documentElement; + + // Check that getElementsByTagNameNS returns a nodelist. + do_check_true(doc.getElementsByTagNameNS("*", "*") instanceof nsIDOMNodeList); + do_check_true(root.getElementsByTagNameNS("*", "*") instanceof nsIDOMNodeList); + + // Check that passing "" and null for the namespace URI gives the same result + var list1 = doc.getElementsByTagNameNS("", "test"); + var list2 = doc.getElementsByTagNameNS(null, "test"); + do_check_eq(list1.length, list2.length); + for (var i = 0; i < list1.length; ++i) { + do_check_eq(list1.item(i), list2.item(i)); + } + + // Check that getElementsByTagNameNS excludes the element it's called on. + do_check_eq(doc.getElementsByTagNameNS("*", "*").length, + root.getElementsByTagNameNS("*", "*").length + 1); + do_check_eq(doc.getElementById("test2") + .getElementsByTagNameNS("*", "*").length, + 8); + do_check_eq(doc.getElementById("test2") + .getElementsByTagNameNS("", "test").length, + 1); + do_check_eq(doc.getElementById("test2") + .getElementsByTagNameNS("*", "test").length, + 7); + + // Check that the first element of getElementsByTagNameNS on the document is + // the right thing. + do_check_eq(doc.getElementsByTagNameNS("*", "*").item(0), root); + do_check_eq(doc.getElementsByTagNameNS(null, "*").item(0), root); + + // Check that we get the right things in the right order + + + var numTests = doc.getElementsByTagNameNS("*", "test").length; + do_check_eq(numTests, 14); + + for (var i = 1; i <= numTests; ++i) { + do_check_true(doc.getElementById("test" + i) instanceof nsIDOMElement); + do_check_eq(doc.getElementById("test" + i), + doc.getElementsByTagNameNS("*", "test").item(i-1)); + } + + // Check general proper functioning of having a non-wildcard namespace. + var test2 = doc.getElementById("test2"); + do_check_eq(doc.getElementsByTagNameNS("", "test").length, + 3); + do_check_eq(test2.getElementsByTagNameNS("", "test").length, + 1); + do_check_eq(doc.getElementsByTagNameNS("foo", "test").length, + 7); + do_check_eq(test2.getElementsByTagNameNS("foo", "test").length, + 4); + do_check_eq(doc.getElementsByTagNameNS("foo2", "test").length, + 0); + do_check_eq(test2.getElementsByTagNameNS("foo2", "test").length, + 0); + do_check_eq(doc.getElementsByTagNameNS("bar", "test").length, + 4); + do_check_eq(test2.getElementsByTagNameNS("bar", "test").length, + 2); + + // Check that we handle tagnames containing ':' correctly + do_check_true(doc.getElementsByTagNameNS(null, "foo:test") + instanceof nsIDOMNodeList); + do_check_eq(doc.getElementsByTagNameNS(null, "foo:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("foo", "foo:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("bar", "foo:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("*", "foo:test").length, 0); + + do_check_true(doc.getElementsByTagNameNS(null, "foo2:test") + instanceof nsIDOMNodeList); + do_check_eq(doc.getElementsByTagNameNS(null, "foo2:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("foo2", "foo2:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("bar", "foo2:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("*", "foo2:test").length, 0); + + do_check_true(doc.getElementsByTagNameNS(null, "bar:test") + instanceof nsIDOMNodeList); + do_check_eq(doc.getElementsByTagNameNS(null, "bar:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("bar", "bar:test").length, 0); + do_check_eq(doc.getElementsByTagNameNS("*", "bar:test").length, 0); + + // Check that previously-unknown namespaces are handled right. Note that we + // can just hardcode the strings, since we're running only once in XPCshell. + // If someone wants to run these in a browser, some use of Math.random() may + // be in order. + list1 = doc.getElementsByTagNameNS("random-bogus-namespace", "foo"); + list2 = doc.documentElement.getElementsByTagNameNS("random-bogus-namespace2", + "foo"); + do_check_neq(list1, list2); + do_check_eq(list1.length, 0); + do_check_eq(list2.length, 0); + var newNode = doc.createElementNS("random-bogus-namespace", "foo"); + doc.documentElement.appendChild(newNode); + var newNode = doc.createElementNS("random-bogus-namespace2", "foo"); + doc.documentElement.appendChild(newNode); + do_check_eq(list1.length, 1); + do_check_eq(list2.length, 1); +} + +function test_getElementsByAttribute() +{ + var doc = ParseFile("nodelist_data_2.xul"); + var root = doc.documentElement; + + // Sadly, DOMParser can't create XULDocument objects. But at least we have a + // XULElement! + + do_check_true(root instanceof nsIDOMXULElement); + + do_check_true(root.getElementsByAttribute("foo", "foo") instanceof + nsIDOMNodeList); + + var master1 = doc.getElementById("master1"); + var master2 = doc.getElementById("master2"); + var master3 = doc.getElementById("master3"); + var external = doc.getElementById("external"); + + do_check_true(master1 instanceof nsIDOMXULElement); + do_check_true(master2 instanceof nsIDOMXULElement); + do_check_true(master3 instanceof nsIDOMXULElement); + do_check_true(external instanceof nsIDOMXULElement); + + // Basic tests + do_check_eq(root.getElementsByAttribute("foo", "foo").length, + 14); + do_check_eq(master1.getElementsByAttribute("foo", "foo").length, + 4); + + do_check_eq(root.getElementsByAttribute("foo", "bar").length, + 7); + do_check_eq(master1.getElementsByAttribute("foo", "bar").length, + 2); + + do_check_eq(root.getElementsByAttribute("bar", "bar").length, + 7); + do_check_eq(master1.getElementsByAttribute("bar", "bar").length, + 2); + + do_check_eq(root.getElementsByAttribute("foo", "*").length, + 21); + do_check_eq(master1.getElementsByAttribute("foo", "*").length, + 6); + + // Test the various combinations of attributes with colons in the name + do_check_eq(root.getElementsByAttribute("foo:foo", "foo").length, + 16); + do_check_eq(master1.getElementsByAttribute("foo:foo", "foo").length, + 5); + do_check_eq(master2.getElementsByAttribute("foo:foo", "foo").length, + 4); + do_check_eq(master3.getElementsByAttribute("foo:foo", "foo").length, + 4); + do_check_eq(external.getElementsByAttribute("foo:foo", "foo").length, + 2); + + do_check_eq(root.getElementsByAttribute("foo:foo", "bar").length, + 9); + do_check_eq(master1.getElementsByAttribute("foo:foo", "bar").length, + 2); + do_check_eq(master2.getElementsByAttribute("foo:foo", "bar").length, + 3); + do_check_eq(master3.getElementsByAttribute("foo:foo", "bar").length, + 2); + do_check_eq(external.getElementsByAttribute("foo:foo", "bar").length, + 1); + + do_check_eq(root.getElementsByAttribute("foo:bar", "foo").length, + 7); + do_check_eq(master1.getElementsByAttribute("foo:bar", "foo").length, + 2); + do_check_eq(master2.getElementsByAttribute("foo:bar", "foo").length, + 2); + do_check_eq(master3.getElementsByAttribute("foo:bar", "foo").length, + 2); + do_check_eq(external.getElementsByAttribute("foo:bar", "foo").length, + 1); + + do_check_eq(root.getElementsByAttribute("foo:bar", "bar").length, + 14); + do_check_eq(master1.getElementsByAttribute("foo:bar", "bar").length, + 4); + do_check_eq(master2.getElementsByAttribute("foo:bar", "bar").length, + 4); + do_check_eq(master3.getElementsByAttribute("foo:bar", "bar").length, + 4); + do_check_eq(external.getElementsByAttribute("foo:bar", "bar").length, + 2); + + do_check_eq(root.getElementsByAttribute("foo2:foo", "foo").length, + 8); + do_check_eq(master1.getElementsByAttribute("foo2:foo", "foo").length, + 2); + do_check_eq(master2.getElementsByAttribute("foo2:foo", "foo").length, + 2); + do_check_eq(master3.getElementsByAttribute("foo2:foo", "foo").length, + 3); + do_check_eq(external.getElementsByAttribute("foo2:foo", "foo").length, + 1); + + do_check_eq(root.getElementsByAttribute("foo:foo", "*").length, + 25); + do_check_eq(master1.getElementsByAttribute("foo:foo", "*").length, + 7); + do_check_eq(master2.getElementsByAttribute("foo:foo", "*").length, + 7); + do_check_eq(master3.getElementsByAttribute("foo:foo", "*").length, + 6); + do_check_eq(external.getElementsByAttribute("foo:foo", "*").length, + 3); + + do_check_eq(root.getElementsByAttribute("foo2:foo", "bar").length, + 0); + do_check_eq(root.getElementsByAttribute("foo:foo", "baz").length, + 0); +} + +function test_getElementsByAttributeNS() +{ + var doc = ParseFile("nodelist_data_2.xul"); + var root = doc.documentElement; + + // Sadly, DOMParser can't create XULDocument objects. But at least we have a + // XULElement! + + do_check_true(root instanceof nsIDOMXULElement); + + // Check that getElementsByAttributeNS returns a nodelist. + do_check_true(root.getElementsByAttributeNS("*", "*", "*") instanceof + nsIDOMNodeList); + + var master1 = doc.getElementById("master1"); + var master2 = doc.getElementById("master2"); + var master3 = doc.getElementById("master3"); + var external = doc.getElementById("external"); + + do_check_true(master1 instanceof nsIDOMXULElement); + do_check_true(master2 instanceof nsIDOMXULElement); + do_check_true(master3 instanceof nsIDOMXULElement); + do_check_true(external instanceof nsIDOMXULElement); + + // Test wildcard namespace + do_check_eq(root.getElementsByAttributeNS("*", "foo", "foo").length, + 38); + do_check_eq(master1.getElementsByAttributeNS("*", "foo", "foo").length, + 11); + do_check_eq(master2.getElementsByAttributeNS("*", "foo", "foo").length, + 10); + do_check_eq(master3.getElementsByAttributeNS("*", "foo", "foo").length, + 11); + + do_check_eq(root.getElementsByAttributeNS("*", "foo", "bar").length, + 16); + do_check_eq(master1.getElementsByAttributeNS("*", "foo", "bar").length, + 4); + do_check_eq(master2.getElementsByAttributeNS("*", "foo", "bar").length, + 5); + do_check_eq(master3.getElementsByAttributeNS("*", "foo", "bar").length, + 4); + + do_check_eq(root.getElementsByAttributeNS("*", "bar", "bar").length, + 21); + do_check_eq(master1.getElementsByAttributeNS("*", "bar", "bar").length, + 6); + do_check_eq(master2.getElementsByAttributeNS("*", "bar", "bar").length, + 6); + do_check_eq(master3.getElementsByAttributeNS("*", "bar", "bar").length, + 6); + + do_check_eq(root.getElementsByAttributeNS("*", "foo", "*").length, + 54); + do_check_eq(master1.getElementsByAttributeNS("*", "foo", "*").length, + 15); + do_check_eq(master2.getElementsByAttributeNS("*", "foo", "*").length, + 15); + do_check_eq(master3.getElementsByAttributeNS("*", "foo", "*").length, + 15); + + // Test null namespace. This should be the same as getElementsByAttribute. + do_check_eq(root.getElementsByAttributeNS("", "foo", "foo").length, + root.getElementsByAttribute("foo", "foo").length); + do_check_eq(master1.getElementsByAttributeNS("", "foo", "foo").length, + master1.getElementsByAttribute("foo", "foo").length); + do_check_eq(master2.getElementsByAttributeNS("", "foo", "foo").length, + master2.getElementsByAttribute("foo", "foo").length); + do_check_eq(master3.getElementsByAttributeNS("", "foo", "foo").length, + master3.getElementsByAttribute("foo", "foo").length); + + // Test namespace "foo" + do_check_eq(root.getElementsByAttributeNS("foo", "foo", "foo").length, + 24); + do_check_eq(master1.getElementsByAttributeNS("foo", "foo", "foo").length, + 7); + do_check_eq(master2.getElementsByAttributeNS("foo", "foo", "foo").length, + 6); + do_check_eq(master3.getElementsByAttributeNS("foo", "foo", "foo").length, + 7); + + do_check_eq(root.getElementsByAttributeNS("foo", "foo", "bar").length, + 9); + do_check_eq(master1.getElementsByAttributeNS("foo", "foo", "bar").length, + 2); + do_check_eq(master2.getElementsByAttributeNS("foo", "foo", "bar").length, + 3); + do_check_eq(master3.getElementsByAttributeNS("foo", "foo", "bar").length, + 2); + + do_check_eq(root.getElementsByAttributeNS("foo", "bar", "foo").length, + 7); + do_check_eq(master1.getElementsByAttributeNS("foo", "bar", "foo").length, + 2); + do_check_eq(master2.getElementsByAttributeNS("foo", "bar", "foo").length, + 2); + do_check_eq(master3.getElementsByAttributeNS("foo", "bar", "foo").length, + 2); + + do_check_eq(root.getElementsByAttributeNS("foo", "bar", "bar").length, + 14); + do_check_eq(master1.getElementsByAttributeNS("foo", "bar", "bar").length, + 4); + do_check_eq(master2.getElementsByAttributeNS("foo", "bar", "bar").length, + 4); + do_check_eq(master3.getElementsByAttributeNS("foo", "bar", "bar").length, + 4); +} diff --git a/dom/base/test/unit/test_normalize.js b/dom/base/test/unit/test_normalize.js new file mode 100644 index 0000000000..a4f1b4df72 --- /dev/null +++ b/dom/base/test/unit/test_normalize.js @@ -0,0 +1,109 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() +{ + /* + * NOTE: [i] is not allowed in this test, since it's done via classinfo and + * we don't have that in xpcshell; the workaround is item(i). Suck. + */ + init(); + + test_element(); + + // more tests would be nice here (such as for documents), but the primary + // uses of Node.normalize() are in test_element; stuff beyond this is either + // unimplemented or is unlikely to be used all that much within a browser + // DOM implementation +} + +// TEST CODE + +var doc; // cache for use in all tests + +function init() +{ + doc = ParseFile("empty_document.xml"); +} + +function test_element() +{ + var x = doc.createElement("funk"); + + // one empty Text node + x.appendChild(doc.createTextNode("")); + do_check_eq(x.childNodes.length, 1); + + x.normalize(); + do_check_eq(x.childNodes.length, 0); + + + // multiple empty Text nodes + x.appendChild(doc.createTextNode("")); + x.appendChild(doc.createTextNode("")); + do_check_eq(x.childNodes.length, 2); + + x.normalize(); + do_check_eq(x.childNodes.length, 0); + + + // empty Text node followed by other Text node + x.appendChild(doc.createTextNode("")); + x.appendChild(doc.createTextNode("Guaraldi")); + do_check_eq(x.childNodes.length, 2); + + x.normalize(); + do_check_eq(x.childNodes.length, 1); + do_check_eq(x.childNodes.item(0).nodeValue, "Guaraldi"); + + + // Text node followed by empty Text node + clearKids(x); + x.appendChild(doc.createTextNode("Guaraldi")); + x.appendChild(doc.createTextNode("")); + do_check_eq(x.childNodes.length, 2); + + x.normalize(); + do_check_eq(x.childNodes.item(0).nodeValue, "Guaraldi"); + + + // Text node followed by empty Text node followed by other Node + clearKids(x); + x.appendChild(doc.createTextNode("Guaraldi")); + x.appendChild(doc.createTextNode("")); + x.appendChild(doc.createElement("jazzy")); + do_check_eq(x.childNodes.length, 3); + + x.normalize(); + do_check_eq(x.childNodes.length, 2); + do_check_eq(x.childNodes.item(0).nodeValue, "Guaraldi"); + do_check_eq(x.childNodes.item(1).nodeName, "jazzy"); + + + // Nodes are recursively normalized + clearKids(x); + var kid = doc.createElement("eit"); + kid.appendChild(doc.createTextNode("")); + + x.appendChild(doc.createTextNode("Guaraldi")); + x.appendChild(doc.createTextNode("")); + x.appendChild(kid); + do_check_eq(x.childNodes.length, 3); + do_check_eq(x.childNodes.item(2).childNodes.length, 1); + + x.normalize(); + do_check_eq(x.childNodes.length, 2); + do_check_eq(x.childNodes.item(0).nodeValue, "Guaraldi"); + do_check_eq(x.childNodes.item(1).childNodes.length, 0); +} + + +// UTILITY FUNCTIONS + +function clearKids(node) +{ + while (node.hasChildNodes()) + node.removeChild(node.childNodes.item(0)); +} diff --git a/dom/base/test/unit/test_range.js b/dom/base/test/unit/test_range.js new file mode 100644 index 0000000000..0ba1e1cd80 --- /dev/null +++ b/dom/base/test/unit/test_range.js @@ -0,0 +1,465 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const C_i = Components.interfaces; + +const UNORDERED_TYPE = C_i.nsIDOMXPathResult.ANY_UNORDERED_NODE_TYPE; + +/** + * Determine if the data node has only ignorable white-space. + * + * @return nsIDOMNodeFilter.FILTER_SKIP if it does. + * @return nsIDOMNodeFilter.FILTER_ACCEPT otherwise. + */ +function isWhitespace(aNode) { + return ((/\S/).test(aNode.nodeValue)) ? + C_i.nsIDOMNodeFilter.FILTER_SKIP : + C_i.nsIDOMNodeFilter.FILTER_ACCEPT; +} + +/** + * Create a DocumentFragment with cloned children equaling a node's children. + * + * @param aNode The node to copy from. + * + * @return DocumentFragment node. + */ +function getFragment(aNode) { + var frag = aNode.ownerDocument.createDocumentFragment(); + for (var i = 0; i < aNode.childNodes.length; i++) { + frag.appendChild(aNode.childNodes.item(i).cloneNode(true)); + } + return frag; +} + +// Goodies from head_content.js +const serializer = new DOMSerializer(); +const parser = new DOMParser(); + +/** + * Dump the contents of a document fragment to the console. + * + * @param aFragment The fragment to serialize. + */ +function dumpFragment(aFragment) { + dump(serializer.serializeToString(aFragment) + "\n\n"); +} + +/** + * Translate an XPath to a DOM node. This method uses a document + * fragment as context node. + * + * @param aContextNode The context node to apply the XPath to. + * @param aPath The XPath to use. + * + * @return nsIDOMNode The target node retrieved from the XPath. + */ +function evalXPathInDocumentFragment(aContextNode, aPath) { + do_check_true(aContextNode instanceof C_i.nsIDOMDocumentFragment); + do_check_true(aContextNode.childNodes.length > 0); + if (aPath == ".") { + return aContextNode; + } + + // Separate the fragment's xpath lookup from the rest. + var firstSlash = aPath.indexOf("/"); + if (firstSlash == -1) { + firstSlash = aPath.length; + } + var prefix = aPath.substr(0, firstSlash); + var realPath = aPath.substr(firstSlash + 1); + if (!realPath) { + realPath = "."; + } + + // Set up a special node filter to look among the fragment's child nodes. + var childIndex = 1; + var bracketIndex = prefix.indexOf("["); + if (bracketIndex != -1) { + childIndex = Number(prefix.substring(bracketIndex + 1, prefix.indexOf("]"))); + do_check_true(childIndex > 0); + prefix = prefix.substr(0, bracketIndex); + } + + var targetType = C_i.nsIDOMNodeFilter.SHOW_ELEMENT; + var targetNodeName = prefix; + if (prefix.indexOf("processing-instruction(") == 0) { + targetType = C_i.nsIDOMNodeFilter.SHOW_PROCESSING_INSTRUCTION; + targetNodeName = prefix.substring(prefix.indexOf("(") + 2, prefix.indexOf(")") - 1); + } + switch (prefix) { + case "text()": + targetType = C_i.nsIDOMNodeFilter.SHOW_TEXT | + C_i.nsIDOMNodeFilter.SHOW_CDATA_SECTION; + targetNodeName = null; + break; + case "comment()": + targetType = C_i.nsIDOMNodeFilter.SHOW_COMMENT; + targetNodeName = null; + break; + case "node()": + targetType = C_i.nsIDOMNodeFilter.SHOW_ALL; + targetNodeName = null; + } + + var filter = { + count: 0, + + // nsIDOMNodeFilter + acceptNode: function acceptNode(aNode) { + if (aNode.parentNode != aContextNode) { + // Don't bother looking at kids either. + return C_i.nsIDOMNodeFilter.FILTER_REJECT; + } + + if (targetNodeName && targetNodeName != aNode.nodeName) { + return C_i.nsIDOMNodeFilter.FILTER_SKIP; + } + + this.count++; + if (this.count != childIndex) { + return C_i.nsIDOMNodeFilter.FILTER_SKIP; + } + + return C_i.nsIDOMNodeFilter.FILTER_ACCEPT; + } + }; + + // Look for the node matching the step from the document fragment. + var walker = aContextNode.ownerDocument.createTreeWalker( + aContextNode, + targetType, + filter); + var targetNode = walker.nextNode(); + do_check_neq(targetNode, null); + + // Apply our remaining xpath to the found node. + var expr = aContextNode.ownerDocument.createExpression(realPath, null); + var result = expr.evaluate(targetNode, UNORDERED_TYPE, null); + return result.singleNodeValue; +} + +/** + * Get a DOM range corresponding to the test's source node. + * + * @param aSourceNode <source/> element with range information. + * @param aFragment DocumentFragment generated with getFragment(). + * + * @return Range object. + */ +function getRange(aSourceNode, aFragment) { + do_check_true(aSourceNode instanceof C_i.nsIDOMElement); + do_check_true(aFragment instanceof C_i.nsIDOMDocumentFragment); + var doc = aSourceNode.ownerDocument; + + var containerPath = aSourceNode.getAttribute("startContainer"); + var startContainer = evalXPathInDocumentFragment(aFragment, containerPath); + var startOffset = Number(aSourceNode.getAttribute("startOffset")); + + containerPath = aSourceNode.getAttribute("endContainer"); + var endContainer = evalXPathInDocumentFragment(aFragment, containerPath); + var endOffset = Number(aSourceNode.getAttribute("endOffset")); + + var range = doc.createRange(); + range.setStart(startContainer, startOffset); + range.setEnd(endContainer, endOffset); + return range; +} + +/** + * Get the document for a given path, and clean it up for our tests. + * + * @param aPath The path to the local document. + */ +function getParsedDocument(aPath) { + return do_parse_document(aPath, "application/xml").then(processParsedDocument); +} + +function processParsedDocument(doc) { + do_check_true(doc.documentElement.localName != "parsererror"); + do_check_true(doc instanceof C_i.nsIDOMXPathEvaluator); + do_check_true(doc instanceof C_i.nsIDOMDocument); + + // Clean out whitespace. + var walker = doc.createTreeWalker(doc, + C_i.nsIDOMNodeFilter.SHOW_TEXT | + C_i.nsIDOMNodeFilter.SHOW_CDATA_SECTION, + isWhitespace); + while (walker.nextNode()) { + var parent = walker.currentNode.parentNode; + parent.removeChild(walker.currentNode); + walker.currentNode = parent; + } + + // Clean out mandatory splits between nodes. + var splits = doc.getElementsByTagName("split"); + var i; + for (i = splits.length - 1; i >= 0; i--) { + var node = splits.item(i); + node.parentNode.removeChild(node); + } + splits = null; + + // Replace empty CDATA sections. + var emptyData = doc.getElementsByTagName("empty-cdata"); + for (i = emptyData.length - 1; i >= 0; i--) { + var node = emptyData.item(i); + var cdata = doc.createCDATASection(""); + node.parentNode.replaceChild(cdata, node); + } + + return doc; +} + +/** + * Run the extraction tests. + */ +function run_extract_test() { + var filePath = "test_delete_range.xml"; + getParsedDocument(filePath).then(do_extract_test); +} + +function do_extract_test(doc) { + var tests = doc.getElementsByTagName("test"); + + // Run our deletion, extraction tests. + for (var i = 0; i < tests.length; i++) { + dump("Configuring for test " + i + "\n"); + var currentTest = tests.item(i); + + // Validate the test is properly formatted for what this harness expects. + var baseSource = currentTest.firstChild; + do_check_eq(baseSource.nodeName, "source"); + var baseResult = baseSource.nextSibling; + do_check_eq(baseResult.nodeName, "result"); + var baseExtract = baseResult.nextSibling; + do_check_eq(baseExtract.nodeName, "extract"); + do_check_eq(baseExtract.nextSibling, null); + + /* We do all our tests on DOM document fragments, derived from the test + element's children. This lets us rip the various fragments to shreds, + while preserving the original elements so we can make more copies of + them. + + After the range's extraction or deletion is done, we use + nsIDOMNode.isEqualNode() between the altered source fragment and the + result fragment. We also run isEqualNode() between the extracted + fragment and the fragment from the baseExtract node. If they are not + equal, we have failed a test. + + We also have to ensure the original nodes on the end points of the + range are still in the source fragment. This is bug 332148. The nodes + may not be replaced with equal but separate nodes. The range extraction + may alter these nodes - in the case of text containers, they will - but + the nodes must stay there, to preserve references such as user data, + event listeners, etc. + + First, an extraction test. + */ + + var resultFrag = getFragment(baseResult); + var extractFrag = getFragment(baseExtract); + + dump("Extract contents test " + i + "\n\n"); + var baseFrag = getFragment(baseSource); + var baseRange = getRange(baseSource, baseFrag); + var startContainer = baseRange.startContainer; + var endContainer = baseRange.endContainer; + + var cutFragment = baseRange.extractContents(); + dump("cutFragment: " + cutFragment + "\n"); + if (cutFragment) { + do_check_true(extractFrag.isEqualNode(cutFragment)); + } else { + do_check_eq(extractFrag.firstChild, null); + } + do_check_true(baseFrag.isEqualNode(resultFrag)); + + dump("Ensure the original nodes weren't extracted - test " + i + "\n\n"); + var walker = doc.createTreeWalker(baseFrag, + C_i.nsIDOMNodeFilter.SHOW_ALL, + null); + var foundStart = false; + var foundEnd = false; + do { + if (walker.currentNode == startContainer) { + foundStart = true; + } + + if (walker.currentNode == endContainer) { + // An end container node should not come before the start container node. + do_check_true(foundStart); + foundEnd = true; + break; + } + } while (walker.nextNode()) + do_check_true(foundEnd); + + /* Now, we reset our test for the deleteContents case. This one differs + from the extractContents case only in that there is no extracted document + fragment to compare against. So we merely compare the starting fragment, + minus the extracted content, against the result fragment. + */ + dump("Delete contents test " + i + "\n\n"); + baseFrag = getFragment(baseSource); + baseRange = getRange(baseSource, baseFrag); + var startContainer = baseRange.startContainer; + var endContainer = baseRange.endContainer; + baseRange.deleteContents(); + do_check_true(baseFrag.isEqualNode(resultFrag)); + + dump("Ensure the original nodes weren't deleted - test " + i + "\n\n"); + walker = doc.createTreeWalker(baseFrag, + C_i.nsIDOMNodeFilter.SHOW_ALL, + null); + foundStart = false; + foundEnd = false; + do { + if (walker.currentNode == startContainer) { + foundStart = true; + } + + if (walker.currentNode == endContainer) { + // An end container node should not come before the start container node. + do_check_true(foundStart); + foundEnd = true; + break; + } + } while (walker.nextNode()) + do_check_true(foundEnd); + + // Clean up after ourselves. + walker = null; + } +} + +/** + * Miscellaneous tests not covered above. + */ +function run_miscellaneous_tests() { + var filePath = "test_delete_range.xml"; + getParsedDocument(filePath).then(do_miscellaneous_tests); +} + +function do_miscellaneous_tests(doc) { + var tests = doc.getElementsByTagName("test"); + + // Let's try some invalid inputs to our DOM range and see what happens. + var currentTest = tests.item(0); + var baseSource = currentTest.firstChild; + var baseResult = baseSource.nextSibling; + var baseExtract = baseResult.nextSibling; + + var baseFrag = getFragment(baseSource); + + var baseRange = getRange(baseSource, baseFrag); + var startContainer = baseRange.startContainer; + var endContainer = baseRange.endContainer; + var startOffset = baseRange.startOffset; + var endOffset = baseRange.endOffset; + + // Text range manipulation. + if ((endOffset > startOffset) && + (startContainer == endContainer) && + (startContainer instanceof C_i.nsIDOMText)) { + // Invalid start node + try { + baseRange.setStart(null, 0); + do_throw("Should have thrown NOT_OBJECT_ERR!"); + } catch (e) { + do_check_eq(e.constructor.name, "TypeError"); + } + + // Invalid start node + try { + baseRange.setStart({}, 0); + do_throw("Should have thrown SecurityError!"); + } catch (e) { + do_check_eq(e.constructor.name, "TypeError"); + } + + // Invalid index + try { + baseRange.setStart(startContainer, -1); + do_throw("Should have thrown IndexSizeError!"); + } catch (e) { + do_check_eq(e.name, "IndexSizeError"); + } + + // Invalid index + var newOffset = startContainer instanceof C_i.nsIDOMText ? + startContainer.nodeValue.length + 1 : + startContainer.childNodes.length + 1; + try { + baseRange.setStart(startContainer, newOffset); + do_throw("Should have thrown IndexSizeError!"); + } catch (e) { + do_check_eq(e.name, "IndexSizeError"); + } + + newOffset--; + // Valid index + baseRange.setStart(startContainer, newOffset); + do_check_eq(baseRange.startContainer, baseRange.endContainer); + do_check_eq(baseRange.startOffset, newOffset); + do_check_true(baseRange.collapsed); + + // Valid index + baseRange.setEnd(startContainer, 0); + do_check_eq(baseRange.startContainer, baseRange.endContainer); + do_check_eq(baseRange.startOffset, 0); + do_check_true(baseRange.collapsed); + } else { + do_throw("The first test should be a text-only range test. Test is invalid.") + } + + /* See what happens when a range has a startContainer in one fragment, and an + endContainer in another. According to the DOM spec, section 2.4, the range + should collapse to the new container and offset. */ + baseRange = getRange(baseSource, baseFrag); + startContainer = baseRange.startContainer; + var startOffset = baseRange.startOffset; + endContainer = baseRange.endContainer; + var endOffset = baseRange.endOffset; + + dump("External fragment test\n\n"); + + var externalTest = tests.item(1); + var externalSource = externalTest.firstChild; + var externalFrag = getFragment(externalSource); + var externalRange = getRange(externalSource, externalFrag); + + baseRange.setEnd(externalRange.endContainer, 0); + do_check_eq(baseRange.startContainer, externalRange.endContainer); + do_check_eq(baseRange.startOffset, 0); + do_check_true(baseRange.collapsed); + + /* + // XXX ajvincent if rv == WRONG_DOCUMENT_ERR, return false? + do_check_false(baseRange.isPointInRange(startContainer, startOffset)); + do_check_false(baseRange.isPointInRange(startContainer, startOffset + 1)); + do_check_false(baseRange.isPointInRange(endContainer, endOffset)); + */ + + // Requested by smaug: A range involving a comment as a document child. + doc = parser.parseFromString("<!-- foo --><foo/>", "application/xml"); + do_check_true(doc instanceof C_i.nsIDOMDocument); + do_check_eq(doc.childNodes.length, 2); + baseRange = doc.createRange(); + baseRange.setStart(doc.firstChild, 1); + baseRange.setEnd(doc.firstChild, 2); + var frag = baseRange.extractContents(); + do_check_eq(frag.childNodes.length, 1); + do_check_true(frag.firstChild instanceof C_i.nsIDOMComment); + do_check_eq(frag.firstChild.nodeValue, "f"); + + /* smaug also requested attribute tests. Sadly, those are not yet supported + in ranges - see https://bugzilla.mozilla.org/show_bug.cgi?id=302775. + */ +} + +function run_test() { + run_extract_test(); + run_miscellaneous_tests(); +} diff --git a/dom/base/test/unit/test_thirdpartyutil.js b/dom/base/test/unit/test_thirdpartyutil.js new file mode 100644 index 0000000000..2c4ef47458 --- /dev/null +++ b/dom/base/test/unit/test_thirdpartyutil.js @@ -0,0 +1,96 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Test ThirdPartyUtil methods. See mozIThirdPartyUtil. + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; + +Cu.import("resource://gre/modules/NetUtil.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); + +var prefs = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + +// Since this test creates a TYPE_DOCUMENT channel via javascript, it will +// end up using the wrong LoadInfo constructor. Setting this pref will disable +// the ContentPolicyType assertion in the constructor. +prefs.setBoolPref("network.loadinfo.skip_type_assertion", true); + +var NS_ERROR_INVALID_ARG = Components.results.NS_ERROR_INVALID_ARG; + +function do_check_throws(f, result, stack) +{ + if (!stack) { + try { + // We might not have a 'Components' object. + stack = Components.stack.caller; + } catch (e) { + } + } + + try { + f(); + } catch (exc) { + do_check_eq(exc.result, result); + return; + } + do_throw("expected " + result + " exception, none thrown", stack); +} + +function run_test() { + let util = Cc["@mozilla.org/thirdpartyutil;1"].getService(Ci.mozIThirdPartyUtil); + + // Create URIs and channels pointing to foo.com and bar.com. + // We will use these to put foo.com into first and third party contexts. + let spec1 = "http://foo.com/foo.html"; + let spec2 = "http://bar.com/bar.html"; + let uri1 = NetUtil.newURI(spec1); + let uri2 = NetUtil.newURI(spec2); + const contentPolicyType = Ci.nsIContentPolicy.TYPE_DOCUMENT; + let channel1 = NetUtil.newChannel({uri: uri1, loadUsingSystemPrincipal: true, contentPolicyType}); + let channel2 = NetUtil.newChannel({uri: uri2, loadUsingSystemPrincipal: true, contentPolicyType}); + + // Create some file:// URIs. + let filespec1 = "file://foo.txt"; + let filespec2 = "file://bar.txt"; + let fileuri1 = NetUtil.newURI(filespec1); + let fileuri2 = NetUtil.newURI(filespec2); + let filechannel1 = NetUtil.newChannel({uri: fileuri1, loadUsingSystemPrincipal: true}); + let filechannel2 = NetUtil.newChannel({uri: fileuri2, loadUsingSystemPrincipal: true}); + + // Test isThirdPartyURI. + do_check_false(util.isThirdPartyURI(uri1, uri1)); + do_check_true(util.isThirdPartyURI(uri1, uri2)); + do_check_true(util.isThirdPartyURI(uri2, uri1)); + do_check_false(util.isThirdPartyURI(fileuri1, fileuri1)); + do_check_false(util.isThirdPartyURI(fileuri1, fileuri2)); + do_check_true(util.isThirdPartyURI(uri1, fileuri1)); + do_check_throws(function() { util.isThirdPartyURI(uri1, null); }, + NS_ERROR_INVALID_ARG); + do_check_throws(function() { util.isThirdPartyURI(null, uri1); }, + NS_ERROR_INVALID_ARG); + do_check_throws(function() { util.isThirdPartyURI(null, null); }, + NS_ERROR_INVALID_ARG); + + // We can't test isThirdPartyWindow since we can't really set up a window + // hierarchy. We leave that to mochitests. + + // Test isThirdPartyChannel. As above, we can't test the bits that require + // a load context or window heirarchy. Because of bug 1259873, we assume + // that these are not third-party. + do_check_throws(function() { util.isThirdPartyChannel(null); }, + NS_ERROR_INVALID_ARG); + do_check_false(util.isThirdPartyChannel(channel1)); + do_check_false(util.isThirdPartyChannel(channel1, uri1)); + do_check_true(util.isThirdPartyChannel(channel1, uri2)); + + let httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal); + httpchannel1.forceAllowThirdPartyCookie = true; + do_check_false(util.isThirdPartyChannel(channel1)); + do_check_false(util.isThirdPartyChannel(channel1, uri1)); + do_check_true(util.isThirdPartyChannel(channel1, uri2)); +} + diff --git a/dom/base/test/unit/test_treewalker.js b/dom/base/test/unit/test_treewalker.js new file mode 100644 index 0000000000..e9aff3435c --- /dev/null +++ b/dom/base/test/unit/test_treewalker.js @@ -0,0 +1,26 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function run_test() +{ + test_treeWalker_currentNode(); +} + +// TEST CODE + +function test_treeWalker_currentNode() +{ + var XHTMLDocString = '<html xmlns="http://www.w3.org/1999/xhtml">'; + XHTMLDocString += '<body><input/>input</body></html>'; + + var doc = ParseXML(XHTMLDocString); + + var body = doc.getElementsByTagName("body")[0]; + var filter = I.nsIDOMNodeFilter.SHOW_ELEMENT | I.nsIDOMNodeFilter.SHOW_TEXT; + var walker = doc.createTreeWalker(body, filter, null); + walker.currentNode = body.firstChild; + walker.nextNode(); +} + diff --git a/dom/base/test/unit/test_xhr_document.js b/dom/base/test/unit/test_xhr_document.js new file mode 100644 index 0000000000..5a090d598f --- /dev/null +++ b/dom/base/test/unit/test_xhr_document.js @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var Cc = Components.classes; +var Ci = Components.interfaces; +var Cu = Components.utils; + +Cu.import("resource://testing-common/httpd.js"); +Cu.import("resource://gre/modules/NetUtil.jsm"); + +var server = new HttpServer(); +server.start(-1); + +var docbody = '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body></body></html>'; + +function handler(metadata, response) { + let body = NetUtil.readInputStreamToString(metadata.bodyInputStream, + metadata.bodyInputStream.available()); + response.setStatusLine(metadata.httpVersion, 200, "OK"); + response.write(body, body.length); +} + +function run_test() { + do_test_pending(); + server.registerPathHandler("/foo", handler); + + var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser); + parser.init(); + let doc = parser.parseFromString(docbody, "text/html"); + let xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Ci.nsIXMLHttpRequest); + xhr.onload = function() { + do_check_eq(xhr.responseText, docbody); + server.stop(do_test_finished); + }; + xhr.onerror = function() { + do_check_false(false); + server.stop(do_test_finished); + }; + xhr.open("POST", "http://localhost:" + server.identity.primaryPort + "/foo", true); + xhr.send(doc); +} diff --git a/dom/base/test/unit/test_xhr_origin_attributes.js b/dom/base/test/unit/test_xhr_origin_attributes.js new file mode 100644 index 0000000000..5c53771dad --- /dev/null +++ b/dom/base/test/unit/test_xhr_origin_attributes.js @@ -0,0 +1,50 @@ +let Cc = Components.classes; +let Ci = Components.interfaces; +let Cu = Components.utils; + +Cu.import("resource://testing-common/httpd.js"); + +let server = new HttpServer(); +server.start(-1); + +let body = "<!DOCTYPE HTML><html><head><meta charset='utf-8'></head><body></body></html>"; + +function handler(request, response) { + response.setStatusLine(request.httpVersion, 200, "Ok"); + response.setHeader("Content-Type", "text/html", false); + + if (!request.hasHeader("Cookie")) { + response.setHeader("Set-Cookie", "test", false); + ok(true); + } else { + ok(false); + } + + response.bodyOutputStream.write(body, body.length); +} + +function run_test() { + do_test_pending(); + server.registerPathHandler("/foo", handler); + + let xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Ci.nsIXMLHttpRequest); + xhr.open("GET", "http://localhost:" + server.identity.primaryPort + "/foo", true); + xhr.send(null); + + xhr.onload = function() { + // We create another XHR to connect to the same site, but this time we + // specify with different origin attributes, which will make the XHR use a + // different cookie-jar than the previous one. + let xhr2 = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Ci.nsIXMLHttpRequest); + xhr2.open("GET", "http://localhost:" + server.identity.primaryPort + "/foo", true); + xhr2.setOriginAttributes({userContextId: 1}); + xhr2.send(null); + + let loadInfo = xhr2.channel.loadInfo; + Assert.equal(loadInfo.originAttributes.userContextId, 1); + + xhr2.onload = function() { + server.stop(do_test_finished); + } + }; +} diff --git a/dom/base/test/unit/test_xhr_standalone.js b/dom/base/test/unit/test_xhr_standalone.js new file mode 100644 index 0000000000..e1e55f3f58 --- /dev/null +++ b/dom/base/test/unit/test_xhr_standalone.js @@ -0,0 +1,21 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// Test setting .responseType and .withCredentials is allowed +// in non-window non-Worker context + +function run_test() +{ + var xhr = Components.classes['@mozilla.org/xmlextras/xmlhttprequest;1']. + createInstance(Components.interfaces.nsIXMLHttpRequest); + xhr.open('GET', 'data:,', false); + var exceptionThrown = false; + try { + xhr.responseType = ''; + xhr.withCredentials = false; + } catch (e) { + exceptionThrown = true; + } + do_check_eq(false, exceptionThrown); +} diff --git a/dom/base/test/unit/test_xml_parser.js b/dom/base/test/unit/test_xml_parser.js new file mode 100644 index 0000000000..a87c216726 --- /dev/null +++ b/dom/base/test/unit/test_xml_parser.js @@ -0,0 +1,48 @@ +function run_test () { + for (var i = 0; i < tests.length && tests[i][0]; ++i) { + if (!tests[i][0].call()) { + do_throw(tests[i][1]); + } + } +} + +var tests = [ + [ test1, "Unable to parse basic XML document" ], + [ test2, "ParseXML doesn't return nsIDOMDocument" ], + [ test3, "ParseXML return value's documentElement is not nsIDOMElement" ], + [ test4, "" ], + [ test5, "" ], + [ test6, "" ], + [ null ] +]; + +function test1() { + return ParseXML("<root/>"); +} + +function test2() { + return (ParseXML("<root/>") instanceof nsIDOMDocument); +} + +function test3() { + return (ParseXML("<root/>").documentElement instanceof nsIDOMElement); +} + +function test4() { + var doc = ParseXML("<root/>"); + do_check_eq(doc.documentElement.namespaceURI, null); + return true; +} + +function test5() { + var doc = ParseXML("<root xmlns=''/>"); + do_check_eq(doc.documentElement.namespaceURI, null); + return true; +} + +function test6() { + var doc = ParseXML("<root xmlns='ns1'/>"); + do_check_neq(doc.documentElement.namespaceURI, null); + do_check_eq(doc.documentElement.namespaceURI, 'ns1'); + return true; +} diff --git a/dom/base/test/unit/test_xml_serializer.js b/dom/base/test/unit/test_xml_serializer.js new file mode 100644 index 0000000000..c74d067a81 --- /dev/null +++ b/dom/base/test/unit/test_xml_serializer.js @@ -0,0 +1,374 @@ + +// The xml serializer uses the default line break of the plateform. +// So we need to know the value of this default line break, in order +// to build correctly the reference strings for tests. +// This variable will contain this value. +var LB; + +function run_test() { + + if (mozinfo.os == "win") { + LB = "\r\n"; + } else { + LB = "\n"; + } + + for (var i = 0; i < tests.length && tests[i]; ++i) { + tests[i].call(); + } +} + +var tests = [ + test1, + test2, + test3, + test4, + test5, + test6, + test7, + test8, + test9, + test10, + null +]; + +function testString(str) { + do_check_eq(roundtrip(str), str); +} + +function test1() { + // Basic round-tripping which we expect to hand back the same text + // as we passed in (not strictly required for correctness in some of + // those cases, but best for readability of serializer output) + testString('<root/>'); + testString('<root><child/></root>'); + testString('<root xmlns=""/>'); + testString('<root xml:lang="en"/>'); + testString('<root xmlns="ns1"><child xmlns="ns2"/></root>') + testString('<root xmlns="ns1"><child xmlns=""/></root>') + testString('<a:root xmlns:a="ns1"><child/></a:root>') + testString('<a:root xmlns:a="ns1"><a:child/></a:root>') + testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1"/></a:root>') + testString('<a:root xmlns:a="ns1"><a:child xmlns:a="ns2"/></a:root>') + testString('<a:root xmlns:a="ns1"><b:child xmlns:b="ns1" b:attr=""/></a:root>') +} + +function test2() { + // Test setting of "xmlns" attribute in the null namespace + + // XXXbz are these tests needed? What should happen here? These + // may be bogus. + + // Setting random "xmlns" attribute + var doc = ParseXML('<root xmlns="ns1"/>'); + doc.documentElement.setAttribute("xmlns", "ns2"); + do_check_serialize(doc); +} + +function test3() { + // Test basic appending of kids. Again, we're making assumptions + // about how our serializer will serialize simple DOMs. + var doc = ParseXML('<root xmlns="ns1"/>'); + var root = doc.documentElement; + var child = doc.createElementNS("ns2", "child"); + root.appendChild(child); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1"><child xmlns="ns2"/></root>'); + + doc = ParseXML('<root xmlns="ns1"/>'); + root = doc.documentElement; + child = doc.createElementNS("ns2", "prefix:child"); + root.appendChild(child); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1"><prefix:child xmlns:prefix="ns2"/></root>'); + + doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); + root = doc.documentElement; + child = doc.createElementNS("ns2", "prefix:child"); + root.appendChild(child); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<prefix:root xmlns:prefix="ns1"><a0:child xmlns:a0="ns2"/>'+ + '</prefix:root>'); + +} + +function test4() { + // setAttributeNS tests + + var doc = ParseXML('<root xmlns="ns1"/>'); + var root = doc.documentElement; + root.setAttributeNS("ns1", "prefix:local", "val"); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1" prefix:local="val" xmlns:prefix="ns1"/>'); + + doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); + root = doc.documentElement; + root.setAttributeNS("ns1", "local", "val"); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<prefix:root xmlns:prefix="ns1" prefix:local="val"/>'); + + doc = ParseXML('<root xmlns="ns1"/>'); + root = doc.documentElement; + root.setAttributeNS("ns2", "local", "val"); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1" a0:local="val" xmlns:a0="ns2"/>'); + + // Handling of prefix-generation for non-null-namespace attributes + // which have the same namespace as the current default namespace + // (bug 301260). + doc = ParseXML('<root xmlns="ns1"/>'); + root = doc.documentElement; + root.setAttributeNS("ns1", "local", "val"); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1" a0:local="val" xmlns:a0="ns1"/>'); + + // Tree-walking test + doc = ParseXML('<root xmlns="ns1" xmlns:a="ns2">'+ + '<child xmlns:b="ns2" xmlns:a="ns3">'+ + '<child2/></child></root>'); + root = doc.documentElement; + // Have to QI here -- no classinfo flattening in xpcshell, apparently + var node = root.firstChild.firstChild.QueryInterface(nsIDOMElement); + node.setAttributeNS("ns4", "l1", "v1"); + node.setAttributeNS("ns4", "p2:l2", "v2"); + node.setAttributeNS("", "l3", "v3"); + node.setAttributeNS("ns3", "l4", "v4"); + node.setAttributeNS("ns3", "p5:l5", "v5"); + node.setAttributeNS("ns3", "a:l6", "v6"); + node.setAttributeNS("ns2", "l7", "v7"); + node.setAttributeNS("ns2", "p8:l8", "v8"); + node.setAttributeNS("ns2", "b:l9", "v9"); + node.setAttributeNS("ns2", "a:l10", "v10"); + node.setAttributeNS("ns1", "a:l11", "v11"); + node.setAttributeNS("ns1", "b:l12", "v12"); + node.setAttributeNS("ns1", "l13", "v13"); + do_check_serialize(doc); + // Note: we end up with "a2" as the prefix on "l11" and "l12" because we use + // "a1" earlier, and discard it in favor of something we get off the + // namespace stack, apparently + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1" xmlns:a="ns2">'+ + '<child xmlns:b="ns2" xmlns:a="ns3">'+ + '<child2 a0:l1="v1" xmlns:a0="ns4"' + + ' a0:l2="v2"' + + ' l3="v3"' + + ' a:l4="v4"' + + ' a:l5="v5"' + + ' a:l6="v6"' + + ' b:l7="v7"' + + ' b:l8="v8"' + + ' b:l9="v9"' + + ' b:l10="v10"' + + ' a2:l11="v11" xmlns:a2="ns1"' + + ' a2:l12="v12"' + + ' a2:l13="v13"/></child></root>'); +} + +function test5() { + // Handling of kids in the null namespace when the default is a + // different namespace (bug 301260). + var doc = ParseXML('<root xmlns="ns1"/>') + var child = doc.createElement('child'); + doc.documentElement.appendChild(child); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1"><child xmlns=""/></root>'); +} + +function test6() { + // Handling of not using a namespace prefix (or default namespace!) + // that's not bound to our namespace in our scope (bug 301260). + var doc = ParseXML('<prefix:root xmlns:prefix="ns1"/>'); + var root = doc.documentElement; + var child1 = doc.createElementNS("ns2", "prefix:child1"); + var child2 = doc.createElementNS("ns1", "prefix:child2"); + child1.appendChild(child2); + root.appendChild(child1); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<prefix:root xmlns:prefix="ns1"><a0:child1 xmlns:a0="ns2">'+ + '<prefix:child2/></a0:child1></prefix:root>'); + + doc = ParseXML('<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2"/></root>'); + root = doc.documentElement; + child1 = root.firstChild; + child2 = doc.createElementNS("ns1", "prefix:child2"); + child1.appendChild(child2); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1"><prefix:child1 xmlns:prefix="ns2">'+ + '<child2/></prefix:child1></root>'); + + doc = ParseXML('<prefix:root xmlns:prefix="ns1">'+ + '<prefix:child1 xmlns:prefix="ns2"/></prefix:root>'); + root = doc.documentElement; + child1 = root.firstChild; + child2 = doc.createElementNS("ns1", "prefix:child2"); + child1.appendChild(child2); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<prefix:root xmlns:prefix="ns1"><prefix:child1 xmlns:prefix="ns2">'+ + '<a0:child2 xmlns:a0="ns1"/></prefix:child1></prefix:root>'); + + + doc = ParseXML('<root xmlns="ns1"/>'); + root = doc.documentElement; + child1 = doc.createElementNS("ns2", "child1"); + child2 = doc.createElementNS("ns1", "child2"); + child1.appendChild(child2); + root.appendChild(child1); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="ns1"><child1 xmlns="ns2"><child2 xmlns="ns1"/>'+ + '</child1></root>'); +} + +function test7() { + // Handle xmlns attribute declaring a default namespace on a non-namespaced + // element (bug 326994). + var doc = ParseXML('<root xmlns=""/>') + var root = doc.documentElement; + root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", + "http://www.w3.org/1999/xhtml"); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), '<root/>'); + + doc = ParseXML('<root xmlns=""><child1/></root>') + root = doc.documentElement; + root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", + "http://www.w3.org/1999/xhtml"); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), '<root><child1/></root>'); + + doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' + + '<child1 xmlns=""><child2/></child1></root>') + root = doc.documentElement; + + // No interface flattening in xpcshell + var child1 = root.firstChild.QueryInterface(nsIDOMElement); + child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", + "http://www.w3.org/1999/xhtml"); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' + + '<child2/></child1></root>'); + + doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' + + '<child1 xmlns="">' + + '<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' + + '</child1></root>') + root = doc.documentElement; + // No interface flattening in xpcshell + child1 = root.firstChild.QueryInterface(nsIDOMElement); + var child2 = child1.firstChild.QueryInterface(nsIDOMElement); + child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", + "http://www.w3.org/1999/xhtml"); + child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", ""); + do_check_serialize(doc); + do_check_eq(SerializeXML(doc), + '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' + + '<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>'); +} + +function test8() { + // Test behavior of serializing with a given charset. + var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+LB+'<root/>'; + var str2 = '<?xml version="1.0" encoding="UTF8"?>'+LB+'<root/>'; + var doc1 = ParseXML(str1); + var doc2 = ParseXML(str2); + + var p = Pipe(); + DOMSerializer().serializeToStream(doc1, p.outputStream, "ISO-8859-1"); + p.outputStream.close(); + do_check_eq(ScriptableInput(p).read(-1), str1); + + p = Pipe(); + DOMSerializer().serializeToStream(doc2, p.outputStream, "ISO-8859-1"); + p.outputStream.close(); + do_check_eq(ScriptableInput(p).read(-1), str1); + + p = Pipe(); + DOMSerializer().serializeToStream(doc1, p.outputStream, "UTF8"); + p.outputStream.close(); + do_check_eq(ScriptableInput(p).read(-1), str2); + + p = Pipe(); + DOMSerializer().serializeToStream(doc2, p.outputStream, "UTF8"); + p.outputStream.close(); + do_check_eq(ScriptableInput(p).read(-1), str2); +} + +function test9() { + // Test behavior of serializing between given charsets, using + // ISO-8859-1-representable text. + var contents = '<root>' + + '\u00BD + \u00BE == \u00BD\u00B2 + \u00BC + \u00BE' + + '</root>'; + var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+ LB + contents; + var str2 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents; + var str3 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents; + var doc1 = ParseXML(str1); + var doc2 = ParseXML(str2); + var doc3 = ParseXML(str3); + + checkSerialization(doc1, "ISO-8859-1", str1); + checkSerialization(doc2, "ISO-8859-1", str1); + checkSerialization(doc3, "ISO-8859-1", str1); + + checkSerialization(doc1, "UTF8", str2); + checkSerialization(doc2, "UTF8", str2); + checkSerialization(doc3, "UTF8", str2); + + checkSerialization(doc1, "UTF-16", str3); + checkSerialization(doc2, "UTF-16", str3); + checkSerialization(doc3, "UTF-16", str3); +} + +function test10() { + // Test behavior of serializing between given charsets, using + // Unicode characters (XXX but only BMP ones because I don't know + // how to create one with non-BMP characters, either with JS strings + // or using DOM APIs). + var contents = '<root>' + + 'AZaz09 \u007F ' + // U+000000 to U+00007F + '\u0080 \u0398 \u03BB \u0725 ' + // U+000080 to U+0007FF + '\u0964 \u0F5F \u20AC \uFFFB' + // U+000800 to U+00FFFF + '</root>'; + var str1 = '<?xml version="1.0" encoding="UTF8"?>'+ LB + contents; + var str2 = '<?xml version="1.0" encoding="UTF-16"?>'+ LB + contents; + var doc1 = ParseXML(str1); + var doc2 = ParseXML(str2); + + checkSerialization(doc1, "UTF8", str1); + checkSerialization(doc2, "UTF8", str1); + + checkSerialization(doc1, "UTF-16", str2); + checkSerialization(doc2, "UTF-16", str2); +} + +function checkSerialization(doc, toCharset, expectedString) { + var p = Pipe(); + DOMSerializer().serializeToStream(doc, p.outputStream, toCharset); + p.outputStream.close(); + + var cin = C["@mozilla.org/intl/converter-input-stream;1"] + .createInstance(I.nsIConverterInputStream); + cin.init(p.inputStream, toCharset, 1024, 0x0); + + // compare the first expectedString.length characters for equality + var outString = {}; + var count = cin.readString(expectedString.length, outString); + do_check_true(count == expectedString.length); + do_check_true(outString.value == expectedString); + + // if there's anything more in the stream, it's a bug + do_check_eq(0, cin.readString(1, outString)); + do_check_eq(outString.value, ""); +} diff --git a/dom/base/test/unit/test_xmlserializer.js b/dom/base/test/unit/test_xmlserializer.js new file mode 100644 index 0000000000..8c6020a70c --- /dev/null +++ b/dom/base/test/unit/test_xmlserializer.js @@ -0,0 +1,112 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function xmlEncode(aFile, aFlags, aCharset) { + if(aFlags == undefined) aFlags = 0; + if(aCharset == undefined) aCharset = "UTF-8"; + + return do_parse_document(aFile, "text/xml").then(doc => { + var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/xml"] + .createInstance(nsIDocumentEncoder); + encoder.setCharset(aCharset); + encoder.init(doc, "text/xml", aFlags); + return encoder.encodeToString(); + }); +} + +function run_test() +{ + var result, expected; + const de = Components.interfaces.nsIDocumentEncoder; + + xmlEncode("1_original.xml", de.OutputLFLineBreak).then(result => { + expected = loadContentFile("1_result.xml"); + do_check_eq(expected, result); + }); + + xmlEncode("2_original.xml", de.OutputLFLineBreak).then(result => { + expected = loadContentFile("2_result_1.xml"); + do_check_eq(expected, result); + }); + + xmlEncode("2_original.xml", de.OutputCRLineBreak).then(result => { + expected = expected.replace(/\n/g, "\r"); + do_check_eq(expected, result); + }); + + xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputCRLineBreak).then(result => { + expected = expected.replace(/\r/mg, "\r\n"); + do_check_eq(expected, result); + }); + + xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputFormatted).then(result => { + expected = loadContentFile("2_result_2.xml"); + do_check_eq(expected, result); + }); + + xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap).then(result => { + expected = loadContentFile("2_result_3.xml"); + do_check_eq(expected, result); + }); + + xmlEncode("2_original.xml", de.OutputLFLineBreak | de.OutputWrap).then(result => { + expected = loadContentFile("2_result_4.xml"); + do_check_eq(expected, result); + }); + + xmlEncode("3_original.xml", de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap).then(result => { + expected = loadContentFile("3_result.xml"); + do_check_eq(expected, result); + }); + + xmlEncode("3_original.xml", de.OutputLFLineBreak | de.OutputWrap).then(result => { + expected = loadContentFile("3_result_2.xml"); + do_check_eq(expected, result); + }); + + // tests on namespaces + do_parse_document("4_original.xml", "text/xml").then(run_namespace_tests); +} + +function run_namespace_tests(doc) { + const de = Components.interfaces.nsIDocumentEncoder; + var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/xml"] + .createInstance(nsIDocumentEncoder); + encoder.setCharset("UTF-8"); + encoder.init(doc, "text/xml", de.OutputLFLineBreak); + + result = encoder.encodeToString(); + expected = loadContentFile("4_result_1.xml"); + do_check_eq(expected, result); + + encoder.setNode(doc.documentElement.childNodes[9]); + result = encoder.encodeToString(); + expected = loadContentFile("4_result_2.xml"); + do_check_eq(expected, result); + + encoder.setNode(doc.documentElement.childNodes[7].childNodes[1]); + result = encoder.encodeToString(); + expected = loadContentFile("4_result_3.xml"); + do_check_eq(expected, result); + + encoder.setNode(doc.documentElement.childNodes[11].childNodes[1]); + result = encoder.encodeToString(); + expected = loadContentFile("4_result_4.xml"); + do_check_eq(expected, result); + + encoder.setCharset("UTF-8"); + // it doesn't support this flags + encoder.init(doc, "text/xml", de.OutputLFLineBreak | de.OutputFormatted | de.OutputWrap); + encoder.setWrapColumn(40); + result = encoder.encodeToString(); + expected = loadContentFile("4_result_5.xml"); + do_check_eq(expected, result); + + encoder.init(doc, "text/xml", de.OutputLFLineBreak | de.OutputWrap); + encoder.setWrapColumn(40); + result = encoder.encodeToString(); + expected = loadContentFile("4_result_6.xml"); + do_check_eq(expected, result); +} diff --git a/dom/base/test/unit/xpcshell.ini b/dom/base/test/unit/xpcshell.ini new file mode 100644 index 0000000000..201b53d91f --- /dev/null +++ b/dom/base/test/unit/xpcshell.ini @@ -0,0 +1,55 @@ +[DEFAULT] +head = head_utilities.js +tail = +support-files = + 1_original.xml + 1_result.xml + 2_original.xml + 2_result_1.xml + 2_result_2.xml + 2_result_3.xml + 2_result_4.xml + 3_original.xml + 3_result.xml + 3_result_2.xml + 4_original.xml + 4_result_1.xml + 4_result_2.xml + 4_result_3.xml + 4_result_4.xml + 4_result_5.xml + 4_result_6.xml + empty_document.xml + isequalnode_data.xml + nodelist_data_1.xml + nodelist_data_2.xul + test_delete_range.xml + +[test_bloburi.js] +[test_bug553888.js] +[test_bug737966.js] +[test_error_codes.js] +run-sequentially = Hardcoded 4444 port. +# Bug 1018414: hardcoded localhost doesn't work properly on some OS X installs +skip-if = os == 'mac' +[test_isequalnode.js] +head = head_xml.js +[test_nodelist.js] +head = head_xml.js +[test_normalize.js] +head = head_xml.js +[test_range.js] +head = head_xml.js +[test_thirdpartyutil.js] +[test_treewalker.js] +head = head_xml.js +[test_xhr_document.js] +[test_xhr_standalone.js] +[test_xhr_origin_attributes.js] +[test_xml_parser.js] +head = head_xml.js +[test_xml_serializer.js] +head = head_xml.js +[test_xmlserializer.js] +[test_cancelPrefetch.js] +[test_chromeutils_base64.js] diff --git a/dom/base/test/unit_ipc/test_bug553888_wrap.js b/dom/base/test/unit_ipc/test_bug553888_wrap.js new file mode 100644 index 0000000000..3f16a1e4ae --- /dev/null +++ b/dom/base/test/unit_ipc/test_bug553888_wrap.js @@ -0,0 +1,4 @@ +function run_test()
+{
+ run_test_in_child("../unit/test_bug553888.js");
+}
\ No newline at end of file diff --git a/dom/base/test/unit_ipc/test_xhr_document_ipc.js b/dom/base/test/unit_ipc/test_xhr_document_ipc.js new file mode 100644 index 0000000000..1f65969b27 --- /dev/null +++ b/dom/base/test/unit_ipc/test_xhr_document_ipc.js @@ -0,0 +1,3 @@ +function run_test() { + run_test_in_child("../unit/test_xhr_document.js"); +} diff --git a/dom/base/test/unit_ipc/xpcshell.ini b/dom/base/test/unit_ipc/xpcshell.ini new file mode 100644 index 0000000000..d05d300cf0 --- /dev/null +++ b/dom/base/test/unit_ipc/xpcshell.ini @@ -0,0 +1,10 @@ +[DEFAULT]
+head =
+tail =
+skip-if = toolkit == 'android'
+support-files =
+ !/dom/base/test/unit/test_bug553888.js
+ !/dom/base/test/unit/test_xhr_document.js
+
+[test_bug553888_wrap.js]
+[test_xhr_document_ipc.js]
diff --git a/dom/base/test/variable_style_sheet.sjs b/dom/base/test/variable_style_sheet.sjs new file mode 100644 index 0000000000..def6465ef2 --- /dev/null +++ b/dom/base/test/variable_style_sheet.sjs @@ -0,0 +1,19 @@ +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/css", false); + + var accessCount; + var state = getState("varSSAccessCount"); + if (!state) { + setState("varSSAccessCount", "0"); + accessCount = 0; + } else { + setState("varSSAccessCount", (parseInt(state) + 1).toString()); + accessCount = parseInt(state) + 1; + } + + response.write("#content { background-color: rgb(" + + (accessCount % 256) + + ", 0, 0); }"); +} diff --git a/dom/base/test/viewport_helpers.js b/dom/base/test/viewport_helpers.js new file mode 100644 index 0000000000..8ad9d2b398 --- /dev/null +++ b/dom/base/test/viewport_helpers.js @@ -0,0 +1,3 @@ +function scaleRatio(scale) { + return {"set": [["layout.css.devPixelsPerPx", "" + scale]]}; +} diff --git a/dom/base/test/w3element_traversal.svg b/dom/base/test/w3element_traversal.svg new file mode 100644 index 0000000000..22540b4648 --- /dev/null +++ b/dom/base/test/w3element_traversal.svg @@ -0,0 +1,70 @@ +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" +[ +<!ENTITY tree "<tspan id='first_element_child_entity'></tspan>"> +]> + +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:pickle="http://ns.example.org/pickle" + version="1.1" + width="100%" height="100%" viewBox="0 0 400 400"> + + <text > + <tspan id="first_element_child_namespace"></tspan> + </text> + <g id="parentEl_namespace"> + <pickle:dill /> + </g> + + <text id="parentEl_pes" > + <tspan id="first_element_child_pes"></tspan> + <tspan id="middle_element_child_pes"></tspan> + <tspan id="last_element_child_pes"></tspan> + </text> + + + <text id="parentEl" > + <tspan id="first_element_child_sibnull"></tspan> + </text> + + <text id="parentEl_nes" > + <tspan id="first_element_child_nes"></tspan> + <tspan id="last_element_child_nes"></tspan> + </text> + + <text id="parentEl_lec" > + <tspan id="first_element_child_lec"></tspan> + <tspan id="last_element_child_lec"></tspan> + </text> + + + <text id="parentEl_fec" > + <tspan id="first_element_child_fec"></tspan> + </text> + + <text id="parentEl_entity" >&tree;</text> + + <text id="parentEl_dynremove" > + <tspan id="first_element_child_dynremove"></tspan> + <tspan id="last_element_child_dynremove"></tspan> + </text> + + <text id="parentEl_dynadd" > + <tspan id="first_element_child_dynadd"></tspan> + </text> + + <text id="parentEl_null" ></text> + + <text id="parentEl_count" > + <tspan id="first_element_child_count"> + <tspan></tspan> + <tspan></tspan> + </tspan> + <tspan id="middle_element_child"></tspan> + <tspan id="last_element_child_count"></tspan> + </text> + + <text id="parentEl_nochild"></text> + +</svg> + diff --git a/dom/base/test/websocket_helpers.js b/dom/base/test/websocket_helpers.js new file mode 100644 index 0000000000..46cf765d7c --- /dev/null +++ b/dom/base/test/websocket_helpers.js @@ -0,0 +1,66 @@ +var current_test = 0; + +function shouldNotOpen(e) { + var ws = e.target; + ok(false, "onopen shouldn't be called on test " + ws._testNumber + "!"); +} + +function shouldCloseCleanly(e) { + var ws = e.target; + ok(e.wasClean, "the ws connection in test " + ws._testNumber + " should be closed cleanly"); +} + +function shouldCloseNotCleanly(e) { + var ws = e.target; + ok(!e.wasClean, "the ws connection in test " + ws._testNumber + " shouldn't be closed cleanly"); +} + +function ignoreError(e) { +} + +function CreateTestWS(ws_location, ws_protocol) { + var ws; + + try { + if (ws_protocol == undefined) { + ws = new WebSocket(ws_location); + } else { + ws = new WebSocket(ws_location, ws_protocol); + } + + ws._testNumber = current_test; + ok(true, "Created websocket for test " + ws._testNumber +"\n"); + + ws.onerror = function(e) { + ok(false, "onerror called on test " + e.target._testNumber + "!"); + } + + } catch (e) { + throw e; + } + + return ws; +} + +function forcegc() { + SpecialPowers.forceGC(); + SpecialPowers.gc(); +} + +function feedback() { + $("feedback").innerHTML = "executing test: " + (current_test+1) + " of " + tests.length + " tests."; +} + +function finish() { + SimpleTest.finish(); +} + +function doTest() { + if (current_test >= tests.length) { + finish(); + return; + } + + feedback(); + tests[current_test++]().then(doTest); +} diff --git a/dom/base/test/websocket_hybi/file_binary-frames_wsh.py b/dom/base/test/websocket_hybi/file_binary-frames_wsh.py new file mode 100644 index 0000000000..656d0e1890 --- /dev/null +++ b/dom/base/test/websocket_hybi/file_binary-frames_wsh.py @@ -0,0 +1,18 @@ +from mod_pywebsocket import common +from mod_pywebsocket import stream + + +def web_socket_do_extra_handshake(request): + pass + + +def web_socket_transfer_data(request): + messages_to_send = ['Hello, world!', '', all_distinct_bytes()] + for message in messages_to_send: + # FIXME: Should use better API to send binary messages when pywebsocket supports it. + header = stream.create_header(common.OPCODE_BINARY, len(message), 1, 0, 0, 0, 0) + request.connection.write(header + message) + + +def all_distinct_bytes(): + return ''.join([chr(i) for i in xrange(256)]) diff --git a/dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py b/dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py new file mode 100644 index 0000000000..024e3f4d07 --- /dev/null +++ b/dom/base/test/websocket_hybi/file_check-binary-messages_wsh.py @@ -0,0 +1,21 @@ +from mod_pywebsocket import common +from mod_pywebsocket import msgutil + + +def web_socket_do_extra_handshake(request): + pass # Always accept. + + +def web_socket_transfer_data(request): + expected_messages = ['Hello, world!', '', all_distinct_bytes()] + + for test_number, expected_message in enumerate(expected_messages): + message = msgutil.receive_message(request) + if type(message) == str and message == expected_message: + msgutil.send_message(request, 'PASS: Message #%d.' % test_number) + else: + msgutil.send_message(request, 'FAIL: Message #%d: Received unexpected message: %r' % (test_number, message)) + + +def all_distinct_bytes(): + return ''.join([chr(i) for i in xrange(256)]) diff --git a/dom/base/test/websocket_hybi/mochitest.ini b/dom/base/test/websocket_hybi/mochitest.ini new file mode 100644 index 0000000000..21d61c8c86 --- /dev/null +++ b/dom/base/test/websocket_hybi/mochitest.ini @@ -0,0 +1,13 @@ +[DEFAULT] +support-files = + file_binary-frames_wsh.py + file_check-binary-messages_wsh.py + +[test_receive-arraybuffer.html] +skip-if = toolkit == 'android' +[test_receive-blob.html] +skip-if = toolkit == 'android' +[test_send-arraybuffer.html] +skip-if = toolkit == 'android' +[test_send-blob.html] +skip-if = toolkit == 'android' diff --git a/dom/base/test/websocket_hybi/test_receive-arraybuffer.html b/dom/base/test/websocket_hybi/test_receive-arraybuffer.html new file mode 100644 index 0000000000..0bd1cfefc9 --- /dev/null +++ b/dom/base/test/websocket_hybi/test_receive-arraybuffer.html @@ -0,0 +1,97 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> + +<script class="testbody" type="text/javascript"> + +function debug(msg) { + ok(1, msg); +} + +function createArrayBufferContainingHelloWorld() +{ + var hello = "Hello, world!"; + var array = new Uint8Array(hello.length); + for (var i = 0; i < hello.length; ++i) + array[i] = hello.charCodeAt(i); + return array.buffer; +} + +function createEmptyArrayBuffer() +{ + return new ArrayBuffer(0); +} + +function createArrayBufferContainingAllDistinctBytes() +{ + var array = new Uint8Array(256); + for (var i = 0; i < 256; ++i) + array[i] = i; + return array.buffer; +} + +var ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/websocket_hybi/file_binary-frames"); +ws.binaryType = "arraybuffer"; +is(ws.binaryType, "arraybuffer", "should be equal to 'arraybuffer'"); + +var closeEvent; +var receivedMessages = []; +var expectedValues = [createArrayBufferContainingHelloWorld(), createEmptyArrayBuffer(), createArrayBufferContainingAllDistinctBytes()]; + +ws.onmessage = function(event) +{ + receivedMessages.push(event.data); +}; + +ws.onclose = function(event) +{ + closeEvent = event; + + is(receivedMessages.length, expectedValues.length, "lengths not equal"); + for (var i = 0; i < expectedValues.length; ++i) + check(i); + SimpleTest.finish(); +}; + +var responseType; + +function check(index) +{ + debug("Checking message #" + index + "."); + ok(receivedMessages[index] instanceof ArrayBuffer, + "Should receive an arraybuffer!"); + checkArrayBuffer(index, receivedMessages[index], expectedValues[index]); +} + +var actualArray; +var expectedArray; + +function checkArrayBuffer(testIndex, actual, expected) +{ + actualArray = new Uint8Array(actual); + expectedArray = new Uint8Array(expected); + is(actualArray.length, expectedArray.length, "lengths not equal"); + // Print only the first mismatched byte in order not to flood console. + for (var i = 0; i < expectedArray.length; ++i) { + if (actualArray[i] != expectedArray[i]) { + ok(false, "Value mismatch: actualArray[" + i + "] = " + actualArray[i] + ", expectedArray[" + i + "] = " + expectedArray[i]); + return; + } + } + ok(true, "Passed: Message #" + testIndex + "."); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> diff --git a/dom/base/test/websocket_hybi/test_receive-blob.html b/dom/base/test/websocket_hybi/test_receive-blob.html new file mode 100644 index 0000000000..cd8beceec9 --- /dev/null +++ b/dom/base/test/websocket_hybi/test_receive-blob.html @@ -0,0 +1,110 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> + +<script class="testbody" type="text/javascript"> + +function debug(msg) { + ok(true, msg); +} + +function createArrayBufferContainingHelloWorld() +{ + var hello = "Hello, world!"; + var array = new Uint8Array(hello.length); + for (var i = 0; i < hello.length; ++i) + array[i] = hello.charCodeAt(i); + return array.buffer; +} + +function createEmptyArrayBuffer() +{ + return new ArrayBuffer(0); +} + +function createArrayBufferContainingAllDistinctBytes() +{ + var array = new Uint8Array(256); + for (var i = 0; i < 256; ++i) + array[i] = i; + return array.buffer; +} + +var ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/websocket_hybi/file_binary-frames"); +is(ws.binaryType, "blob", "should be 'blob'"); + +var closeEvent; +var receivedMessages = []; +var expectedValues = [createArrayBufferContainingHelloWorld(), createEmptyArrayBuffer(), createArrayBufferContainingAllDistinctBytes()]; + +ws.onmessage = function(event) +{ + receivedMessages.push(event.data); +}; + +ws.onclose = function(event) +{ + closeEvent = event; + + is(receivedMessages.length, expectedValues.length, "lengths not same"); + check(0); +}; + +var responseType; + +function check(index) +{ + if (index == expectedValues.length) { + SimpleTest.finish(); + return; + } + + debug("Checking message #" + index + "."); + ok(receivedMessages[index] instanceof Blob, + "We should be receiving a Blob"); + var reader = new FileReader(); + reader.readAsArrayBuffer(receivedMessages[index]); + reader.onload = function(event) + { + checkArrayBuffer(index, reader.result, expectedValues[index]); + check(index + 1); + }; + reader.onerror = function(event) + { + ok(false, "Failed to read blob: error code = " + reader.error.code); + check(index + 1); + }; +} + +var actualArray; +var expectedArray; + +function checkArrayBuffer(testIndex, actual, expected) +{ + actualArray = new Uint8Array(actual); + expectedArray = new Uint8Array(expected); + is(actualArray.length, expectedArray.length, "lengths not same"); + // Print only the first mismatched byte in order not to flood console. + for (var i = 0; i < expectedArray.length; ++i) { + if (actualArray[i] != expectedArray[i]) { + ok(false, "Value mismatch: actualArray[" + i + "] = " + actualArray[i] + ", expectedArray[" + i + "] = " + expectedArray[i]); + return; + } + } + ok(true, "Passed: Message #" + testIndex + "."); +} + +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> diff --git a/dom/base/test/websocket_hybi/test_send-arraybuffer.html b/dom/base/test/websocket_hybi/test_send-arraybuffer.html new file mode 100644 index 0000000000..4db0746fbc --- /dev/null +++ b/dom/base/test/websocket_hybi/test_send-arraybuffer.html @@ -0,0 +1,82 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> + +<script class="testbody" type="text/javascript"> + +function debug(msg) { + ok(1, msg); +} + +function startsWith(target, prefix) +{ + return target.indexOf(prefix) === 0; +} + +function createArrayBufferContainingHelloWorld() +{ + var hello = "Hello, world!"; + var array = new Uint8Array(hello.length); + for (var i = 0; i < hello.length; ++i) + array[i] = hello.charCodeAt(i); + return array.buffer; +} + +function createEmptyArrayBuffer() +{ + return new ArrayBuffer(0); +} + +function createArrayBufferContainingAllDistinctBytes() +{ + var array = new Uint8Array(256); + for (var i = 0; i < 256; ++i) + array[i] = i; + return array.buffer; +} + +var ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/websocket_hybi/file_check-binary-messages"); +var closeEvent; + +ws.onopen = function() +{ + ok(true, "onopen reached"); + ws.send(createArrayBufferContainingHelloWorld()); + ws.send(createEmptyArrayBuffer()); + ws.send(createArrayBufferContainingAllDistinctBytes()); +}; + +ws.onmessage = function(event) +{ + var message = event.data; + if (startsWith(message, "PASS")) + ok(true, message); + else + ok(false, message); +}; + +ws.onclose = function(event) +{ + ok(event.wasClean, "should have closed cleanly"); + SimpleTest.finish(); +}; + +ws.onerror = function(event) +{ + ok(false, "onerror should not have been called"); +}; + +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> diff --git a/dom/base/test/websocket_hybi/test_send-blob.html b/dom/base/test/websocket_hybi/test_send-blob.html new file mode 100644 index 0000000000..291883cd76 --- /dev/null +++ b/dom/base/test/websocket_hybi/test_send-blob.html @@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html> +<head> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body> + +<p id="display"> +</p> +<div id="content" style="display: none"> +</div> +<pre id="test"> + +<script class="testbody" type="text/javascript"> + +function startsWith(target, prefix) +{ + return target.indexOf(prefix) === 0; +} + +function distinctBytes() +{ + var array = new Array(); + for (var i = 0; i < 256; ++i) + array[i] = i; + // Concatenates chars into a single binary string + return String.fromCharCode.apply(null, array); +} + +var filesToCreate = [ + {name: "hellofile", data: "Hello, world!"}, + {name: "emptyfile"}, + {name: "allchars", data: distinctBytes()}, +]; + +SpecialPowers.createFiles(filesToCreate, function (files) { + var ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/websocket_hybi/file_check-binary-messages"); + var closeEvent; + + ws.onopen = function() + { + ws.send(files[0]); + ws.send(files[1]); + ws.send(files[2]); + }; + + ws.onmessage = function(event) + { + var message = event.data; + if (startsWith(message, "PASS")) + ok(true, message); + else + ok(false, message); + }; + + ws.onclose = function(event) + { + ok(event.wasClean, "should have closed cleanly"); + SimpleTest.finish(); + }; +}, +function (msg) { + ok(false, "Failed to create files: " + msg); + SimpleTest.finish(); +}); + +SimpleTest.waitForExplicitFinish(); + +</script> +</body> +</html> diff --git a/dom/base/test/websocket_tests.js b/dom/base/test/websocket_tests.js new file mode 100644 index 0000000000..e628965071 --- /dev/null +++ b/dom/base/test/websocket_tests.js @@ -0,0 +1,1244 @@ +// test1: client tries to connect to a http scheme location; +function test1() { + return new Promise(function(resolve, reject) { + try { + var ws = CreateTestWS("http://mochi.test:8888/tests/dom/base/test/file_websocket"); + ok(false, "test1 failed"); + } catch (e) { + ok(true, "test1 failed"); + } + + resolve(); + }); +} + +// test2: assure serialization of the connections; +// this test expects that the serialization list to connect to the proxy +// is empty. +function test2() { + return new Promise(function(resolve, reject) { + var waitTest2Part1 = true; + var waitTest2Part2 = true; + + var ws1 = CreateTestWS("ws://sub2.test2.example.com/tests/dom/base/test/file_websocket", "test-2.1"); + var ws2 = CreateTestWS("ws://sub2.test2.example.com/tests/dom/base/test/file_websocket", "test-2.2"); + + var ws2CanConnect = false; + + function maybeFinished() { + if (!waitTest2Part1 && !waitTest2Part2) { + resolve(); + } + } + + ws1.onopen = function() { + ok(true, "ws1 open in test 2"); + ws2CanConnect = true; + ws1.close(); + } + + ws1.onclose = function(e) { + waitTest2Part1 = false; + maybeFinished(); + } + + ws2.onopen = function() { + ok(ws2CanConnect, "shouldn't connect yet in test-2!"); + ws2.close(); + } + + ws2.onclose = function(e) { + waitTest2Part2 = false; + maybeFinished(); + } + }); +} + +// test3: client tries to connect to an non-existent ws server; +function test3() { + return new Promise(function(resolve, reject) { + var hasError = false; + var ws = CreateTestWS("ws://this.websocket.server.probably.does.not.exist"); + + ws.onopen = shouldNotOpen; + + ws.onerror = function (e) { + hasError = true; + } + + ws.onclose = function(e) { + shouldCloseNotCleanly(e); + ok(hasError, "rcvd onerror event"); + is(e.code, 1006, "test-3 close code should be 1006 but is:" + e.code); + resolve(); + } + }); +} + +// test4: client tries to connect using a relative url; +function test4() { + return new Promise(function(resolve, reject) { + try { + var ws = CreateTestWS("file_websocket"); + ok(false, "test-4 failed"); + } catch (e) { + ok(true, "test-4 failed"); + } + + resolve(); + }); +} + +// test5: client uses an invalid protocol value; +function test5() { + return new Promise(function(resolve, reject) { + try { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", ""); + ok(false, "couldn't accept an empty string in the protocol parameter"); + } catch (e) { + ok(true, "couldn't accept an empty string in the protocol parameter"); + } + + try { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "\n"); + ok(false, "couldn't accept any not printable ASCII character in the protocol parameter"); + } catch (e) { + ok(true, "couldn't accept any not printable ASCII character in the protocol parameter"); + } + + try { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test 5"); + ok(false, "U+0020 not acceptable in protocol parameter"); + } catch (e) { + ok(true, "U+0020 not acceptable in protocol parameter"); + } + + resolve(); + }); +} + +// test6: counter and encoding check; +function test6() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-6"); + var counter = 1; + + ws.onopen = function() { + ws.send(counter); + } + + ws.onmessage = function(e) { + if (counter == 5) { + is(e.data, "あいうえお", "test-6 counter 5 data ok"); + ws.close(); + } else { + is(parseInt(e.data), counter+1, "bad counter"); + counter += 2; + ws.send(counter); + } + } + + ws.onclose = function(e) { + shouldCloseCleanly(e); + resolve(); + } + }); +} + +// test7: onmessage event origin property check +function test7() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://sub2.test2.example.org/tests/dom/base/test/file_websocket", "test-7"); + var gotmsg = false; + + ws.onopen = function() { + ok(true, "test 7 open"); + } + + ws.onmessage = function(e) { + ok(true, "test 7 message"); + is(e.origin, "ws://sub2.test2.example.org", "onmessage origin set to ws:// host"); + gotmsg = true; + ws.close(); + } + + ws.onclose = function(e) { + ok(gotmsg, "recvd message in test 7 before close"); + shouldCloseCleanly(e); + resolve(); + } + }); +} + +// test8: client calls close() and the server sends the close frame (with no +// code or reason) in acknowledgement; +function test8() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-8"); + + ws.onopen = function() { + is(ws.protocol, "test-8", "test-8 subprotocol selection"); + ws.close(); + } + + ws.onclose = function(e) { + shouldCloseCleanly(e); + // We called close() with no close code: so pywebsocket will also send no + // close code, which translates to code 1005 + is(e.code, 1005, "test-8 close code has wrong value:" + e.code); + is(e.reason, "", "test-8 close reason has wrong value:" + e.reason); + resolve(); + } + }); +} + +// test9: client closes the connection before the ws connection is established; +function test9() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://test2.example.org/tests/dom/base/test/file_websocket", "test-9"); + + ws._receivedErrorEvent = false; + + ws.onopen = shouldNotOpen; + + ws.onerror = function(e) { + ws._receivedErrorEvent = true; + } + + ws.onclose = function(e) { + ok(ws._receivedErrorEvent, "Didn't received the error event in test 9."); + shouldCloseNotCleanly(e); + resolve(); + } + + ws.close(); + }); +} + +// test10: client sends a message before the ws connection is established; +function test10() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://sub1.test1.example.com/tests/dom/base/test/file_websocket", "test-10"); + + ws.onclose = function(e) { + shouldCloseCleanly(e); + resolve(); + } + + try { + ws.send("client data"); + ok(false, "Couldn't send data before connecting!"); + } catch (e) { + ok(true, "Couldn't send data before connecting!"); + } + + ws.onopen = function() + { + ok(true, "test 10 opened"); + ws.close(); + } + }); +} + +// test11: a simple hello echo; +function test11() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-11"); + is(ws.readyState, 0, "create bad readyState in test-11!"); + + ws.onopen = function() { + is(ws.readyState, 1, "open bad readyState in test-11!"); + ws.send("client data"); + } + + ws.onmessage = function(e) { + is(e.data, "server data", "bad received message in test-11!"); + ws.close(1000, "Have a nice day"); + + // this ok() is disabled due to a race condition - it state may have + // advanced through 2 (closing) and into 3 (closed) before it is evald + // ok(ws.readyState == 2, "onmessage bad readyState in test-11!"); + } + + ws.onclose = function(e) { + is(ws.readyState, 3, "onclose bad readyState in test-11!"); + shouldCloseCleanly(e); + is(e.code, 1000, "test 11 got wrong close code: " + e.code); + is(e.reason, "Have a nice day", "test 11 got wrong close reason: " + e.reason); + resolve(); + } + }); +} + +// test12: client sends a message containing unpaired surrogates +function test12() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-12"); + + ws.onopen = function() { + try { + // send an unpaired surrogate + ws._gotMessage = false; + ws.send("a\ud800b"); + ok(true, "ok to send an unpaired surrogate"); + } catch (e) { + ok(false, "shouldn't fail any more when sending an unpaired surrogate!"); + } + } + + ws.onmessage = function(msg) { + is(msg.data, "SUCCESS", "Unpaired surrogate in UTF-16 not converted in test-12"); + ws._gotMessage = true; + // Must support unpaired surrogates in close reason, too + ws.close(1000, "a\ud800b"); + } + + ws.onclose = function(e) { + is(ws.readyState, 3, "onclose bad readyState in test-12!"); + ok(ws._gotMessage, "didn't receive message!"); + shouldCloseCleanly(e); + is(e.code, 1000, "test 12 got wrong close code: " + e.code); + is(e.reason, "a\ufffdb", "test 11 didn't get replacement char in close reason: " + e.reason); + resolve(); + } + }); +} + +// test13: server sends an invalid message; +function test13() { + return new Promise(function(resolve, reject) { + // previous versions of this test counted the number of protocol errors + // returned, but the protocol stack typically closes down after reporting a + // protocol level error - trying to resync is too dangerous + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-13"); + ws._timesCalledOnError = 0; + + ws.onerror = function() { + ws._timesCalledOnError++; + } + + ws.onclose = function(e) { + ok(ws._timesCalledOnError > 0, "no error events"); + resolve(); + } + }); +} + +// test14: server sends the close frame, it doesn't close the tcp connection +// and it keeps sending normal ws messages; +function test14() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-14"); + + ws.onmessage = function() { + ok(false, "shouldn't received message after the server sent the close frame"); + } + + ws.onclose = function(e) { + shouldCloseCleanly(e); + resolve(); + }; + }); +} + +// test15: server closes the tcp connection, but it doesn't send the close +// frame; +function test15() { + return new Promise(function(resolve, reject) { + /* + * DISABLED: see comments for test-15 case in file_websocket_wsh.py + */ + resolve(); + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-15"); + ws.onclose = function(e) { + shouldCloseNotCleanly(e); + resolve(); + } + + // termination of the connection might cause an error event if it happens in OPEN + ws.onerror = function() { + } + }); +} + +// test16: client calls close() and tries to send a message; +function test16() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-16"); + + ws.onopen = function() { + ws.close(); + ok(!ws.send("client data"), "shouldn't send message after calling close()"); + } + + ws.onmessage = function() { + ok(false, "shouldn't send message after calling close()"); + } + + ws.onerror = function() { + } + + ws.onclose = function() { + resolve(); + } + }); +} + +// test17: see bug 572975 - all event listeners set +function test17() { + return new Promise(function(resolve, reject) { + var status_test17 = "not started"; + + var test17func = function() { + var local_ws = new WebSocket("ws://sub1.test2.example.org/tests/dom/base/test/file_websocket", "test-17"); + status_test17 = "started"; + + local_ws.onopen = function(e) { + status_test17 = "opened"; + e.target.send("client data"); + forcegc(); + }; + + local_ws.onerror = function() { + ok(false, "onerror called on test " + current_test + "!"); + }; + + local_ws.onmessage = function(e) { + ok(e.data == "server data", "Bad message in test-17"); + status_test17 = "got message"; + forcegc(); + }; + + local_ws.onclose = function(e) { + ok(status_test17 == "got message", "Didn't got message in test-17!"); + shouldCloseCleanly(e); + status_test17 = "closed"; + forcegc(); + resolve(); + }; + + window._test17 = null; + forcegc(); + } + + window._test17 = test17func; + window._test17(); + }); +} + +// The tests that expects that their websockets neither open nor close MUST +// be in the end of the tests, i.e. HERE, in order to prevent blocking the other +// tests. + +// test18: client tries to connect to an http resource; +function test18() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket_http_resource.txt"); + ws.onopen = shouldNotOpen; + ws.onerror = ignoreError; + ws.onclose = function(e) + { + shouldCloseNotCleanly(e); + resolve(); + } + }); +} + +// test19: server closes the tcp connection before establishing the ws +// connection; +function test19() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-19"); + ws.onopen = shouldNotOpen; + ws.onerror = ignoreError; + ws.onclose = function(e) + { + shouldCloseNotCleanly(e); + resolve(); + } + }); +} + +// test20: see bug 572975 - only on error and onclose event listeners set +function test20() { + return new Promise(function(resolve, reject) { + var test20func = function() { + var local_ws = new WebSocket("ws://sub1.test1.example.org/tests/dom/base/test/file_websocket", "test-20"); + + local_ws.onerror = function() { + ok(false, "onerror called on test " + current_test + "!"); + } + + local_ws.onclose = function(e) { + ok(true, "test 20 closed despite gc"); + resolve(); + } + + local_ws = null; + window._test20 = null; + forcegc(); + } + + window._test20 = test20func; + window._test20(); + }); +} + +// test21: see bug 572975 - same as test 17, but delete strong event listeners +// when receiving the message event; +function test21() { + return new Promise(function(resolve, reject) { + var test21func = function() { + var local_ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-21"); + var received_message = false; + + local_ws.onopen = function(e) { + e.target.send("client data"); + forcegc(); + e.target.onopen = null; + forcegc(); + } + + local_ws.onerror = function() { + ok(false, "onerror called on test " + current_test + "!"); + } + + local_ws.onmessage = function(e) { + is(e.data, "server data", "Bad message in test-21"); + received_message = true; + forcegc(); + e.target.onmessage = null; + forcegc(); + } + + local_ws.onclose = function(e) { + shouldCloseCleanly(e); + ok(received_message, "close transitioned through onmessage"); + resolve(); + } + + local_ws = null; + window._test21 = null; + forcegc(); + } + + window._test21 = test21func; + window._test21(); + }); +} + +// test22: server takes too long to establish the ws connection; +function test22() { + return new Promise(function(resolve, reject) { + const pref_open = "network.websocket.timeout.open"; + SpecialPowers.setIntPref(pref_open, 5); + + var ws = CreateTestWS("ws://sub2.test2.example.org/tests/dom/base/test/file_websocket", "test-22"); + + ws.onopen = shouldNotOpen; + ws.onerror = ignoreError; + + ws.onclose = function(e) { + shouldCloseNotCleanly(e); + resolve(); + } + + SpecialPowers.clearUserPref(pref_open); + }); +} + +// test23: should detect WebSocket on window object; +function test23() { + return new Promise(function(resolve, reject) { + ok("WebSocket" in window, "WebSocket should be available on window object"); + resolve(); + }); +} + +// test24: server rejects sub-protocol string +function test24() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-does-not-exist"); + + ws.onopen = shouldNotOpen; + ws.onclose = function(e) { + shouldCloseNotCleanly(e); + resolve(); + } + + ws.onerror = function() { + } + }); +} + +// test25: ctor with valid empty sub-protocol array +function test25() { + return new Promise(function(resolve, reject) { + var prots=[]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + // This test errors because the server requires a sub-protocol, but + // the test just wants to ensure that the ctor doesn't generate an + // exception + ws.onerror = ignoreError; + ws.onopen = shouldNotOpen; + + ws.onclose = function(e) { + is(ws.protocol, "", "test25 subprotocol selection"); + ok(true, "test 25 protocol array close"); + resolve(); + } + }); +} + +// test26: ctor with invalid sub-protocol array containing 1 empty element +function test26() { + return new Promise(function(resolve, reject) { + var prots=[""]; + + try { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + ok(false, "testing empty element sub protocol array"); + } catch (e) { + ok(true, "testing empty sub element protocol array"); + } + + resolve(); + }); +} + +// test27: ctor with invalid sub-protocol array containing an empty element in +// list +function test27() { + return new Promise(function(resolve, reject) { + var prots=["test27", ""]; + + try { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + ok(false, "testing empty element mixed sub protocol array"); + } catch (e) { + ok(true, "testing empty element mixed sub protocol array"); + } + + resolve(); + }); +} + +// test28: ctor using valid 1 element sub-protocol array +function test28() { + return new Promise(function(resolve, reject) { + var prots=["test28"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 28 protocol array open"); + ws.close(); + } + + ws.onclose = function(e) { + is(ws.protocol, "test28", "test28 subprotocol selection"); + ok(true, "test 28 protocol array close"); + resolve(); + } + }); +} + +// test29: ctor using all valid 5 element sub-protocol array +function test29() { + return new Promise(function(resolve, reject) { + var prots=["test29a", "test29b"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 29 protocol array open"); + ws.close(); + } + + ws.onclose = function(e) { + ok(true, "test 29 protocol array close"); + resolve(); + } + }); +} + +// test30: ctor using valid 1 element sub-protocol array with element server +// will reject +function test30() { + return new Promise(function(resolve, reject) { + var prots=["test-does-not-exist"]; + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = shouldNotOpen; + + ws.onclose = function(e) { + shouldCloseNotCleanly(e); + resolve(); + } + + ws.onerror = function() { + } + }); +} + +// test31: ctor using valid 2 element sub-protocol array with 1 element server +// will reject and one server will accept +function test31() { + return new Promise(function(resolve, reject) { + var prots=["test-does-not-exist", "test31"]; + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 31 protocol array open"); + ws.close(); + } + + ws.onclose = function(e) { + is(ws.protocol, "test31", "test31 subprotocol selection"); + ok(true, "test 31 protocol array close"); + resolve(); + } + }); +} + +// test32: ctor using invalid sub-protocol array that contains duplicate items +function test32() { + return new Promise(function(resolve, reject) { + var prots=["test32","test32"]; + + try { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + ok(false, "testing duplicated element sub protocol array"); + } catch (e) { + ok(true, "testing duplicated sub element protocol array"); + } + + resolve(); + }); +} + +// test33: test for sending/receiving custom close code (but no close reason) +function test33() { + return new Promise(function(resolve, reject) { + var prots=["test33"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 33 open"); + ws.close(3131); // pass code but not reason + } + + ws.onclose = function(e) { + ok(true, "test 33 close"); + shouldCloseCleanly(e); + is(e.code, 3131, "test 33 got wrong close code: " + e.code); + is(e.reason, "", "test 33 got wrong close reason: " + e.reason); + resolve(); + } + }); +} + +// test34: test for receiving custom close code and reason +function test34() { + return new Promise(function(resolve, reject) { + var prots=["test-34"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 34 open"); + ws.close(); + } + + ws.onclose = function(e) + { + ok(true, "test 34 close"); + ok(e.wasClean, "test 34 closed cleanly"); + is(e.code, 1001, "test 34 custom server code"); + is(e.reason, "going away now", "test 34 custom server reason"); + resolve(); + } + }); +} + +// test35: test for sending custom close code and reason +function test35() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-35a"); + + ws.onopen = function(e) { + ok(true, "test 35a open"); + ws.close(3500, "my code"); + } + + ws.onclose = function(e) { + ok(true, "test 35a close"); + ok(e.wasClean, "test 35a closed cleanly"); + var wsb = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-35b"); + + wsb.onopen = function(e) { + ok(true, "test 35b open"); + wsb.close(); + } + + wsb.onclose = function(e) { + ok(true, "test 35b close"); + ok(e.wasClean, "test 35b closed cleanly"); + is(e.code, 3501, "test 35 custom server code"); + is(e.reason, "my code", "test 35 custom server reason"); + resolve(); + } + } + }); +} + +// test36: negative test for sending out of range close code +function test36() { + return new Promise(function(resolve, reject) { + var prots=["test-36"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 36 open"); + + try { + ws.close(13200); + ok(false, "testing custom close code out of range"); + } catch (e) { + ok(true, "testing custom close code out of range"); + ws.close(3200); + } + } + + ws.onclose = function(e) { + ok(true, "test 36 close"); + ok(e.wasClean, "test 36 closed cleanly"); + resolve(); + } + }); +} + +// test37: negative test for too long of a close reason +function test37() { + return new Promise(function(resolve, reject) { + var prots=["test-37"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 37 open"); + + try { + ws.close(3100,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"); + ok(false, "testing custom close reason out of range"); + } catch (e) { + ok(true, "testing custom close reason out of range"); + ws.close(3100,"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"); + } + } + + ws.onclose = function(e) { + ok(true, "test 37 close"); + ok(e.wasClean, "test 37 closed cleanly"); + + var wsb = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-37b"); + + wsb.onopen = function(e) { + // now test that a rejected close code and reason dont persist + ok(true, "test 37b open"); + try { + wsb.close(3101,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123"); + ok(false, "testing custom close reason out of range 37b"); + } catch (e) { + ok(true, "testing custom close reason out of range 37b"); + wsb.close(); + } + } + + wsb.onclose = function(e) { + ok(true, "test 37b close"); + ok(e.wasClean, "test 37b closed cleanly"); + + var wsc = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-37c"); + + wsc.onopen = function(e) { + ok(true, "test 37c open"); + wsc.close(); + } + + wsc.onclose = function(e) { + isnot(e.code, 3101, "test 37c custom server code not present"); + is(e.reason, "", "test 37c custom server reason not present"); + resolve(); + } + } + } + }); +} + +// test38: ensure extensions attribute is defined +function test38() { + return new Promise(function(resolve, reject) { + var prots=["test-38"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 38 open"); + isnot(ws.extensions, undefined, "extensions attribute defined"); + // is(ws.extensions, "deflate-stream", "extensions attribute deflate-stream"); + ws.close(); + } + + ws.onclose = function(e) { + ok(true, "test 38 close"); + resolve(); + } + }); +} + +// test39: a basic wss:// connectivity test +function test39() { + return new Promise(function(resolve, reject) { + var prots=["test-39"]; + + var ws = CreateTestWS("wss://example.com/tests/dom/base/test/file_websocket", prots); + status_test39 = "started"; + + ws.onopen = function(e) { + status_test39 = "opened"; + ok(true, "test 39 open"); + ws.close(); + } + + ws.onclose = function(e) { + ok(true, "test 39 close"); + is(status_test39, "opened", "test 39 did open"); + resolve(); + } + }); +} + +// test40: negative test for wss:// with no cert +function test40() { + return new Promise(function(resolve, reject) { + var prots=["test-40"]; + + var ws = CreateTestWS("wss://nocert.example.com/tests/dom/base/test/file_websocket", prots); + + status_test40 = "started"; + ws.onerror = ignoreError; + + ws.onopen = function(e) { + status_test40 = "opened"; + ok(false, "test 40 open"); + ws.close(); + } + + ws.onclose = function(e) { + ok(true, "test 40 close"); + is(status_test40, "started", "test 40 did not open"); + resolve(); + } + }); +} + +// test41: HSTS +function test41() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://example.com/tests/dom/base/test/file_websocket", "test-41a", 1); + + ws.onopen = function(e) { + ok(true, "test 41a open"); + is(ws.url, "ws://example.com/tests/dom/base/test/file_websocket", + "test 41a initial ws should not be redirected"); + ws.close(); + } + + ws.onclose = function(e) { + ok(true, "test 41a close"); + + // establish a hsts policy for example.com + var wsb = CreateTestWS("wss://example.com/tests/dom/base/test/file_websocket", "test-41b", 1); + + wsb.onopen = function(e) { + ok(true, "test 41b open"); + wsb.close(); + } + + wsb.onclose = function(e) { + ok(true, "test 41b close"); + + // try ws:// again, it should be done over wss:// now due to hsts + var wsc = CreateTestWS("ws://example.com/tests/dom/base/test/file_websocket", "test-41c"); + + wsc.onopen = function(e) { + ok(true, "test 41c open"); + is(wsc.url, "wss://example.com/tests/dom/base/test/file_websocket", + "test 41c ws should be redirected by hsts to wss"); + wsc.close(); + } + + wsc.onclose = function(e) { + ok(true, "test 41c close"); + + // clean up the STS state + const Ci = SpecialPowers.Ci; + var loadContext = SpecialPowers.wrap(window) + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsILoadContext); + var flags = 0; + if (loadContext.usePrivateBrowsing) + flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE; + SpecialPowers.cleanUpSTSData("http://example.com", flags); + resolve(); + } + } + } + }); +} + +// test42: non-char utf-8 sequences +function test42() { + return new Promise(function(resolve, reject) { + // test some utf-8 non-characters. They should be allowed in the + // websockets context. Test via round trip echo. + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-42"); + var data = ["U+FFFE \ufffe", + "U+FFFF \uffff", + "U+10FFFF \udbff\udfff"]; + var index = 0; + + ws.onopen = function() { + ws.send(data[0]); + ws.send(data[1]); + ws.send(data[2]); + } + + ws.onmessage = function(e) { + is(e.data, data[index], "bad received message in test-42! index="+index); + index++; + if (index == 3) { + ws.close(); + } + } + + ws.onclose = function(e) { + resolve(); + } + }); +} + +// test43: Test setting binaryType attribute +function test43() { + return new Promise(function(resolve, reject) { + var prots=["test-43"]; + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", prots); + + ws.onopen = function(e) { + ok(true, "test 43 open"); + // Test binaryType setting + ws.binaryType = "arraybuffer"; + ws.binaryType = "blob"; + ws.binaryType = ""; // illegal + is(ws.binaryType, "blob"); + ws.binaryType = "ArrayBuffer"; // illegal + is(ws.binaryType, "blob"); + ws.binaryType = "Blob"; // illegal + is(ws.binaryType, "blob"); + ws.binaryType = "mcfoofluu"; // illegal + is(ws.binaryType, "blob"); + ws.close(); + } + + ws.onclose = function(e) { + ok(true, "test 43 close"); + resolve(); + } + }); +} + +// test44: Test sending/receving binary ArrayBuffer +function test44() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-44"); + is(ws.readyState, 0, "bad readyState in test-44!"); + ws.binaryType = "arraybuffer"; + + ws.onopen = function() { + is(ws.readyState, 1, "open bad readyState in test-44!"); + var buf = new ArrayBuffer(3); + // create byte view + var view = new Uint8Array(buf); + view[0] = 5; + view[1] = 0; // null byte + view[2] = 7; + ws.send(buf); + } + + ws.onmessage = function(e) { + ok(e.data instanceof ArrayBuffer, "Should receive an arraybuffer!"); + var view = new Uint8Array(e.data); + ok(view.length == 2 && view[0] == 0 && view[1] ==4, "testing Reply arraybuffer" ); + ws.close(); + } + + ws.onclose = function(e) { + is(ws.readyState, 3, "onclose bad readyState in test-44!"); + shouldCloseCleanly(e); + resolve(); + } + }); +} + +// test45: Test sending/receving binary Blob +function test45() { + return new Promise(function(resolve, reject) { + function test45Real(blobFile) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-45"); + is(ws.readyState, 0, "bad readyState in test-45!"); + // ws.binaryType = "blob"; // Don't need to specify: blob is the default + + ws.onopen = function() { + is(ws.readyState, 1, "open bad readyState in test-45!"); + ws.send(blobFile); + } + + var test45blob; + + ws.onmessage = function(e) { + test45blob = e.data; + ok(test45blob instanceof Blob, "We should be receiving a Blob"); + + ws.close(); + } + + ws.onclose = function(e) { + is(ws.readyState, 3, "onclose bad readyState in test-45!"); + shouldCloseCleanly(e); + + // check blob contents + var reader = new FileReader(); + reader.onload = function(event) { + is(reader.result, "flob", "response should be 'flob': got '" + + reader.result + "'"); + } + + reader.onerror = function(event) { + testFailed("Failed to read blob: error code = " + reader.error.code); + } + + reader.onloadend = function(event) { + resolve(); + } + + reader.readAsBinaryString(test45blob); + } + } + + SpecialPowers.createFiles([{name: "testBlobFile", data: "flob"}], + function(files) { + test45Real(files[0]); + }, + function(msg) { + testFailed("Failed to create file for test45: " + msg); + resolve(); + }); + }); +} + +// test46: Test that we don't dispatch incoming msgs once in CLOSING state +function test46() { + return new Promise(function(resolve, reject) { + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-46"); + is(ws.readyState, 0, "create bad readyState in test-46!"); + + ws.onopen = function() { + is(ws.readyState, 1, "open bad readyState in test-46!"); + ws.close() + is(ws.readyState, 2, "close must set readyState to 2 in test-46!"); + } + + ws.onmessage = function(e) { + ok(false, "received message after calling close in test-46!"); + } + + ws.onclose = function(e) { + is(ws.readyState, 3, "onclose bad readyState in test-46!"); + shouldCloseCleanly(e); + resolve(); + } + }); +} + +// test47: Make sure onerror/onclose aren't called during close() +function test47() { + return new Promise(function(resolve, reject) { + var hasError = false; + var ws = CreateTestWS("ws://another.websocket.server.that.probably.does.not.exist"); + + ws.onopen = shouldNotOpen; + + ws.onerror = function (e) { + is(ws.readyState, 3, "test-47: readyState should be CLOSED(3) in onerror: got " + + ws.readyState); + ok(!ws._withinClose, "onerror() called during close()!"); + hasError = true; + } + + ws.onclose = function(e) { + shouldCloseNotCleanly(e); + ok(hasError, "test-47: should have called onerror before onclose"); + is(ws.readyState, 3, "test-47: readyState should be CLOSED(3) in onclose: got " + + ws.readyState); + ok(!ws._withinClose, "onclose() called during close()!"); + is(e.code, 1006, "test-47 close code should be 1006 but is:" + e.code); + resolve(); + } + + // Call close before we're connected: throws error + // Make sure we call onerror/onclose asynchronously + ws._withinClose = 1; + ws.close(3333, "Closed before we were open: error"); + ws._withinClose = 0; + is(ws.readyState, 2, "test-47: readyState should be CLOSING(2) after close(): got " + + ws.readyState); + }); +} + +// test48: see bug 1227136 - client calls close() from onopen() and waits until +// WebSocketChannel::mSocketIn is nulled out on socket thread. +function test48() { + return new Promise(function(resolve, reject) { + const pref_close = "network.websocket.timeout.close"; + SpecialPowers.setIntPref(pref_close, 1); + + var ws = CreateTestWS("ws://mochi.test:8888/tests/dom/base/test/file_websocket", "test-48"); + + ws.onopen = function() { + ws.close(); + + var date = new Date(); + var curDate = null; + do { + curDate = new Date(); + } while(curDate-date < 1500); + + } + + ws.onclose = function(e) { + ok(true, "ws close in test 48"); + resolve(); + } + + SpecialPowers.clearUserPref(pref_close); + }); +} diff --git a/dom/base/test/wholeTexty-helper.xml b/dom/base/test/wholeTexty-helper.xml new file mode 100644 index 0000000000..779a54c8b4 --- /dev/null +++ b/dom/base/test/wholeTexty-helper.xml @@ -0,0 +1,6 @@ +<?xml version="1.0"?> +<!DOCTYPE document + [ + <!ENTITY foobar "baz<quux/>"> + ]> +<document><![CDATA[]]><entity>&foobar;</entity></document> diff --git a/dom/base/test/worker_postMessages.js b/dom/base/test/worker_postMessages.js new file mode 100644 index 0000000000..968ec209a2 --- /dev/null +++ b/dom/base/test/worker_postMessages.js @@ -0,0 +1,33 @@ +function test_workers() { + onmessage = function(e) { + postMessage(e.data, e.ports); + } +} + +function test_broadcastChannel() { + var bc = new BroadcastChannel('postMessagesTest_inWorkers'); + bc.onmessage = function(e) { + postMessage(e.data); + } +} + +function test_messagePort(port) { + port.onmessage = function(e) { + postMessage(e.data, e.ports); + } +} + +onmessage = function(e) { + if (e.data == 'workers') { + test_workers(); + postMessage('ok'); + } else if (e.data == 'broadcastChannel') { + test_broadcastChannel(); + postMessage('ok'); + } else if (e.data == 'messagePort') { + test_messagePort(e.ports[0]); + postMessage('ok'); + } else { + postMessage('ko'); + } +} |