DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (6663d3dc883b)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
<!DOCTYPE HTML>
<html><head>
<title>Test for bug 525389</title>
<style src="/tests/SimpleTest/test.css" type="text/css"></style>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>

<script class="testbody" type="application/javascript">

  var utils = SpecialPowers.getDOMWindowUtils(window);
  var Cc = SpecialPowers.Cc;
  var Ci = SpecialPowers.Ci;

function getLoadContext() {
  return SpecialPowers.wrap(window).docShell.QueryInterface(Ci.nsILoadContext);
}

async function runTest() {
  var pasteCount = 0;
  var pasteFunc = function(event) { pasteCount++; };

  function verifyContent(s) {
    var e = document.getElementById("i1");
    var doc = e.contentDocument;
    if (navigator.platform.includes("Win")) {
      // On Windows ignore \n which got left over from the removal of the fragment tags
      // <html><body>\n<!--StartFragment--> and <!--EndFragment-->\n</body>\n</html>.
      is(doc.body.innerHTML.replace(/\n/g, ""), s, "");
    } else {
      is(doc.body.innerHTML, s, "");
    }
  }

  function pasteInto(trans, html, target_id) {
    var e = document.getElementById("i1");
    var doc = e.contentDocument;
    doc.designMode = "on";
    doc.body.innerHTML = html;
    doc.defaultView.focus();
    if (target_id)
      e = doc.getElementById(target_id);
    else
      e = doc.body;
    var selection = doc.defaultView.getSelection();
    selection.removeAllRanges();
    selection.selectAllChildren(e);
    selection.collapseToEnd();

    pasteCount = 0;
    e.addEventListener("paste", pasteFunc);
    utils.sendContentCommandEvent("pasteTransferable", trans);
    e.removeEventListener("paste", pasteFunc);

    return e;
  }

  function getTransferableFromClipboard(asHTML) {
    var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
    trans.init(getLoadContext());
    if (asHTML) {
      trans.addDataFlavor("text/html");
    } else {
      trans.addDataFlavor("text/unicode");
    }
    var clip = SpecialPowers.Services.clipboard;
    clip.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
    return trans;
  }

  // Commented out as the test for it below is also commented out.
  // function makeTransferable(s, asHTML, target_id) {
  //   var e = document.getElementById("i2");
  //   var doc = e.contentDocument;
  //   if (asHTML) {
  //     doc.body.innerHTML = s;
  //   } else {
  //     var text = doc.createTextNode(s);
  //     doc.body.appendChild(text);
  //   }
  //   doc.designMode = "on";
  //   doc.defaultView.focus();
  //   var selection = doc.defaultView.getSelection();
  //   selection.removeAllRanges();
  //   if (!target_id) {
  //     selection.selectAllChildren(doc.body);
  //   } else {
  //     var range = document.createRange();
  //     range.selectNode(doc.getElementById(target_id));
  //     selection.addRange(range);
  //   }
  //
  //   // We cannot use plain strings, we have to use nsSupportsString.
  //   var supportsStringClass = SpecialPowers.Components.classes["@mozilla.org/supports-string;1"];
  //   var ssData = supportsStringClass.createInstance(Ci.nsISupportsString);
  //
  //   // Create the transferable.
  //   var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
  //   trans.init(getLoadContext());
  //
  //   // Add the data to the transferable.
  //   if (asHTML) {
  //     trans.addDataFlavor("text/html");
  //     ssData.data = doc.body.innerHTML;
  //     trans.setTransferData("text/html", ssData, ssData.length * 2);
  //   } else {
  //     trans.addDataFlavor("text/unicode");
  //     ssData.data = doc.body.innerHTML;
  //     trans.setTransferData("text/unicode", ssData, ssData.length * 2);
  //   }
  //
  //   return trans;
  // }

  async function copyToClipBoard(s, asHTML, target_id) {
    var e = document.getElementById("i2");
    var doc = e.contentDocument;
    if (asHTML) {
      doc.body.innerHTML = s;
    } else {
      var text = doc.createTextNode(s);
      doc.body.appendChild(text);
    }
    doc.designMode = "on";
    doc.defaultView.focus();
    var selection = doc.defaultView.getSelection();
    selection.removeAllRanges();
    if (!target_id) {
      selection.selectAllChildren(doc.body);
    } else {
      var range = document.createRange();
      range.selectNode(doc.getElementById(target_id));
      selection.addRange(range);
    }

    await SimpleTest.promiseClipboardChange(() => true,
      () => { SpecialPowers.wrap(doc).execCommand("copy", false, null); });

    return e;
  }

  await copyToClipBoard("<span>Hello</span><span>Kitty</span>", true);
  var trans = getTransferableFromClipboard(true);
  pasteInto(trans, "");
  verifyContent("<span>Hello</span><span>Kitty</span>");
  is(pasteCount, 1, "paste event was not triggered");

  // this test is not working out exactly like the clipboard test
  // has to do with generating the nsITransferable above
  // trans = makeTransferable('<span>Hello</span><span>Kitty</span>', true);
  // pasteInto(trans, '');
  // verifyContent('<span>Hello</span><span>Kitty</span>');

  await copyToClipBoard("<dl><dd>Hello Kitty</dd></dl><span>Hello</span><span>Kitty</span>", true);
  trans = getTransferableFromClipboard(true);
  pasteInto(trans, '<ol><li id="paste_here">X</li></ol>', "paste_here");
  verifyContent('<ol><li id="paste_here">X<dl><dd>Hello Kitty</dd></dl><span>Hello</span><span>Kitty</span></li></ol>');
  is(pasteCount, 1, "paste event was not triggered");

// The following test doesn't do what I expected, because the special handling
// of IsList nodes in nsHTMLEditor::InsertHTMLWithContext simply removes
// non-list/item children.  See bug 481177.
//  await copyToClipBoard("<ol><li>Hello Kitty</li><span>Hello</span></ol>", true);
//  pasteInto('<ol><li id="paste_here">X</li></ol>',"paste_here");
//  verifyContent('<ol><li id="paste_here">X</li><li>Hello Kitty</li><span>Hello</span></ol>');

  await copyToClipBoard("<pre>Kitty</pre><span>Hello</span>", true);
  trans = getTransferableFromClipboard(true);
  pasteInto(trans, '<pre id="paste_here">Hello </pre>', "paste_here");
  verifyContent('<pre id="paste_here">Hello Kitty<span>Hello</span></pre>');
  is(pasteCount, 1, "paste event was not triggered");

  await copyToClipBoard('1<span style="display: contents">2</span>3', true);
  trans = getTransferableFromClipboard(true);
  pasteInto(trans, '<div id="paste_here"></div>', "paste_here");
  verifyContent('<div id="paste_here">1<span style="display: contents">2</span>3</div>');
  is(pasteCount, 1, "paste event was not triggered");

  // test that we can preventDefault pastes
  pasteFunc = function(event) { event.preventDefault(); return false; };
  await copyToClipBoard("<pre>Kitty</pre><span>Hello</span>", true);
  trans = getTransferableFromClipboard(true);
  pasteInto(trans, '<pre id="paste_here">Hello </pre>', "paste_here");
  verifyContent('<pre id="paste_here">Hello </pre>');
  is(pasteCount, 0, "paste event was triggered");
}

SimpleTest.waitForExplicitFinish();
addLoadEvent(() => {
  add_task(async function test_copy() {
    await runTest();
  });
});

</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=525389">Mozilla Bug 525389</a>
<p id="display"></p>

<pre id="test">
</pre>

<iframe id="i1" width="200" height="100" src="about:blank"></iframe><br>
<iframe id="i2" width="200" height="100" src="about:blank"></iframe><br>

</body>
</html>