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: }