michael@0: /* vim: set ts=2 et sw=2 tw=80: */
michael@0: /* Any copyright is dedicated to the Public Domain.
michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0:
michael@0: "use strict";
michael@0:
michael@0: // Tests that various mutations to the dom update the markup view correctly.
michael@0: // The test for comparing the markup view to the real dom is a bit weird:
michael@0: // - Select the text in the markup view
michael@0: // - Parse that as innerHTML in a document we've created for the purpose.
michael@0: // - Remove extraneous whitespace in that tree
michael@0: // - Compare it to the real dom with isEqualNode.
michael@0:
michael@0: const TEST_URL = TEST_URL_ROOT + "doc_markup_mutation.html";
michael@0: // All the mutation types we want to test.
michael@0: const TEST_DATA = [
michael@0: {
michael@0: desc: "Adding an attribute",
michael@0: test: () => {
michael@0: let node1 = getNode("#node1");
michael@0: node1.setAttribute("newattr", "newattrval");
michael@0: }
michael@0: },
michael@0: {
michael@0: desc: "Removing an attribute",
michael@0: test: () => {
michael@0: let node1 = getNode("#node1");
michael@0: node1.removeAttribute("newattr");
michael@0: }
michael@0: },
michael@0: {
michael@0: desc: "Updating the text-content",
michael@0: test: () => {
michael@0: let node1 = getNode("#node1");
michael@0: node1.textContent = "newtext";
michael@0: }
michael@0: },
michael@0: {
michael@0: desc: "Updating the innerHTML",
michael@0: test: () => {
michael@0: let node2 = getNode("#node2");
michael@0: node2.innerHTML = "
foo
";
michael@0: }
michael@0: },
michael@0: {
michael@0: desc: "Removing child nodes",
michael@0: test: () => {
michael@0: let node4 = getNode("#node4");
michael@0: while (node4.firstChild) {
michael@0: node4.removeChild(node4.firstChild);
michael@0: }
michael@0: }
michael@0: },
michael@0: {
michael@0: desc: "Appending a child to a different parent",
michael@0: test: () => {
michael@0: let node17 = getNode("#node17");
michael@0: let node1 = getNode("#node2");
michael@0: node1.appendChild(node17);
michael@0: }
michael@0: },
michael@0: {
michael@0: desc: "Swapping a parent and child element, putting them in the same tree",
michael@0: // body
michael@0: // node1
michael@0: // node18
michael@0: // node19
michael@0: // node20
michael@0: // node21
michael@0: // will become:
michael@0: // body
michael@0: // node1
michael@0: // node20
michael@0: // node21
michael@0: // node18
michael@0: // node19
michael@0: test: () => {
michael@0: let node18 = getNode("#node18");
michael@0: let node20 = getNode("#node20");
michael@0:
michael@0: let node1 = getNode("#node1");
michael@0:
michael@0: node1.appendChild(node20);
michael@0: node20.appendChild(node18);
michael@0: }
michael@0: }
michael@0: ];
michael@0:
michael@0: let test = asyncTest(function*() {
michael@0: info("Creating the helper tab for parsing");
michael@0: let parseTab = yield addTab("data:text/html,");
michael@0: let parseDoc = content.document;
michael@0:
michael@0: info("Creating the test tab");
michael@0: let contentTab = yield addTab(TEST_URL);
michael@0: let doc = content.document;
michael@0: // Strip whitespace in the document for easier comparison
michael@0: stripWhitespace(doc.documentElement);
michael@0:
michael@0: let {inspector} = yield openInspector();
michael@0: let markup = inspector.markup;
michael@0:
michael@0: info("Expanding all markup-view nodes");
michael@0: yield markup.expandAll();
michael@0:
michael@0: for (let step of TEST_DATA) {
michael@0: info("Starting test: " + step.desc);
michael@0:
michael@0: info("Executing the test markup mutation, listening for inspector-updated before moving on");
michael@0: let updated = inspector.once("inspector-updated");
michael@0: step.test();
michael@0: yield updated;
michael@0:
michael@0: info("Expanding all markup-view nodes to make sure new nodes are imported");
michael@0: yield markup.expandAll();
michael@0:
michael@0: info("Comparing the markup-view markup with the content document");
michael@0: compareMarkup(parseDoc, inspector);
michael@0: }
michael@0: });
michael@0:
michael@0: function stripWhitespace(node) {
michael@0: node.normalize();
michael@0: let iter = node.ownerDocument.createNodeIterator(node,
michael@0: NodeFilter.SHOW_TEXT + NodeFilter.SHOW_COMMENT, null);
michael@0:
michael@0: while ((node = iter.nextNode())) {
michael@0: node.nodeValue = node.nodeValue.replace(/\s+/g, '');
michael@0: if (node.nodeType == Node.TEXT_NODE &&
michael@0: !/[^\s]/.exec(node.nodeValue)) {
michael@0: node.parentNode.removeChild(node);
michael@0: }
michael@0: }
michael@0: }
michael@0:
michael@0: function compareMarkup(parseDoc, inspector) {
michael@0: // Grab the text from the markup panel...
michael@0: let markupContainerEl = getContainerForRawNode("body", inspector).elt;
michael@0: let sel = markupContainerEl.ownerDocument.defaultView.getSelection();
michael@0: sel.selectAllChildren(markupContainerEl);
michael@0:
michael@0: // Parse it
michael@0: let parseNode = parseDoc.querySelector("body");
michael@0: parseNode.outerHTML = sel;
michael@0: parseNode = parseDoc.querySelector("body");
michael@0:
michael@0: // Pull whitespace out of text and comment nodes, there will
michael@0: // be minor unimportant differences.
michael@0: stripWhitespace(parseNode);
michael@0:
michael@0: // console.log(contentNode.innerHTML, parseNode.innerHTML);
michael@0: ok(getNode("body").isEqualNode(parseNode),
michael@0: "Markup panel matches what's in the content document.");
michael@0: }