B2G/gecko/browser/devtools/markupview/test/browser_inspector_markup_mutation.js
/**
 * Tests that various mutations to the dom update the markup tool correctly.
 * The test for comparing the markup tool to the real dom is a bit weird:
 * - Select the text in the markup tool
 * - Parse that as innerHTML in a document we've created for the purpose.
 * - Remove extraneous whitespace in that tree
 * - Compare it to the real dom with isEqualNode.
 */
Tests that various mutations to the dom update the markup tool correctly.
The test for comparing the markup tool to the real dom is a bit weird:
- Select the text in the markup tool
- Parse that as innerHTML in a document we've created for the purpose.
- Remove extraneous whitespace in that tree
- Compare it to the real dom with isEqualNode.
Tests that various mutations to the dom update the markup tool correctly . The test for comparing the markup tool to the real dom is a bit weird : - Select the text in the markup tool - Parse that as innerHTML in a document we ' ve created for the purpose . - Remove extraneous whitespace in that tree - Compare it to the real dom with isEqualNode .
function test() {
  waitForExplicitFinish();
  let contentTab;
  let doc;
  let markup;
  let parseTab;
  let parseDoc;
  function stripWhitespace(node)
  {
    node.normalize();
    let iter = node.ownerDocument.createNodeIterator(node, NodeFilter.SHOW_TEXT + NodeFilter.SHOW_COMMENT,
      null, false);
    while ((node = iter.nextNode())) {
      node.nodeValue = node.nodeValue.replace(/\s+/g, '');
      if (node.nodeType == Node.TEXT_NODE &&
        !/[^\s]/.exec(node.nodeValue)) {
        node.parentNode.removeChild(node);
      }
    }
  }
  function checkMarkup()
  {
    markup.expandAll();
    let contentNode = doc.querySelector("body");
    let panelNode = markup._containers.get(contentNode).elt;
    let parseNode = parseDoc.querySelector("body");
    let sel = panelNode.ownerDocument.defaultView.getSelection();
    sel.selectAllChildren(panelNode);
    parseNode.outerHTML = sel;
    parseNode = parseDoc.querySelector("body");
    stripWhitespace(parseNode);
    ok(contentNode.isEqualNode(parseNode), "Markup panel should match document.");
  }
  let mutations = [
    function() {
      let node1 = doc.querySelector("#node1");
      node1.setAttribute("newattr", "newattrval");
    },
    function() {
      let node1 = doc.querySelector("#node1");
      node1.removeAttribute("newattr");
    },
    function() {
      let node1 = doc.querySelector("#node1");
      node1.textContent = "newtext";
    },
    function() {
      let node2 = doc.querySelector("#node2");
      node2.innerHTML = "<div><span>foo</span></div>";
    },
    function() {
      let node4 = doc.querySelector("#node4");
      while (node4.firstChild) {
        node4.removeChild(node4.firstChild);
      }
    },
    function() {
      let node17 = doc.querySelector("#node17");
      let node1 = doc.querySelector("#node2");
      node1.appendChild(node17);
    },
    function() {
      8
      let node18 = doc.querySelector("#node18");
      let node20 = doc.querySelector("#node20");
      let node1 = doc.querySelector("#node1");
      node1.appendChild(node20);
      node20.appendChild(node18);
    },
  ];
  parseTab = gBrowser.selectedTab = gBrowser.addTab();
  gBrowser.selectedBrowser.addEventListener("load", function onload() {
    gBrowser.selectedBrowser.removeEventListener("load", onload, true);
    parseDoc = content.document;
    contentTab = gBrowser.selectedTab = gBrowser.addTab();
    gBrowser.selectedBrowser.addEventListener("load", function onload2() {
      gBrowser.selectedBrowser.removeEventListener("load", onload2, true);
      doc = content.document;
      stripWhitespace(doc.documentElement);
      waitForFocus(setupTest, content);
    }, true);
    content.location = "http://mochi.test:8888/browser/browser/devtools/markupview/test/browser_inspector_markup_mutation.html";
  }, true);
  content.location = "data:text/html,<html></html>";
  function setupTest() {
    Services.obs.addObserver(runTests, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
    InspectorUI.toggleInspectorUI();
  }
  function runTests() {
    Services.obs.removeObserver(runTests, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED);
    InspectorUI.currentInspector.once("markuploaded", startTests);
    InspectorUI.select(doc.body, true, true, true);
    InspectorUI.stopInspecting();
    InspectorUI.toggleHTMLPanel();
  }
  function startTests() {
    markup = InspectorUI.currentInspector.markup;
    checkMarkup();
    nextStep(0);
  }
  function nextStep(cursor) {
    if (cursor >= mutations.length) {
      Services.obs.addObserver(finishUp, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED, false);
      InspectorUI.closeInspectorUI();
      return;
    }
    mutations[cursor]();
    InspectorUI.currentInspector.once("markupmutation", function() {
      executeSoon(function() {
        checkMarkup();
        nextStep(cursor + 1);
      });
    });
  }
  function finishUp() {
    Services.obs.removeObserver(finishUp, InspectorUI.INSPECTOR_NOTIFICATIONS.CLOSED);
    doc = null;
    gBrowser.removeTab(contentTab);
    gBrowser.removeTab(parseTab);
    finish();
  }
}
function test ( ) { waitForExplicitFinish ( ) ; let contentTab ; let doc ; let markup ; let parseTab ; let parseDoc ; function stripWhitespace ( node ) { node . normalize ( ) ; let iter = node . ownerDocument . createNodeIterator ( node , NodeFilter . SHOW_TEXT + NodeFilter . SHOW_COMMENT , null , false ) ; while ( ( node = iter . nextNode ( ) ) ) { node . nodeValue = node . nodeValue . replace ( / \s+ / g , '' ) ; if ( node . nodeType == Node . TEXT_NODE && ! / [^\s] / . exec ( node . nodeValue ) ) { node . parentNode . removeChild ( node ) ; } } } function checkMarkup ( ) { markup . expandAll ( ) ; let contentNode = doc . querySelector ( "body" ) ; let panelNode = markup . _containers . get ( contentNode ) . elt ; let parseNode = parseDoc . querySelector ( "body" ) ; let sel = panelNode . ownerDocument . defaultView . getSelection ( ) ; sel . selectAllChildren ( panelNode ) ; parseNode . outerHTML = sel ; parseNode = parseDoc . querySelector ( "body" ) ; stripWhitespace ( parseNode ) ; ok ( contentNode . isEqualNode ( parseNode ) , "Markup panel should match document." ) ; } let mutations = [ function ( ) { let node1 = doc . querySelector ( "#node1" ) ; node1 . setAttribute ( "newattr" , "newattrval" ) ; } , function ( ) { let node1 = doc . querySelector ( "#node1" ) ; node1 . removeAttribute ( "newattr" ) ; } , function ( ) { let node1 = doc . querySelector ( "#node1" ) ; node1 . textContent = "newtext" ; } , function ( ) { let node2 = doc . querySelector ( "#node2" ) ; node2 . innerHTML = "<div><span>foo</span></div>" ; } , function ( ) { let node4 = doc . querySelector ( "#node4" ) ; while ( node4 . firstChild ) { node4 . removeChild ( node4 . firstChild ) ; } } , function ( ) { let node17 = doc . querySelector ( "#node17" ) ; let node1 = doc . querySelector ( "#node2" ) ; node1 . appendChild ( node17 ) ; } , function ( ) { let node18 = doc . querySelector ( "#node18" ) ; let node20 = doc . querySelector ( "#node20" ) ; let node1 = doc . querySelector ( "#node1" ) ; node1 . appendChild ( node20 ) ; node20 . appendChild ( node18 ) ; } , ] ; parseTab = gBrowser . selectedTab = gBrowser . addTab ( ) ; gBrowser . selectedBrowser . addEventListener ( "load" , function onload ( ) { gBrowser . selectedBrowser . removeEventListener ( "load" , onload , true ) ; parseDoc = content . document ; contentTab = gBrowser . selectedTab = gBrowser . addTab ( ) ; gBrowser . selectedBrowser . addEventListener ( "load" , function onload2 ( ) { gBrowser . selectedBrowser . removeEventListener ( "load" , onload2 , true ) ; doc = content . document ; stripWhitespace ( doc . documentElement ) ; waitForFocus ( setupTest , content ) ; } , true ) ; content . location = "http://mochi.test:8888/browser/browser/devtools/markupview/test/browser_inspector_markup_mutation.html" ; } , true ) ; content . location = "data:text/html,<html></html>" ; function setupTest ( ) { Services . obs . addObserver ( runTests , InspectorUI . INSPECTOR_NOTIFICATIONS . OPENED , false ) ; InspectorUI . toggleInspectorUI ( ) ; } function runTests ( ) { Services . obs . removeObserver ( runTests , InspectorUI . INSPECTOR_NOTIFICATIONS . OPENED ) ; InspectorUI . currentInspector . once ( "markuploaded" , startTests ) ; InspectorUI . select ( doc . body , true , true , true ) ; InspectorUI . stopInspecting ( ) ; InspectorUI . toggleHTMLPanel ( ) ; } function startTests ( ) { markup = InspectorUI . currentInspector . markup ; checkMarkup ( ) ; nextStep ( 0 ) ; } function nextStep ( cursor ) { if ( cursor >= mutations . length ) { Services . obs . addObserver ( finishUp , InspectorUI . INSPECTOR_NOTIFICATIONS . CLOSED , false ) ; InspectorUI . closeInspectorUI ( ) ; return ; } mutations [ cursor ] ( ) ; InspectorUI . currentInspector . once ( "markupmutation" , function ( ) { executeSoon ( function ( ) { checkMarkup ( ) ; nextStep ( cursor + 1 ) ; } ) ; } ) ; } function finishUp ( ) { Services . obs . removeObserver ( finishUp , InspectorUI . INSPECTOR_NOTIFICATIONS . CLOSED ) ; doc = null ; gBrowser . removeTab ( contentTab ) ; gBrowser . removeTab ( parseTab ) ; finish ( ) ; } }
Tests that various mutations to the dom update the markup tool correctly.
Tests that various mutations to the dom update the markup tool correctly .
// Will hold the doc we're viewing // Holds the MarkupTool object we're testing. // Holds the document we use to help re-parse the markup tool's output. // Strip whitespace from a node and its children. // Verify that the markup in the tool is the same as the markup in the document. // Grab the text from the markup panel... // Parse it // Pull whitespace out of text and comment nodes, there will // be minor unimportant differences. // All the mutation types we want to test. // Add an attribute // Move a child to a new parent. // Swap a parent and child element, putting them in the same tree. // body //  node1 //  node18 //    node19 //      node20 //        node21 // will become: // body //   node1 //     node20 //      node21 //      node18 //        node19 // Create the helper tab for parsing... // Then create the actual dom we're inspecting... // Strip whitespace from the doc for easier comparison.