WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
52642
Get rid of firstDeepEditingPositionForNode and lastDeepEditingPositionForNode
https://bugs.webkit.org/show_bug.cgi?id=52642
Summary
Get rid of firstDeepEditingPositionForNode and lastDeepEditingPositionForNode
Ryosuke Niwa
Reported
2011-01-18 10:49:52 PST
firstDeepEditingPositionForNode and lastDeepEditingPositionForNode need to be removed because they produce legacy editing positions.
Attachments
Work in progress
(20.95 KB, patch)
2011-02-17 17:00 PST
,
Levi Weintraub
no flags
Details
Formatted Diff
Diff
Patch
(28.05 KB, patch)
2011-02-22 16:45 PST
,
Levi Weintraub
no flags
Details
Formatted Diff
Diff
Patch
(26.15 KB, patch)
2011-02-25 14:51 PST
,
Levi Weintraub
no flags
Details
Formatted Diff
Diff
Patch
(26.37 KB, patch)
2011-03-08 15:46 PST
,
Levi Weintraub
no flags
Details
Formatted Diff
Diff
Patch
(26.77 KB, patch)
2011-03-14 19:05 PDT
,
Levi Weintraub
no flags
Details
Formatted Diff
Diff
Patch
(26.92 KB, patch)
2011-03-15 12:14 PDT
,
Levi Weintraub
rniwa
: review+
Details
Formatted Diff
Diff
Show Obsolete
(5)
View All
Add attachment
proposed patch, testcase, etc.
Levi Weintraub
Comment 1
2011-02-17 17:00:53 PST
Created
attachment 82877
[details]
Work in progress There are still various places in the code I'm uncovering that handle legacy positions incorrectly. I'm addressing them as they become apparent.
Levi Weintraub
Comment 2
2011-02-22 16:45:57 PST
Created
attachment 83415
[details]
Patch
Levi Weintraub
Comment 3
2011-02-22 16:47:24 PST
This patch will fail without the changes in the bugs it's listed to depend on.
Levi Weintraub
Comment 4
2011-02-25 14:51:08 PST
Created
attachment 83881
[details]
Patch
Levi Weintraub
Comment 5
2011-02-25 14:51:35 PST
Re-uploading fixing the conflicts so it'll build.
Ryosuke Niwa
Comment 6
2011-03-03 00:45:47 PST
Comment on
attachment 83881
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=83881&action=review
Thanks for tackling this hard bug! It seems like we need a few more iterations before landing this one.
> Source/WebCore/dom/Position.h:194 > + return a.anchorNode() == b.anchorNode() && a.deprecatedEditingOffset() == b.deprecatedEditingOffset() && a.anchorType() == b.anchorType();
Should we also check whether values of m_isLegacyEditingPosition are same?
> Source/WebCore/editing/TypingCommand.cpp:574 > - setEndingSelection(VisibleSelection(endingSelection().end(), lastDeepEditingPositionForNode(downstreamEnd.deprecatedNode()), DOWNSTREAM)); > + setEndingSelection(VisibleSelection(endingSelection().end(), positionAfterNode(downstreamEnd.deprecatedNode()), DOWNSTREAM));
Why not firstPositionInOrAfterNode?
> Source/WebCore/editing/VisibleSelection.cpp:92 > - return VisibleSelection(firstDeepEditingPositionForNode(node), lastDeepEditingPositionForNode(node), DOWNSTREAM); > + return VisibleSelection(firstPositionInNode(node), lastPositionInNode(node), DOWNSTREAM);
Is it always safe to return position inside the node? It seems like this is always called for anchor element? We should probably assert that so that we don't start generating positions inside other elements / nodes.
> Source/WebCore/editing/VisibleSelection.cpp:501 > - p = lastDeepEditingPositionForNode(shadowAncestor); > + p = lastPositionInNode(shadowAncestor);
Why does this make sense? If I understand correctly, shadow ancestor is nodes like input, textarea, etc... that contains shadow DOM, right? We should always position before or after that node. r- because of this.
> Source/WebCore/editing/htmlediting.cpp:281 > + if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && highestRoot->isContentEditable()) > + return firstPositionInOrBeforeNode(highestRoot);
I don't get this change. If you know you can always get a position inside the highestRoot, then why would you call firstPositionInOrBeforeNode when you return? r- because of this.
> Source/WebCore/editing/htmlediting.cpp:287 > - p = lastDeepEditingPositionForNode(shadowAncestor); > + p = lastPositionInOrAfterNode(shadowAncestor);
I don't think it makes any sense to use a position inside a shadow ancestor. You should always call positionAfterNode here.
> Source/WebCore/editing/htmlediting.cpp:725 > - VisiblePosition firstInListChild(firstDeepEditingPositionForNode(listChildNode)); > - VisiblePosition lastInListChild(lastDeepEditingPositionForNode(listChildNode)); > + VisiblePosition firstInListChild(firstPositionInNode(listChildNode)); > + VisiblePosition lastInListChild(lastPositionInNode(listChildNode));
I don't think this is right. listChildNode can be BR or whatever node under ul / ol, and it's not necessarily li.
> Source/WebCore/editing/visible_units.cpp:749 > - return firstDeepEditingPositionForNode(startNode); > + return positionBeforeNode(startNode);
Why not firstPositionInOrBeforeNode?
> Source/WebCore/editing/visible_units.cpp:808 > - return lastDeepEditingPositionForNode(startNode); > + return positionAfterNode(startNode);
Ditto.
Levi Weintraub
Comment 7
2011-03-07 14:34:48 PST
Comment on
attachment 83881
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=83881&action=review
>> Source/WebCore/dom/Position.h:194 >> + return a.anchorNode() == b.anchorNode() && a.deprecatedEditingOffset() == b.deprecatedEditingOffset() && a.anchorType() == b.anchorType(); > > Should we also check whether values of m_isLegacyEditingPosition are same?
Perhaps we should only consider anchorType to matter if both are new positions? I certainly don't want to and m_isLegacyEditingPosition onto the expression. Two otherwise equivalent positions in a text node shouldn't be considered different only because one was created using a legacy method.
>> Source/WebCore/editing/TypingCommand.cpp:574 >> + setEndingSelection(VisibleSelection(endingSelection().end(), positionAfterNode(downstreamEnd.deprecatedNode()), DOWNSTREAM)); > > Why not firstPositionInOrAfterNode?
This is only for tables, and we actually want to use the position after it, not inside.
>> Source/WebCore/editing/VisibleSelection.cpp:92 >> + return VisibleSelection(firstPositionInNode(node), lastPositionInNode(node), DOWNSTREAM); > > Is it always safe to return position inside the node? It seems like this is always called for anchor element? We should probably assert that so that we don't start generating positions inside other elements / nodes.
It should always be safe, and therefor is definitely worthy of an assertion, thanks :)
>> Source/WebCore/editing/VisibleSelection.cpp:501 >> + p = lastPositionInNode(shadowAncestor); > > Why does this make sense? If I understand correctly, shadow ancestor is nodes like input, textarea, etc... that contains shadow DOM, right? We should always position before or after that node. r- because of this.
Good catch, you're right. I confused shadowAncestor with shadowRoot, which we never want to be before/after.
>> Source/WebCore/editing/visible_units.cpp:749 >> + return positionBeforeNode(startNode); > > Why not firstPositionInOrBeforeNode?
We don't want positions inside tables, images, or horizontal rules.
Levi Weintraub
Comment 8
2011-03-07 14:49:23 PST
Comment on
attachment 83881
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=83881&action=review
>> Source/WebCore/editing/htmlediting.cpp:725 >> + VisiblePosition lastInListChild(lastPositionInNode(listChildNode)); > > I don't think this is right. listChildNode can be BR or whatever node under ul / ol, and it's not necessarily li.
Correct me if I'm wrong, but it appears enclosingListChild will only return li, ul, ol, and dl elements. This function is attempting to determine if there's an empty list item that contains the visible position, so I don't think we'd want to compare that position to positions before or after that containing list/list item.
Levi Weintraub
Comment 9
2011-03-07 15:15:40 PST
Comment on
attachment 83881
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=83881&action=review
>>> Source/WebCore/editing/htmlediting.cpp:725 >>> + VisiblePosition lastInListChild(lastPositionInNode(listChildNode)); >> >> I don't think this is right. listChildNode can be BR or whatever node under ul / ol, and it's not necessarily li. > > Correct me if I'm wrong, but it appears enclosingListChild will only return li, ul, ol, and dl elements. This function is attempting to determine if there's an empty list item that contains the visible position, so I don't think we'd want to compare that position to positions before or after that containing list/list item.
Ryosuke is totally right. This can return non-list items. Fixing this too.
Levi Weintraub
Comment 10
2011-03-08 15:46:14 PST
Created
attachment 85102
[details]
Patch
Ryosuke Niwa
Comment 11
2011-03-14 18:27:45 PDT
Comment on
attachment 85102
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=85102&action=review
Great! Most of changes look good to me. I have a few questions:
> Source/WebCore/dom/Position.cpp:167 > return Position(m_anchorNode, 0, PositionIsOffsetInAnchor);
Isn't this just firstPositionInNode?
> Source/WebCore/dom/Position.cpp:328 > - return m_offset <= 0; > + return m_anchorType == PositionIsBeforeAnchor || m_offset <= 0;
I don't think this is right. If we're before/after node, then I don't think we're at first editing position in the (container) node.
> Source/WebCore/dom/Position.cpp:335 > - return m_offset >= lastOffsetForEditing(deprecatedNode()); > + return m_anchorType == PositionIsAfterAnchor || m_offset >= lastOffsetForEditing(deprecatedNode());
Ditto.
> Source/WebCore/dom/Position.cpp:786 > - return !m_offset && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); > + return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
Why are we adding this check here?
> Source/WebCore/editing/ApplyBlockElementCommand.cpp:196 > - start = positionBeforeNode(start.deprecatedNode()); > + start = firstPositionInNode(start.deprecatedNode());
How do we know that start can always contain a position?
> Source/WebCore/editing/ApplyBlockElementCommand.cpp:227 > - start = positionBeforeNode(end.deprecatedNode()->previousSibling()); > + start = firstPositionInNode(end.deprecatedNode()->previousSibling());
Ditto about end.
> Source/WebCore/editing/VisibleSelection.cpp:93 > - return VisibleSelection(firstDeepEditingPositionForNode(node), lastDeepEditingPositionForNode(node), DOWNSTREAM); > + ASSERT(!editingIgnoresContent(node)); > + return VisibleSelection(firstPositionInNode(node), lastPositionInNode(node), DOWNSTREAM);
How do we know that it's okay to have a position inside node?
Levi Weintraub
Comment 12
2011-03-14 18:46:05 PDT
Comment on
attachment 85102
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=85102&action=review
Thanks for the review!
>> Source/WebCore/dom/Position.cpp:328 >> + return m_anchorType == PositionIsBeforeAnchor || m_offset <= 0; > > I don't think this is right. If we're before/after node, then I don't think we're at first editing position in the (container) node.
This definitely deserves a fixme and bug to get rid of at[First/last]EditingPositionForNode.
>> Source/WebCore/dom/Position.cpp:786 >> + return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); > > Why are we adding this check here?
After positions aren't considered candidates, but through javascript br's can still have children. I'll add a comment.
>> Source/WebCore/editing/ApplyBlockElementCommand.cpp:196 >> + start = firstPositionInNode(start.deprecatedNode()); > > How do we know that start can always contain a position?
This is a mistake. It should have been firstPositionInOrBefore, thanks!
>> Source/WebCore/editing/ApplyBlockElementCommand.cpp:227 >> + start = firstPositionInNode(end.deprecatedNode()->previousSibling()); > > Ditto about end.
Ditto :D
>> Source/WebCore/editing/VisibleSelection.cpp:93 >> + return VisibleSelection(firstPositionInNode(node), lastPositionInNode(node), DOWNSTREAM); > > How do we know that it's okay to have a position inside node?
That's why I added the assert. Currently all callers ensure this.
Levi Weintraub
Comment 13
2011-03-14 19:05:54 PDT
Created
attachment 85758
[details]
Patch
Ryosuke Niwa
Comment 14
2011-03-14 19:22:12 PDT
Comment on
attachment 85758
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=85758&action=review
> Source/WebCore/dom/Position.cpp:328 > - return m_offset <= 0; > + return m_anchorType == PositionIsBeforeAnchor || m_offset <= 0;
Wait, didn't you say you'll add comment here?
> Source/WebCore/dom/Position.cpp:786 > - return !m_offset && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); > + return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
Ditto.
> Source/WebCore/editing/htmlediting.cpp:302 > + return lastPositionInOrAfterNode(highestRoot);
?? Why lastPositionInOrAfterNode? It should be lastPositionInNode, right?
Levi Weintraub
Comment 15
2011-03-15 10:33:30 PDT
Comment on
attachment 85758
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=85758&action=review
>> Source/WebCore/dom/Position.cpp:328 >> + return m_anchorType == PositionIsBeforeAnchor || m_offset <= 0; > > Wait, didn't you say you'll add comment here?
I put a fixme in the header
>> Source/WebCore/dom/Position.cpp:786 >> + return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); > > Ditto.
I thought about it more and thought this code really did speak for itself, as writing a comment seemed to just be rehashing.
>> Source/WebCore/editing/htmlediting.cpp:302 >> + return lastPositionInOrAfterNode(highestRoot); > > ?? Why lastPositionInOrAfterNode? It should be lastPositionInNode, right?
Good catch :)
Ryosuke Niwa
Comment 16
2011-03-15 10:41:10 PDT
Comment on
attachment 85758
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=85758&action=review
>>> Source/WebCore/dom/Position.cpp:786 >>> + return !m_offset && m_anchorType != PositionIsAfterAnchor && !nodeIsUserSelectNone(deprecatedNode()->parentNode()); >> >> Ditto. > > I thought about it more and thought this code really did speak for itself, as writing a comment seemed to just be rehashing.
I still think we need a FIXME here.
Levi Weintraub
Comment 17
2011-03-15 12:14:25 PDT
Created
attachment 85841
[details]
Patch
Ryosuke Niwa
Comment 18
2011-03-15 12:28:23 PDT
Comment on
attachment 85841
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=85841&action=review
> Source/WebCore/dom/Position.cpp:244 > + // FIXME: Explicitly handle before/after positions
I don't think these comments are valuable. It's clear from the fact it calls deprecatedEditingOffset().
Levi Weintraub
Comment 19
2011-03-15 12:37:07 PDT
Committed
r81165
: <
http://trac.webkit.org/changeset/81165
>
WebKit Review Bot
Comment 20
2011-03-15 23:28:08 PDT
http://trac.webkit.org/changeset/81165
might have broken GTK Linux 32-bit Debug and GTK Linux 64-bit Debug
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