summaryrefslogtreecommitdiffstats
path: root/editor/libeditor
diff options
context:
space:
mode:
Diffstat (limited to 'editor/libeditor')
-rw-r--r--editor/libeditor/HTMLEditorDataTransfer.cpp31
-rw-r--r--editor/libeditor/tests/mochitest.ini3
-rw-r--r--editor/libeditor/tests/test_bug1306532.html64
3 files changed, 82 insertions, 16 deletions
diff --git a/editor/libeditor/HTMLEditorDataTransfer.cpp b/editor/libeditor/HTMLEditorDataTransfer.cpp
index b9cd8adb9..ed350c0dd 100644
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -2382,27 +2382,26 @@ HTMLEditor::ReplaceOrphanedStructure(
}
// If we found substructure, paste it instead of its descendants.
- // Only replace with the substructure if all the nodes in the list are
- // descendants.
- bool shouldReplaceNodes = true;
- for (uint32_t i = 0; i < aNodeArray.Length(); i++) {
+ // Postprocess list to remove any descendants of this node so that we don't
+ // insert them twice.
+ uint32_t removedCount = 0;
+ uint32_t originalLength = aNodeArray.Length();
+ for (uint32_t i = 0; i < originalLength; i++) {
uint32_t idx = aStartOrEnd == StartOrEnd::start ?
- i : (aNodeArray.Length() - i - 1);
+ (i - removedCount) : (originalLength - i - 1);
OwningNonNull<nsINode> endpoint = aNodeArray[idx];
- if (!EditorUtils::IsDescendantOf(endpoint, replaceNode)) {
- shouldReplaceNodes = false;
- break;
+ if (endpoint == replaceNode ||
+ EditorUtils::IsDescendantOf(endpoint, replaceNode)) {
+ aNodeArray.RemoveElementAt(idx);
+ removedCount++;
}
}
- if (shouldReplaceNodes) {
- // Now replace the removed nodes with the structural parent
- aNodeArray.Clear();
- if (aStartOrEnd == StartOrEnd::end) {
- aNodeArray.AppendElement(*replaceNode);
- } else {
- aNodeArray.InsertElementAt(0, *replaceNode);
- }
+ // Now replace the removed nodes with the structural parent
+ if (aStartOrEnd == StartOrEnd::end) {
+ aNodeArray.AppendElement(*replaceNode);
+ } else {
+ aNodeArray.InsertElementAt(0, *replaceNode);
}
}
diff --git a/editor/libeditor/tests/mochitest.ini b/editor/libeditor/tests/mochitest.ini
index 9aafa0ac2..4df3f606b 100644
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -217,6 +217,9 @@ skip-if = toolkit == 'android'
[test_bug1258085.html]
[test_bug1268736.html]
[test_bug1270235.html]
+[test_bug1306532.html]
+subsuite = clipboard
+skip-if = toolkit == 'android'
[test_bug1310912.html]
skip-if = toolkit == 'android' # bug 1315898
[test_bug1314790.html]
diff --git a/editor/libeditor/tests/test_bug1306532.html b/editor/libeditor/tests/test_bug1306532.html
new file mode 100644
index 000000000..1d7b3e7af
--- /dev/null
+++ b/editor/libeditor/tests/test_bug1306532.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<html><head>
+<title>Test for bug 1306532</title>
+<style src="/tests/SimpleTest/test.css" type="text/css"></style>
+<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+
+<script class="testbody" type="application/javascript">
+
+function runTest() {
+ // Copy content from table.
+ var selection = getSelection();
+ var startRange = document.createRange();
+ startRange.setStart(headingone, 0);
+ startRange.setEnd(celltwo, 0);
+ selection.removeAllRanges();
+ selection.addRange(startRange);
+ SpecialPowers.wrap(document).execCommand("copy", false, null);
+
+ // Paste content into "pasteframe"
+ var pasteContainer = pasteframe.contentDocument.body;
+ var pasteRange = pasteframe.contentDocument.createRange();
+ pasteRange.selectNodeContents(pasteContainer);
+ pasteRange.collapse(false);
+ selection.removeAllRanges();
+ selection.addRange(pasteRange);
+ SpecialPowers.wrap(pasteframe.contentDocument).execCommand("paste", false, null);
+
+ is(pasteContainer.querySelector("#headingone").textContent, "Month", "First heading should be 'Month'.");
+ is(pasteContainer.querySelector("#headingtwo").textContent, "Savings", "Second heading should be 'Savings'.");
+ is(pasteContainer.querySelector("#cellone").textContent, "January", "First cell should be 'January'.");
+ is(pasteContainer.querySelector("#celltwo").textContent, "$100", "Second cell should be '$100'.");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1306532">Mozilla Bug 1306532</a>
+<p id="display"></p>
+
+<pre id="test">
+</pre>
+
+<div id="container">
+<table border="1">
+ <tr>
+ <th id="headingone">Month</th>
+ <th id="headingtwo">Savings</th>
+ </tr>
+ <tr>
+ <td id="cellone">January</td>
+ <td id="celltwo">$100</td>
+ </tr>
+</table>
+</div>
+
+<iframe onload="runTest();" id="pasteframe" src="data:text/html,<html><body contenteditable='true'>"></iframe>
+
+</body>
+</html>