WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
Bug 35281
when deleting lines between lists, we should try to merge the lists
https://bugs.webkit.org/show_bug.cgi?id=35281
Summary
when deleting lines between lists, we should try to merge the lists
Tony Chang
Reported
2010-02-22 19:39:07 PST
For example: * one * two * ^ * four If the cursor is at ^, pressing enter breaks out of the list and now we have two lists. * one * two ^ * four Pressing backspace next should merge two lists. Instead we end up with two separate lists with a visible space between the two.
Attachments
Patch
(5.73 KB, patch)
2010-02-22 20:10 PST
,
Tony Chang
no flags
Details
Formatted Diff
Diff
Patch
(4.44 KB, patch)
2010-03-08 00:05 PST
,
Tony Chang
no flags
Details
Formatted Diff
Diff
fixes canMergeLists
(3.09 KB, patch)
2010-03-19 01:28 PDT
,
Ryosuke Niwa
no flags
Details
Formatted Diff
Diff
Patch
(6.18 KB, patch)
2010-03-22 19:02 PDT
,
Tony Chang
no flags
Details
Formatted Diff
Diff
Patch
(5.54 KB, patch)
2010-04-21 02:19 PDT
,
Tony Chang
no flags
Details
Formatted Diff
Diff
Patch
(7.01 KB, patch)
2010-04-25 17:59 PDT
,
Tony Chang
no flags
Details
Formatted Diff
Diff
Patch
(13.67 KB, patch)
2010-10-01 15:40 PDT
,
Tony Chang
no flags
Details
Formatted Diff
Diff
Patch
(14.03 KB, patch)
2010-10-01 17:05 PDT
,
Tony Chang
no flags
Details
Formatted Diff
Diff
Patch
(23.32 KB, patch)
2010-10-27 18:56 PDT
,
Tony Chang
rniwa
: review-
Details
Formatted Diff
Diff
Show Obsolete
(8)
View All
Add attachment
proposed patch, testcase, etc.
Tony Chang
Comment 1
2010-02-22 20:10:58 PST
Created
attachment 49262
[details]
Patch
Tony Chang
Comment 2
2010-02-22 20:11:45 PST
Adding Ryosuke, master of editable lists.
Tony Chang
Comment 3
2010-02-22 20:14:45 PST
(In reply to
comment #1
)
> Created an attachment (id=49262) [details] > Patch
Oh, I'm not sure this is the best place to put the merge code. I originally tried to put it in the DeleteSelection code, but DeleteSelection gets triggered by lots of places and this caused the calls to canMergeLists in IndentOutdentCommand to break. I was able to work around this with enough code tweaks, but it seemed like the DeleteSelection code is used in too many places for me to change the behavior safely.
Ryosuke Niwa
Comment 4
2010-03-07 09:36:32 PST
(In reply to
comment #3
)
> (In reply to
comment #1
) > > Created an attachment (id=49262) [details] [details] > > Patch > > Oh, I'm not sure this is the best place to put the merge code. I originally > tried to put it in the DeleteSelection code, but DeleteSelection gets triggered > by lots of places and this caused the calls to canMergeLists in > IndentOutdentCommand to break. I was able to work around this with enough code > tweaks, but it seemed like the DeleteSelection code is used in too many places > for me to change the behavior safely.
You could not modify IndentOutdentCommand instead? Is TypingCommand (guessing from the name) triggered from execCommand or events caused by mice?
Tony Chang
Comment 5
2010-03-08 00:05:32 PST
Created
attachment 50193
[details]
Patch
Tony Chang
Comment 6
2010-03-08 00:10:21 PST
(In reply to
comment #4
)
> (In reply to
comment #3
) > > (In reply to
comment #1
) > > > Created an attachment (id=49262) [details] [details] [details] > > > Patch > > > > Oh, I'm not sure this is the best place to put the merge code. I originally > > tried to put it in the DeleteSelection code, but DeleteSelection gets triggered > > by lots of places and this caused the calls to canMergeLists in > > IndentOutdentCommand to break. I was able to work around this with enough code > > tweaks, but it seemed like the DeleteSelection code is used in too many places > > for me to change the behavior safely. > > You could not modify IndentOutdentCommand instead?
I've attached a separate patch which does the merge in DeleteSelection. One test still fails, but if you think that approach is more appropriate, I can try to fix the test and upload a patch for review.
> Is TypingCommand (guessing > from the name) triggered from execCommand or events caused by mice?
It is triggered by execCommand (see the test) but is not triggered by a cut event. I'm not sure of any other way to delete a line using the mouse.
Ryosuke Niwa
Comment 7
2010-03-18 22:48:33 PDT
Comment on
attachment 50193
[details]
Patch
> - if (node->hasTagName(brTag)) > + if (node->hasTagName(brTag)) { > + VisiblePosition beforePlaceholder = caretAfterDelete.previous(true); > + VisiblePosition afterPlaceholder = caretAfterDelete.next(true); > removeNodeAndPruneAncestors(node); > + HTMLElement* before = enclosingList(beforePlaceholder.deepEquivalent().node()); > + HTMLElement* after = enclosingList(afterPlaceholder.deepEquivalent().node()); > + if (canMergeLists(before, after)) > + mergeIdenticalElements(before, after); > + }
This change alone seem to pass your test case. Why are the other changes also included in this patch? i.e. Why do we need other changes? If each other of other changes address other bugs / cases, then we should also test those as well.
Tony Chang
Comment 8
2010-03-18 22:52:43 PDT
(In reply to
comment #7
)
> This change alone seem to pass your test case. > Why are the other changes also included in this patch? > i.e. Why do we need other changes? > If each other of other changes address other bugs / cases, > then we should also test those as well.
The other changes are to avoid regressing other test cases. Because we merge the nodes earlier, the DOM structure isn't what we expect in InsertListCommand and IndentOutdentCommand.
Ryosuke Niwa
Comment 9
2010-03-19 01:22:17 PDT
(In reply to
comment #8
)
> The other changes are to avoid regressing other test cases. Because we merge > the nodes earlier, the DOM structure isn't what we expect in InsertListCommand > and IndentOutdentCommand.
I see. Now I see a bunch of tests failing without your other changes. I think I understand most of your fixes but I'm not sure about the last one in TypingCommand.cpp. As far as I analyzed the problem lies in MoveParagraph called in the second block of InsertListCommand::doApply(). MoveParagraph is called to move the contents of ol into the new LI element created but it leaves ol behind. In particular, UL 0x11990a6c0 LI 0x11a725660 #text 0x11a726560 "One" LI 0x1053e9280 BR 0x11a7271f0 * BR 0x11a7264a0 OL 0x11990aad0 UL 0x1068d6ec0 LI 0x1068ee590 #text 0x1068e4460 "Three" LI 0x11a00b7f0 #text 0x1068e61d0 "Four" becomes UL 0x1068d6ec0 LI 0x11a725660 #text 0x11a726560 "One" LI 0x1053e9280 BR 0x11a7271f0 LI 0x1068ee590 #text 0x1068e4460 "Three" LI 0x11a00b7f0 #text 0x1068e61d0 "Four" OL 0x11990aad0 due to the code you added in cleanupAfterDeletion(). This is a due to a bug in canMergeLists(). We must ensure that the two litss have the same enclosing list when merging. Here, we're merging un inside of ol and ul even though they belong to the to different levels. With the following canMergeLists, bool canMergeLists(Element* firstList, Element* secondList) { if (!firstList || !secondList) return false; return firstList->hasTagName(secondList->tagQName())// make sure the list types match (ol vs. ul) && firstList->isContentEditable() && secondList->isContentEditable()// both lists are editable && firstList->rootEditableElement() == secondList->rootEditableElement()// don't cross editing boundaries && enclosingList(firstList) == enclosingList(secondList) && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList)); // Make sure there is no visible content between this li and the previous list } TypingCommand does not need to be changed.
Ryosuke Niwa
Comment 10
2010-03-19 01:28:25 PDT
Created
attachment 51136
[details]
fixes canMergeLists I attach my svn diff. It passes all editing layout tests locally.
Tony Chang
Comment 11
2010-03-19 01:31:52 PDT
Comment on
attachment 49262
[details]
Patch Ok, then let's go with the latter approach. I will try to fix up the patch on Monday (JST).
Ryosuke Niwa
Comment 12
2010-03-21 16:34:52 PDT
(In reply to
comment #11
)
> (From update of
attachment 49262
[details]
) > Ok, then let's go with the latter approach. I will try to fix up the patch on > Monday (JST).
My patch for the
bug 19539
contains the identical change to InsertListCommand::doApply: nextList && previousList > canMergeLists(nextList, previousList). It might make sense to land that patch first because the
bug 19539
address the problem in InsertListCommand more directly.
Tony Chang
Comment 13
2010-03-22 19:02:25 PDT
Created
attachment 51385
[details]
Patch
Tony Chang
Comment 14
2010-03-22 19:03:45 PDT
(In reply to
comment #13
)
> Created an attachment (id=51385) [details] > Patch
Updated patch with the fix from Ryosuke. No commit-queue because as mentioned in
comment 12
, there's overlap with
bug 19539
.
Tony Chang
Comment 15
2010-04-21 02:19:50 PDT
Created
attachment 53932
[details]
Patch
Tony Chang
Comment 16
2010-04-21 02:20:18 PDT
(In reply to
comment #15
)
> Created an attachment (id=53932) [details] > Patch
Rev'ed the patch now that 19539 has landed.
Ryosuke Niwa
Comment 17
2010-04-21 02:25:32 PDT
(In reply to
comment #16
)
> (In reply to
comment #15
) > > Created an attachment (id=53932) [details] [details] > > Patch > > Rev'ed the patch now that 19539 has landed.
Ah... thanks for fixing my mistakes. I should have paid more attentions.
Adele Peterson
Comment 18
2010-04-24 11:29:04 PDT
Comment on
attachment 53932
[details]
Patch The tests aren't included in this patch. I actually couldn't see a visible space when trying to test this manually in TOT, so I'd like to try out the test case to see the behavior difference.
Tony Chang
Comment 19
2010-04-25 17:59:52 PDT
Created
attachment 54248
[details]
Patch
Tony Chang
Comment 20
2010-04-25 18:00:51 PDT
(In reply to
comment #18
)
> (From update of
attachment 53932
[details]
) > The tests aren't included in this patch. I actually couldn't see a visible > space when trying to test this manually in TOT, so I'd like to try out the test > case to see the behavior difference.
Sorry, new patch up with layout tests.
Darin Adler
Comment 21
2010-04-26 09:58:47 PDT
Comment on
attachment 54248
[details]
Patch I see five distinct code changes here and only one test case. Does this test case cover all five changes? In other words, if I take out each one of the five changes, is there a test that will fail? If not, I'd like to see additional test cases.
Tony Chang
Comment 22
2010-04-26 17:50:37 PDT
(In reply to
comment #21
)
> (From update of
attachment 54248
[details]
) > I see five distinct code changes here and only one test case. Does this test > case cover all five changes? In other words, if I take out each one of the five > changes, is there a test that will fail? If not, I'd like to see additional > test cases.
If you take out any one of the five changes either an existing test will fail or the new test will fail.
Adam Barth
Comment 23
2010-06-20 10:50:07 PDT
Ojan or Enrica: Interested in reviewing this patch?
Enrica Casucci
Comment 24
2010-06-22 09:57:46 PDT
Comment on
attachment 54248
[details]
Patch
> diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog > index 51a4e50..6605887 100644 > --- a/LayoutTests/ChangeLog > +++ b/LayoutTests/ChangeLog > @@ -1,3 +1,13 @@ > +2010-04-25 Tony Chang <
tony@chromium.org
> > + > + Reviewed by NOBODY (OOPS!). > + > + when deleting lines between lists, we should try to merge the lists > +
https://bugs.webkit.org/show_bug.cgi?id=35281
> + > + * editing/deleting/merge-lists-expected.txt: Added. > + * editing/deleting/merge-lists.html: Added. > + > 2010-04-25 Andrey Kosyakov <
caseq@chromium.org
> > > Reviewed by Adam Barth. > diff --git a/LayoutTests/editing/deleting/merge-lists-expected.txt b/LayoutTests/editing/deleting/merge-lists-expected.txt > new file mode 100644 > index 0000000..1754250 > --- /dev/null > +++ b/LayoutTests/editing/deleting/merge-lists-expected.txt > @@ -0,0 +1,9 @@ > +While on an empty list item, pressing enter should break out of the list and pressing delete should then merge the two lists together. There should be a single list below with 3 list items. > +one > +two > +three > +PASS: > +<li>one</li> > +<li>two</li> > +<li>three</li> > + > diff --git a/LayoutTests/editing/deleting/merge-lists.html b/LayoutTests/editing/deleting/merge-lists.html > new file mode 100644 > index 0000000..b9d6274 > --- /dev/null > +++ b/LayoutTests/editing/deleting/merge-lists.html > @@ -0,0 +1,23 @@ > +<body contentEditable="true"> > +<div>While on an empty list item, pressing enter should break out of the list and pressing delete > +should then merge the two lists together. There should be a single list below with 3 list items. > +<ul id="ul"> > + <li>one</li> > + <li>two</li> > + <li id="test"></li> > + <li>three</li> > +</ul> > +<div id="results">FAIL</div> > +<script src="../editing.js"></script> > +<script> > +function editingTest() > +{ > + execTypeCharacterCommand("\n"); > + execDeleteCommand(); > + if (document.getElementsByTagName("ul").length != 1) > + throw "Wrong number of lists." > + document.getElementById("results").innerText = "PASS: " + document.getElementById("ul").innerHTML; > +} > + > +runDumpAsTextEditingTest(false); > +</script> > diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog > index e329fc2..f11f803 100644 > --- a/WebCore/ChangeLog > +++ b/WebCore/ChangeLog > @@ -1,3 +1,21 @@ > +2010-04-25 Tony Chang <
tony@chromium.org
> > + > + Reviewed by NOBODY (OOPS!). > + > + when deleting lines between lists, we should try to merge the lists > +
https://bugs.webkit.org/show_bug.cgi?id=35281
> + > + Test: editing/deleting/merge-lists.html > + > + * editing/CompositeEditCommand.cpp: > + (WebCore::CompositeEditCommand::cleanupAfterDeletion): try to merge adjacent lists after a deletion > + * editing/IndentOutdentCommand.cpp: > + (WebCore::IndentOutdentCommand::tryIndentingAsListItem): > + * editing/InsertListCommand.cpp: > + (WebCore::InsertListCommand::doApply): > + * editing/htmlediting.cpp: > + (WebCore::canMergeLists): > + > 2010-04-25 Andrey Kosyakov <
caseq@chromium.org
> > > Reviewed by Adam Barth. > diff --git a/WebCore/editing/CompositeEditCommand.cpp b/WebCore/editing/CompositeEditCommand.cpp > index 9dc918d..6811563 100644 > --- a/WebCore/editing/CompositeEditCommand.cpp > +++ b/WebCore/editing/CompositeEditCommand.cpp > @@ -807,8 +807,15 @@ void CompositeEditCommand::cleanupAfterDeletion() > Position position = caretAfterDelete.deepEquivalent().downstream(); > Node* node = position.node(); > // Normally deletion will leave a br as a placeholder. > - if (node->hasTagName(brTag)) > + if (node->hasTagName(brTag)) { > + VisiblePosition beforePlaceholder = caretAfterDelete.previous(true); > + VisiblePosition afterPlaceholder = caretAfterDelete.next(true); > removeNodeAndPruneAncestors(node); > + HTMLElement* before = enclosingList(beforePlaceholder.deepEquivalent().node()); > + HTMLElement* after = enclosingList(afterPlaceholder.deepEquivalent().node()); > + if (canMergeLists(before, after)) > + mergeIdenticalElements(before, after); > + } > // If the selection to move was empty and in an empty block that > // doesn't require a placeholder to prop itself open (like a bordered > // div or an li), remove it during the move (the list removal code > diff --git a/WebCore/editing/IndentOutdentCommand.cpp b/WebCore/editing/IndentOutdentCommand.cpp > index 0f3975b..4e88cd2 100644 > --- a/WebCore/editing/IndentOutdentCommand.cpp > +++ b/WebCore/editing/IndentOutdentCommand.cpp > @@ -99,6 +99,8 @@ bool IndentOutdentCommand::tryIndentingAsListItem(const VisiblePosition& endOfCu > mergeIdenticalElements(previousList, newList); > if (canMergeLists(newList.get(), nextList)) > mergeIdenticalElements(newList, nextList); > + if (canMergeLists(previousList, nextList)) > + mergeIdenticalElements(previousList, nextList); > > return true; > } > diff --git a/WebCore/editing/InsertListCommand.cpp b/WebCore/editing/InsertListCommand.cpp > index cd6838b..2f3f638 100644 > --- a/WebCore/editing/InsertListCommand.cpp > +++ b/WebCore/editing/InsertListCommand.cpp > @@ -136,7 +136,7 @@ void InsertListCommand::doApply() > Node* listChildNode = enclosingListChild(selectionNode); > bool switchListType = false; > if (listChildNode) { > - // Remove the list chlild. > + // Remove the list child. > HTMLElement* listNode = enclosingList(listChildNode); > if (!listNode) > listNode = fixOrphanedListChild(listChildNode); > @@ -263,12 +263,12 @@ void InsertListCommand::doApply() > nextList = outermostEnclosingList(nextPosition.deepEquivalent().node(), enclosingList(listElement.get())); > } > moveParagraph(start, end, VisiblePosition(Position(placeholder.get(), 0)), true); > - if (m_listElement) { > + if (m_listElement && m_listElement->inDocument()) { > if (canMergeLists(previousList, m_listElement.get())) > mergeIdenticalElements(previousList, m_listElement.get()); > if (canMergeLists(m_listElement.get(), nextList)) > mergeIdenticalElements(m_listElement.get(), nextList); > - } else if (canMergeLists(nextList, previousList)) > + } else if (canMergeLists(previousList, nextList)) > mergeIdenticalElements(previousList, nextList); > } > } > diff --git a/WebCore/editing/htmlediting.cpp b/WebCore/editing/htmlediting.cpp > index b7a062b..bfbf929 100644 > --- a/WebCore/editing/htmlediting.cpp > +++ b/WebCore/editing/htmlediting.cpp > @@ -835,6 +835,7 @@ bool canMergeLists(Element* firstList, Element* secondList) > return firstList->hasTagName(secondList->tagQName())// make sure the list types match (ol vs. ul) > && firstList->isContentEditable() && secondList->isContentEditable()// both lists are editable > && firstList->rootEditableElement() == secondList->rootEditableElement()// don't cross editing boundaries > + && enclosingList(firstList) == enclosingList(secondList) > && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList)); > // Make sure there is no visible content between this li and the previous list > }
This makes sense to me.
Ryosuke Niwa
Comment 25
2010-07-26 10:17:03 PDT
Comment on
attachment 54248
[details]
Patch .> diff --git a/LayoutTests/editing/deleting/merge-lists-expected.txt b/LayoutTests/editing/deleting/merge-lists-expected.txt
> new file mode 100644 > index 0000000..1754250 > --- /dev/null > +++ b/LayoutTests/editing/deleting/merge-lists-expected.txt > @@ -0,0 +1,9 @@ > +While on an empty list item, pressing enter should break out of the list and pressing delete should then merge the two lists together. There should be a single list below with 3 list items. > +one > +two > +three > +PASS: > +<li>one</li> > +<li>two</li> > +<li>three</li> > +
> I would like to see the intermediate HTML after you broke out of the list because if that didn't happen, we won't be testing what we claim to test. Or you can start with the HTML after you broke out of the test. But I prefer adding one more dump for the better test coverage.
> --- a/WebCore/editing/CompositeEditCommand.cpp > +++ b/WebCore/editing/CompositeEditCommand.cpp > @@ -807,8 +807,15 @@ void CompositeEditCommand::cleanupAfterDeletion() > Position position = caretAfterDelete.deepEquivalent().downstream(); > Node* node = position.node(); > // Normally deletion will leave a br as a placeholder. > - if (node->hasTagName(brTag)) > + if (node->hasTagName(brTag)) { > + VisiblePosition beforePlaceholder = caretAfterDelete.previous(true); > + VisiblePosition afterPlaceholder = caretAfterDelete.next(true); > removeNodeAndPruneAncestors(node); > + HTMLElement* before = enclosingList(beforePlaceholder.deepEquivalent().node()); > + HTMLElement* after = enclosingList(afterPlaceholder.deepEquivalent().node());
I'm skeptical about this enclosingList business here. What if the list list of the previous or the next lists were inner lists? For example, if we had <ul><ul><li>hello</li></ul><li></li> and then did what the reproduction steps describe here, won't be obtaining the inner list for before and fail to merge? My patch for
https://bugs.webkit.org/show_bug.cgi?id=33668
fixes this problem in InsertListCommand
> + if (canMergeLists(before, after)) > + mergeIdenticalElements(before, after); > + }
LGTM.
> index 0f3975b..4e88cd2 100644 > --- a/WebCore/editing/IndentOutdentCommand.cpp > +++ b/WebCore/editing/IndentOutdentCommand.cpp > @@ -99,6 +99,8 @@ bool IndentOutdentCommand::tryIndentingAsListItem(const VisiblePosition& endOfCu > mergeIdenticalElements(previousList, newList); > if (canMergeLists(newList.get(), nextList)) > mergeIdenticalElements(newList, nextList); > + if (canMergeLists(previousList, nextList)) > + mergeIdenticalElements(previousList, nextList);
Are you sure this code path is ever executed? The only case this will be executed is if both previousList and nextList can be merged with newList. But then the first if statement will merge previousList and newList and leaves newList. We then merge newList and nextList. So the code should work as is unless I'm missing something.
> diff --git a/WebCore/editing/InsertListCommand.cpp b/WebCore/editing/InsertListCommand.cpp > index cd6838b..2f3f638 100644 > --- a/WebCore/editing/InsertListCommand.cpp > +++ b/WebCore/editing/InsertListCommand.cpp > @@ -263,12 +263,12 @@ void InsertListCommand::doApply() > nextList = outermostEnclosingList(nextPosition.deepEquivalent().node(), enclosingList(listElement.get())); > } > moveParagraph(start, end, VisiblePosition(Position(placeholder.get(), 0)), true); > - if (m_listElement) { > + if (m_listElement && m_listElement->inDocument()) {
I suppose JavaScript can modify the DOM but shouldn't the canMergeLists be harmless in that case?
> if (canMergeLists(previousList, m_listElement.get())) > mergeIdenticalElements(previousList, m_listElement.get()); > if (canMergeLists(m_listElement.get(), nextList)) > mergeIdenticalElements(m_listElement.get(), nextList); > - } else if (canMergeLists(nextList, previousList)) > + } else if (canMergeLists(previousList, nextList))
Oops, my bad.
> --- a/WebCore/editing/htmlediting.cpp > +++ b/WebCore/editing/htmlediting.cpp > @@ -835,6 +835,7 @@ bool canMergeLists(Element* firstList, Element* secondList) > return firstList->hasTagName(secondList->tagQName())// make sure the list types match (ol vs. ul) > && firstList->isContentEditable() && secondList->isContentEditable()// both lists are editable > && firstList->rootEditableElement() == secondList->rootEditableElement()// don't cross editing boundaries > + && enclosingList(firstList) == enclosingList(secondList) > && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList)); > // Make sure there is no visible content between this li and the previous list > }
Good change.
Tony Chang
Comment 26
2010-07-30 17:04:01 PDT
Comment on
attachment 54248
[details]
Patch Sounds like this is conflicting with some patches rniwa has in flight. I will revisit after his patch for issue 33668 lands.
Tony Chang
Comment 27
2010-10-01 15:40:05 PDT
Created
attachment 69529
[details]
Patch
Tony Chang
Comment 28
2010-10-01 15:48:25 PDT
The newest patch removes the changes except for the list merging. I also updated MergeIdenticalElementsCommand to support merging into the first element. Without this, we would break during moveParagraphsWithClones which expects the new list to exist after calling cleanupAfterDeletion(). I updated the test to show the intermediate HTML. """I'm skeptical about this enclosingList business here. What if the list list of the previous or the next lists were inner lists? For example, if we had <ul><ul><li>hello</li></ul><li></li> and then did what the reproduction steps describe here, won't be obtaining the inner list for before and fail to merge?""" If this is the editable text: * * Hello * ^ I'm not sure what we're merging here. I added a test for: * * Hello * ^ * * World Where pressing backspace should merge into a single double nested list. If the lists are at different depths, I don't think they should merge.
Ryosuke Niwa
Comment 29
2010-10-01 15:58:35 PDT
Comment on
attachment 69529
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=69529&action=review
> WebCore/editing/CompositeEditCommand.h:46 > + enum MergeDirection { > + MergeIntoFirst, > + MergeIntoSecond, > + }; > +
I'm not sure if MergeDirection is the right name because direction just sounds like it's related to LTR/RTL. But I can't think of a better one. Maybe ElementToMergeInto?
> WebCore/editing/MergeIdenticalElementsCommand.cpp:84 > + if (m_direction == MergeIntoFirst) > + insertNodeAfter(m_element2.get(), m_element1.get());
It seems like this is the only reason we're making it inherit from CompositeEditCommand? We should just call appendChild on its parent when it's at the end, and call insertBefore otherwise.
> WebCore/editing/MergeIdenticalElementsCommand.h:33 > -class MergeIdenticalElementsCommand : public SimpleEditCommand { > +class MergeIdenticalElementsCommand : public CompositeEditCommand {
I don't think we want to make this command CompositeEditCommand. If we're absolutely required to do this, then we should remove doUnapply and doReapply.
Ryosuke Niwa
Comment 30
2010-10-01 16:06:20 PDT
(In reply to
comment #28
)
> If this is the editable text: > > * * Hello > * ^ > > I'm not sure what we're merging here. I added a test for: > > * * Hello > * ^ > * * World > > Where pressing backspace should merge into a single double nested list. If the lists are at different depths, I don't think they should merge.
So you get <ul><ul><li>hello</li><li>world</li></ul></ul>, right? That sounds like a correct behavior to me. Sorry my grammar was really bad in the earlier comment but what I intended to say was that enclosingList incorrectly obtains the inner most list as supposed to the list of the appropriate level. For example, if we had:
> * * Hello > ^ > * World
We should be getting
> * * Hello > * World
Where * Hello and World belongs to the same list: <ul><ul><li>Hello</li></ul><li>World</li></ul>. With your original patch, I think enclosingList would have grabbed ul wrapping "Hello" and failed to merge the outer list, resulting in <ul><ul><li>Hello</li></ul></ul><ul><li>World</li></ul>.
Tony Chang
Comment 31
2010-10-01 17:05:58 PDT
Created
attachment 69543
[details]
Patch
Tony Chang
Comment 32
2010-10-01 17:20:49 PDT
(In reply to
comment #29
)
> I'm not sure if MergeDirection is the right name because direction just sounds like it's related to LTR/RTL. But I can't think of a better one. Maybe ElementToMergeInto?
Renamed to MergeIdenticalElementsDirection.
> > WebCore/editing/MergeIdenticalElementsCommand.cpp:84 > > + if (m_direction == MergeIntoFirst) > > + insertNodeAfter(m_element2.get(), m_element1.get()); > > It seems like this is the only reason we're making it inherit from CompositeEditCommand? We should just call appendChild on its parent when it's at the end, and call insertBefore otherwise.
Ok, restored it as a SimpleEditCommand.
> For example, if we had: > > > * * Hello > > ^ > > * World > > We should be getting > > > * * Hello > > * World > > Where * Hello and World belongs to the same list: <ul><ul><li>Hello</li></ul><li>World</li></ul>. With your original patch, I think enclosingList would have grabbed ul wrapping "Hello" and failed to merge the outer list, resulting in <ul><ul><li>Hello</li></ul></ul><ul><li>World</li></ul>.
With this patch, we still don't merge the outer lists. I'm not 100% convinced we should merge in this case. I tried it in IE9 and it produced: * * HelloWorld But that doesn't seem much better. Anyway, I think this case should be a different bug/patch.
Ryosuke Niwa
Comment 33
2010-10-01 18:05:03 PDT
(In reply to
comment #32
)
> Ok, restored it as a SimpleEditCommand.
Great! Do we currently have a test for undoing/redoing MergeIdenticalElements? If not, could you add one since you're making a lot of changes?
> > For example, if we had: > > > > > * * Hello > > > ^ > > > * World > > > > We should be getting > > > > > * * Hello > > > * World > > > > Where * Hello and World belongs to the same list: <ul><ul><li>Hello</li></ul><li>World</li></ul>. With your original patch, I think enclosingList would have grabbed ul wrapping "Hello" and failed to merge the outer list, resulting in <ul><ul><li>Hello</li></ul></ul><ul><li>World</li></ul>. > > With this patch, we still don't merge the outer lists. I'm not 100% convinced we should merge in this case. I tried it in IE9 and it produced.
Take a look at mergeWithNeighboringLists in InsertListCommand.cpp. Using that function should solve this problem.
Tony Chang
Comment 34
2010-10-01 18:30:05 PDT
(In reply to
comment #33
)
> (In reply to
comment #32
) > > Ok, restored it as a SimpleEditCommand. > > Great! Do we currently have a test for undoing/redoing MergeIdenticalElements?
editing/undo/undo-indent.html covers this.
Ryosuke Niwa
Comment 35
2010-10-26 22:35:59 PDT
Could someone review the patch Tony posted before it gets too old?
Eric Seidel (no email)
Comment 36
2010-10-27 14:54:09 PDT
Comment on
attachment 69543
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=69543&action=review
I'm confused why direction is needed.
> WebCore/editing/CompositeEditCommand.cpp:807 > + VisiblePosition beforePlaceholder = caretAfterDelete.previous(true); > + VisiblePosition afterPlaceholder = caretAfterDelete.next(true); > removeNodeAndPruneAncestors(node); > + HTMLElement* before = enclosingList(beforePlaceholder.deepEquivalent().node()); > + HTMLElement* after = enclosingList(afterPlaceholder.deepEquivalent().node());
Do we need an enclosingList function which takes a visible position? and/or a canMergeListsAt(visiblePosition) function?
> WebCore/editing/CompositeEditCommand.h:42 > + enum MergeIdenticalElementsDirection {
Seems this should just be its own header since it's needed in SimpleEditComand.
> WebCore/editing/MergeIdenticalElementsCommand.h:50 > + CompositeEditCommand::MergeIdenticalElementsDirection m_direction;
Seems this enum wants its own header...
Tony Chang
Comment 37
2010-10-27 18:56:40 PDT
Created
attachment 72127
[details]
Patch
Tony Chang
Comment 38
2010-10-27 18:59:37 PDT
(In reply to
comment #36
)
> (From update of
attachment 69543
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=69543&action=review
> > I'm confused why direction is needed.
Without this, we would break during moveParagraphsWithClones which expects the new list to exist after calling cleanupAfterDeletion(). The old behavior (MergeIntoSecond) is expected by some of the existing callers that try to keep a pointer to the second list.
> Do we need an enclosingList function which takes a visible position? and/or a canMergeListsAt(visiblePosition) function?
Added.
> Seems this should just be its own header since it's needed in SimpleEditComand. > Seems this enum wants its own header...
Done.
Adam Barth
Comment 39
2010-12-21 01:16:43 PST
(In reply to
comment #35
)
> Could someone review the patch Tony posted before it gets too old?
^^^ rniwa?
Alexis Menard (darktears)
Comment 40
2011-03-31 05:22:41 PDT
Comment on
attachment 72127
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=72127&action=review
> LayoutTests/ChangeLog:5 > + when deleting lines between lists, we should try to merge the lists
The subject should start with an upper case letter I believe.
> WebCore/ChangeLog:5 > + when deleting lines between lists, we should try to merge the lists
Same.
> WebCore/editing/MergeIdenticalElementsDirection.h:2 > + * Copyright (C) 2010 Google Inc. All rights reserved.
2011?
Eric Seidel (no email)
Comment 41
2011-04-26 15:50:03 PDT
Comment on
attachment 72127
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=72127&action=review
I like this! I'm ready to r+ this if updated.
> WebCore/WebCore.xcodeproj/project.pbxproj:1303 > + 53E34AEC127907C20060B999 /* MergeIdenticalElementsDirection.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E34AEB127907C20060B999 /* MergeIdenticalElementsDirection.h */; settings = {ATTRIBUTES = (Private, ); }; };
Why does this need to be private instead of project?
> WebCore/editing/MergeIdenticalElementsDirection.h:37 > +typedef enum { > + MergeIntoFirst, > + MergeIntoSecond, > +} MergeIdenticalElementsDirection;
Is this modern syntax?
Aryeh Gregor
Comment 42
2011-08-30 13:43:53 PDT
The current editing spec has this bug too, which I filed:
http://www.w3.org/Bugs/Public/show_bug.cgi?id=13976
Shezan Baig
Comment 43
2013-03-15 07:37:59 PDT
Is this worth pursuing? It seems like it would remove some editing flexibility. For example, it wouldn't allow lists to be siblings without an extra linebreak. i.e, if I have: <ul> <li>first</li> <li>second</li> </ul> <br/>[selection-caret] <ul> <li>another first</li> <li>another second</li> </ul> If this bug is fixed, it would be impossible for an editor to get this markup: <ul> <li>first</li> <li>second</li> </ul> <ul> <li>another first</li> <li>another second</li> </ul> Which may be desirable, since <ul>s have margin before and after. Forcing them to have a <br/> introduces too much spacing between the lists. I think the lists should only be merged if the user presses backspace at: <ul> <li>first</li> <li>second</li> </ul> <ul> <li>[selection-caret]another first</li> <li>another second</li> </ul> Thoughts?
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug