WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
51001
Moving or selecting backwards by words jumps to start of contenteditable region if contenteditable=false span is encountered
https://bugs.webkit.org/show_bug.cgi?id=51001
Summary
Moving or selecting backwards by words jumps to start of contenteditable regi...
Benjamin (Ben) Kalman
Reported
2010-12-13 18:57:02 PST
Repro attached. 1. place cursor on right of the "here" span 2. move back by word granularity a few times (ctrl + left/backspace on linux, option + left/backspace on osx) 3. when cursor would cross "here" it actually jumps back to the start of the region I believe this is caused by
http://trac.webkit.org/changeset/64974
, namely the addition of TextIteratorEndsAtEditingBoundary in visible_units.cpp (lines 115 and 150). Reverting the change results in the failure of editing/selection/doubleclick-inline-first-last-contenteditable.html, however. Please assign this bug to me, I will fix it :-) P.S. there is also a bug going /forwards/ over the "here" span, but I haven't looked at what is causing it. Could be related.
Attachments
Repro
(101 bytes, text/html)
2010-12-13 18:57 PST
,
Benjamin (Ben) Kalman
no flags
Details
Patch
(8.26 KB, patch)
2010-12-13 23:09 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(10.84 KB, patch)
2010-12-16 23:40 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(11.47 KB, patch)
2010-12-29 17:27 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(11.53 KB, patch)
2010-12-29 17:47 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch with parentOrHostNode changed to parentNode
(11.66 KB, patch)
2011-01-11 16:46 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(14.59 KB, patch)
2011-01-17 19:17 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Ugh. check-webkit-style.
(14.58 KB, patch)
2011-01-17 19:24 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(12.92 KB, patch)
2011-01-18 16:02 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(13.91 KB, patch)
2011-01-20 22:50 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Change to advanceRespectingRange
(13.86 KB, patch)
2011-01-23 16:51 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
nicer factored test
(15.64 KB, patch)
2011-01-24 22:28 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
nicer factored test (2)
(13.60 KB, patch)
2011-01-24 22:57 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
rebase
(13.62 KB, patch)
2011-01-26 17:16 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(14.19 KB, patch)
2011-02-20 20:04 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch
(14.25 KB, patch)
2011-02-22 22:00 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch with correct svn version
(14.25 KB, patch)
2011-02-22 22:28 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Patch for landing
(14.24 KB, patch)
2011-02-22 23:00 PST
,
Benjamin (Ben) Kalman
no flags
Details
Formatted Diff
Diff
Show Obsolete
(16)
View All
Add attachment
proposed patch, testcase, etc.
Benjamin (Ben) Kalman
Comment 1
2010-12-13 18:57:51 PST
Created
attachment 76483
[details]
Repro
Benjamin (Ben) Kalman
Comment 2
2010-12-13 23:09:45 PST
Created
attachment 76506
[details]
Patch
Benjamin (Ben) Kalman
Comment 3
2010-12-13 23:22:02 PST
I've looked at the failing test, and it's caused by the following behaviour: given a dom like <div> Foo <span contenteditable=false>Bar|</span> Baz </div> (Cursor indicated with a | vertical bar), moving backwards by a word results in <div> Foo| <span contenteditable>Bar</span> Baz </div> (causing the selection to be cancelled altogether, it seems), rather than <div contenteditable> Foo <span contenteditable=false>|Bar</span> Baz </div>
http://trac.webkit.org/changeset/64974
fixed this problem by stopping iteration when a contenteditable boundary is crossed, a side-effect being the problem described in this bug. I've upload a potential fix (with a test case) which makes the editability-crossing check more specific*. However, I think a nicer approach would be to remove the check altogether and address the actual cause of the issue, which I think is a quirk in VisiblePosition::canonicalPosition. I haven't looked into it much further than that, however (it's a slightly mindbending method at first glance). * and renames accordingly.
Benjamin (Ben) Kalman
Comment 4
2010-12-13 23:22:52 PST
Oops, those 3 html snippets need sed run over them. sed s/contenteditable=false/contenteditable/g
Ryosuke Niwa
Comment 5
2010-12-13 23:36:12 PST
Comment on
attachment 76506
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=76506&action=review
Are we sure we want to make this change? I feel like previousBoundary can now cross editing boundaries and potentially return a position inside non-content editable area even when c is in content editable area. e.g. if we had something like <div contenteditable>hello wo<span contenteditable="false">rld W</span>ebkit</div>, do we still do the right thing? i.e. do not enter inside span when moving forward from hello by word.
> LayoutTests/ChangeLog:7 > +
Could you add a description as to what kind of test you're adding here?
> LayoutTests/editing/selection/extend-backward-by-word-over-non-editable-expected.txt:6 > +Tests that extending backwards over a non-contenteditable word only extends over that word > +| "foo bar <#selection-focus>" > +| <span> > +| contenteditable="false" > +| "baz" > +| "<#selection-anchor> qux quux"
Could you output PASS/FAIl based on the final selection? I'm concerned that people wrongfully rebaseline this test when this regresses or they'll have a hard time figuring out what is the right behavior. Printing PASS/FAIL makes it much easier to know what's correct and what's not.
> WebCore/ChangeLog:8 > + > + Test: editing/selection/extend-backward-by-word-over-non-editable.html
You need to describe what you're change is doing. I usually try to explain what caused the bug and how I fixed it.
> WebCore/editing/TextIterator.h:44 > - TextIteratorEndsAtEditingBoundary = 1 << 3, > + TextIteratorEndsWhenAscendsAcrossEditingBoundary = 1 << 3,
I'm not sure "when ascends across" is descriptive but I can't think of a better name now.
Benjamin (Ben) Kalman
Comment 6
2010-12-13 23:50:09 PST
Comment on
attachment 76506
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=76506&action=review
In response to your overall comment: yes it's fine, and doesn't break the case you describe. I also thought it might, checked it, and it must have always worked; I haven't looked into it too much, but there must be code elsewhere that prevents this from occurring. I think the only reason the weirdness happens here is due to something in VisiblePosition::canonicalPosition, as I mentioned. (Also note that the change which introduced TextIteratorEndsAtEditingBoundary was only committed a few months ago.) I'll fix up the other parts of this patch tonight or tomorrow morning.
>> WebCore/editing/TextIterator.h:44 >> + TextIteratorEndsWhenAscendsAcrossEditingBoundary = 1 << 3, > > I'm not sure "when ascends across" is descriptive but I can't think of a better name now.
I agree it sounds weird, but likewise couldn't think of a better name at the time.
Darin Adler
Comment 7
2010-12-14 10:01:42 PST
I’d like to hear Enrica’s thoughts on this change. She added the editable boundary machinery relatively recently. I’m concerned that this is a bit inflexible because only editable boundary changes that are immediate children are considered. Could there be cases where there is one additional level of nesting but are otherwise correct to handle in this manner?
Ryosuke Niwa
Comment 8
2010-12-14 10:31:44 PST
(In reply to
comment #6
)
> (From update of
attachment 76506
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=76506&action=review
> > In response to your overall comment: yes it's fine, and doesn't break the case you describe. I also thought it might, checked it, and it must have always worked; I haven't looked into it too much, but there must be code elsewhere that prevents this from occurring. I think the only reason the weirdness happens here is due to something in VisiblePosition::canonicalPosition, as I mentioned.
You're right. In the case of selection, we do fix that in respondToSelectionChange. However, previousWordPosition is also called by removeSpellAndCorrectionMarkersFromWordsToBeEdited also calls previousWordPosition. I don't see how it can be taking care of this problem. Also, I'm quite surprised that this fix only applies to previousBoundary and not to nextBoundary. Also I'd like to see some comment or better yet an encapsulation to prevent us from calling nextWordPosition & previousWordPosition wrongfully at places where crossing editing boundary is not okay.
Benjamin (Ben) Kalman
Comment 9
2010-12-14 16:08:57 PST
(In reply to
comment #7
)
> I’d like to hear Enrica’s thoughts on this change. She added the editable boundary machinery relatively recently.
I was under the impression these were added by morrita?
http://trac.webkit.org/changeset/64974
(this is the changeset linked to elsewhere in this bug report). The bug itself is
https://bugs.webkit.org/show_bug.cgi?id=36359
.
> > I’m concerned that this is a bit inflexible because only editable boundary changes that are immediate children are considered. Could there be cases where there is one additional level of nesting but are otherwise correct to handle in this manner?
Yes, there probably do exist corner cases. That said, this bug is caused by a regression from ~4 months ago, and as a tradeoff imo this bug is more important to fix. Not that I'm suggesting this is the right thing to do -- I will into VisiblePosition::canonicalPosition and its handling of contenteditable boundaries, and hopefully fix it there (and then remove the TextIteratorEndsAtEditingBoundary thing altogether).
Benjamin (Ben) Kalman
Comment 10
2010-12-14 16:14:28 PST
> You're right. In the case of selection, we do fix that in respondToSelectionChange. However, previousWordPosition is also called by removeSpellAndCorrectionMarkersFromWordsToBeEdited also calls previousWordPosition. I don't see how it can be taking care of this problem.
What problem to you mean?
> Also, I'm quite surprised that this fix only applies to previousBoundary and not to nextBoundary.
Only previousBoundary uses the TextIteratorEndsAtEditingBoundary, because the patch which caused the regression only changed previousBoundary. As I mentioned, there is indeed a bug with moving forward by words but I haven't looked into whether it's caused by nextBoundary.
> > Also I'd like to see some comment or better yet an encapsulation to prevent us from calling nextWordPosition & previousWordPosition wrongfully at places where crossing editing boundary is not okay.
I think that it was always fine, and the patch which caused this regression introduced the editing boundary crossing check purely to fix the bug addressed by the patch (
https://bugs.webkit.org/show_bug.cgi?id=36359
) i.e. cannot select a word in a contenteditable span at the start of a line.
Benjamin (Ben) Kalman
Comment 11
2010-12-16 23:40:27 PST
Created
attachment 76850
[details]
Patch
Benjamin (Ben) Kalman
Comment 12
2010-12-16 23:54:08 PST
After staring at the code for a while and playing with the debugger, the original patch doesn't make much sense. Instead, I've reverted the change[1] which caused this regression and fixed the problem in a different way[2]. [1] Adding editability boundary checks to TextIterator.h/cpp wasn't necessary; this is done elsewhere (rniwa: I can't find the respondToSelectionChange you mention, but anyway...). [2] This is the use-rightmost-Position stuff. Honestly I'm not entirely sure how legitimate that is, but it's a pretty clean way of fixing the bug imo. Otherwise I'd say, just revert the editability boundary check stuff and leave it at that.
Ryosuke Niwa
Comment 13
2010-12-17 01:08:57 PST
Comment on
attachment 76850
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=76850&action=review
> LayoutTests/editing/selection/extend-backward-by-word-over-non-editable-expected.txt:11 > +Dump of markup 2: > +| "PASS"
This doesn't look right. I don't think this is a good usage of dump-as-markup.
> LayoutTests/editing/selection/extend-backward-by-word-over-non-editable.html:19 > + Markup.description("Tests that extending backwards over a non-contenteditable word only extends over that word"); > + Markup.dump(textContainer); > + Markup.dump(result);
Is there any point in using dump-as-markup.js here? Doesn't printing PASS/FAIL suffice? I think we should just call dumpAsText() and print PASS/FAIL.
> WebCore/editing/visible_units.cpp:129 > + pos = it.range().get()->startPosition();
No need to call get(). We have overloaded operator->().
Ryosuke Niwa
Comment 14
2010-12-17 01:12:17 PST
(In reply to
comment #12
)
> After staring at the code for a while and playing with the debugger, the original patch doesn't make much sense. Instead, I've reverted the change[1] which caused this regression and fixed the problem in a different way[2].
You're probably referring to the changeset
http://trac.webkit.org/changeset/64974
but this change set moved some of editing boundary checks from visible_units into TextIterator. Your patch seems to revert the changes in TextIterator but does not introduce new checks into visible_units. How is this correct?
> [1] Adding editability boundary checks to TextIterator.h/cpp wasn't necessary; this is done elsewhere (rniwa: I can't find the respondToSelectionChange you mention, but anyway...).
I meant VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries.
Benjamin (Ben) Kalman
Comment 15
2010-12-17 01:22:46 PST
Comment on
attachment 76850
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=76850&action=review
>> LayoutTests/editing/selection/extend-backward-by-word-over-non-editable.html:19 >> + Markup.dump(result); > > Is there any point in using dump-as-markup.js here? Doesn't printing PASS/FAIL suffice? I think we should just call dumpAsText() and print PASS/FAIL.
Yes I suppose. otoh it might be nice to see if it fails what the failure is, and when running the test by hand at least this way it also says pass/fail in the dom.
>> WebCore/editing/visible_units.cpp:129 >> + pos = it.range().get()->startPosition(); > > No need to call get(). We have overloaded operator->().
oops, remnant of gdb reshuffling
Benjamin (Ben) Kalman
Comment 16
2010-12-17 01:29:10 PST
(In reply to
comment #14
)
> (In reply to
comment #12
) > > After staring at the code for a while and playing with the debugger, the original patch doesn't make much sense. Instead, I've reverted the change[1] which caused this regression and fixed the problem in a different way[2]. > > You're probably referring to the changeset
http://trac.webkit.org/changeset/64974
but this change set moved some of editing boundary checks from visible_units into TextIterator. Your patch seems to revert the changes in TextIterator but does not introduce new checks into visible_units. How is this correct?
Yep I'm referring to that changeset. It seems to me like the significant editability checks were moved to Position::parentEditingBoundary() as opposed to the text iterator changes that I reverted. The patch did multiple things, and has a non-trivial test, which still passes (and no other editing tests fail either).
> > > [1] Adding editability boundary checks to TextIterator.h/cpp wasn't necessary; this is done elsewhere (rniwa: I can't find the respondToSelectionChange you mention, but anyway...). > > I meant VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries.
Thanks.
Ryosuke Niwa
Comment 17
2010-12-17 01:44:32 PST
(In reply to
comment #15
)
> (From update of
attachment 76850
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=76850&action=review
> > >> LayoutTests/editing/selection/extend-backward-by-word-over-non-editable.html:19 > >> + Markup.dump(result); > > > > Is there any point in using dump-as-markup.js here? Doesn't printing PASS/FAIL suffice? I think we should just call dumpAsText() and print PASS/FAIL. > > Yes I suppose. otoh it might be nice to see if it fails what the failure is, and when running the test by hand at least this way it also says pass/fail in the dom.
I think we should just be informative in FAIL case. You could print information like "wrong offset" or "wrong container"
> Yep I'm referring to that changeset. It seems to me like the significant editability checks were moved to Position::parentEditingBoundary() as opposed to the text iterator changes that I reverted. The patch did multiple things, and has a non-trivial test, which still passes (and no other editing tests fail either).
Ah, now I see it. We should have Morrita-san & Ojan take a look at this patch regardless. I'm very scared of removing editing boundary checks because 1. I feel we don't have adequate test coverage and 2. we hit assertions if we try to modify non-editable nodes.
Darin Adler
Comment 18
2010-12-29 16:52:53 PST
Comment on
attachment 76850
[details]
Patch I don’t understand the status here. Ryosuke made a couple comments, but did not say review- or review+. I think the change is fine, but I think Ryosuke’s comments should be dealt with. Setting review+ and commit-queue- for now.
Benjamin (Ben) Kalman
Comment 19
2010-12-29 17:27:50 PST
Created
attachment 77653
[details]
Patch
Benjamin (Ben) Kalman
Comment 20
2010-12-29 17:31:21 PST
(In reply to
comment #18
)
> (From update of
attachment 76850
[details]
) > I don’t understand the status here. Ryosuke made a couple comments, but did not say review- or review+. I think the change is fine, but I think Ryosuke’s comments should be dealt with. Setting review+ and commit-queue- for now.
Coincidentally I was just (finally, after weeks) updating the patch when you replied to this. Thanks for looking at it. I've rewritten the test and fixed that typo as Ryosuke requested.
Darin Adler
Comment 21
2010-12-29 17:32:55 PST
Comment on
attachment 77653
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=77653&action=review
For now I’m setting commit-queue- because you might want to make changes based on my comments.
> WebCore/editing/TextIterator.cpp:1239 > +bool SimplifiedBackwardsTextIterator::setNodeIfNotNull(Node* node)
All this function does is an assignment statement and a null check. I think both call sites would be clearer if this was written there instead of using a function.
> WebCore/editing/visible_units.cpp:52 > +static Position rightmostEquivalent(Position p)
In WebKit code normally don’t use letters for names. The word “position” would be better than “p” given our usual style. Although there are quite a few counterexamples in this source file. For new code it would be better to use words.
Benjamin (Ben) Kalman
Comment 22
2010-12-29 17:47:56 PST
Created
attachment 77655
[details]
Patch
Benjamin (Ben) Kalman
Comment 23
2010-12-29 17:49:22 PST
(In reply to
comment #21
)
> (From update of
attachment 77653
[details]
) > View in context:
https://bugs.webkit.org/attachment.cgi?id=77653&action=review
> > For now I’m setting commit-queue- because you might want to make changes based on my comments. > > > WebCore/editing/TextIterator.cpp:1239 > > +bool SimplifiedBackwardsTextIterator::setNodeIfNotNull(Node* node) > > All this function does is an assignment statement and a null check. I think both call sites would be clearer if this was written there instead of using a function. > > > WebCore/editing/visible_units.cpp:52 > > +static Position rightmostEquivalent(Position p) > > In WebKit code normally don’t use letters for names. The word “position” would be better than “p” given our usual style. Although there are quite a few counterexamples in this source file. For new code it would be better to use words.
Thanks again.
Darin Adler
Comment 24
2010-12-29 17:54:25 PST
Comment on
attachment 77655
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=77655&action=review
> WebCore/editing/TextIterator.cpp:1143 > + if (!m_node->parentOrHostNode()) > break; > + m_node = m_node->parentOrHostNode();
I would have used a local variable here, but it’s probably fine not to.
WebKit Commit Bot
Comment 25
2010-12-29 18:45:34 PST
Comment on
attachment 77655
[details]
Patch Rejecting
attachment 77655
[details]
from commit-queue. Failed to run "['./Tools/Scripts/webkit-patch', '--status-host=queues.webkit.org', '--bot-id=cr-jail-4', 'build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive']" exit_code: 2 Last 500 characters of output: .................................................................................................................................................................................................................................... editing/spelling ......... editing/spelling/spelling-hasspellingmarker.html -> failed Exiting early after 1 failures. 5409 tests run. 112.57s total testing time 5408 test cases (99%) succeeded 1 test case (<1%) had incorrect layout 3 test cases (<1%) had stderr output Full output:
http://queues.webkit.org/results/7219245
Darin Adler
Comment 26
2010-12-30 10:59:38 PST
Comment on
attachment 77655
[details]
Patch Lets try the commit queue again.
WebKit Commit Bot
Comment 27
2010-12-30 11:32:43 PST
Comment on
attachment 77655
[details]
Patch Rejecting
attachment 77655
[details]
from commit-queue. Failed to run "['./Tools/Scripts/webkit-patch', '--status-host=queues.webkit.org', '--bot-id=cr-jail-3', 'build-and-test', '--no-clean', '--no-update', '--test', '--non-interactive']" exit_code: 2 Last 500 characters of output: .................................................................................................................................................................................................................................... editing/spelling ......... editing/spelling/spelling-hasspellingmarker.html -> failed Exiting early after 1 failures. 5409 tests run. 112.54s total testing time 5408 test cases (99%) succeeded 1 test case (<1%) had incorrect layout 3 test cases (<1%) had stderr output Full output:
http://queues.webkit.org/results/7284223
Eric Seidel (no email)
Comment 28
2010-12-30 11:59:28 PST
It appears this patch causes that test to regress. Sorry the cq isn't smart enough to upload failure diffs yet.
Ryosuke Niwa
Comment 29
2010-12-30 12:22:15 PST
As I noted in #c8, previousWordPosition is also called by removeSpellAndCorrectionMarkersFromWordsToBeEdited, and this patch seems to let spell-check code cross editing boundary, which is obviously not what we want. I wouldn't land this patch unless we investigated the failure and figured out what's the right thing to do.
Darin Adler
Comment 30
2010-12-30 12:44:09 PST
Comment on
attachment 77655
[details]
Patch Changing to review- beacuse of the regression test failure.
Benjamin (Ben) Kalman
Comment 31
2010-12-30 14:35:50 PST
(In reply to
comment #30
)
> (From update of
attachment 77655
[details]
) > Changing to review- beacuse of the regression test failure.
Thanks Darin and Ryosuke, I'll have a look at it when work starts up again next year.
Benjamin (Ben) Kalman
Comment 32
2011-01-05 19:22:11 PST
(In reply to
comment #29
)
> As I noted in #c8, previousWordPosition is also called by removeSpellAndCorrectionMarkersFromWordsToBeEdited, and this patch seems to let spell-check code cross editing boundary, which is obviously not what we want. I wouldn't land this patch unless we investigated the failure and figured out what's the right thing to do.
Remember that the editing boundary check removal here is just fixing a regression from a few months ago. I highly doubt that this patch will let spell check code cross editing boundaries. Anyway, I've looked into this some more. The test diff is -PASS hasMarked("<textarea id='test' cols='80' rows='10'></textarea>"); is true -PASS hasMarked("<input id='test' type='text'>"); is true +FAIL hasMarked("<textarea id='test' cols='80' rows='10'></textarea>"); should be true. Was false. +FAIL hasMarked("<input id='test' type='text'>"); should be true. Was false. PASS hasMarked("<div id='test' contenteditable='true'></div>"); is true PASS hasMarked("<div id='test' contentEditable='true' spellcheck='false'></div>"); is false PASS successfullyParsed is true Which is interesting because the spelling markers still work for <div><div contenteditable>zz</div></div> but not <div><textarea>zz</textarea></div> nor <div><input type="text" value="zz"></div> Which makes me think that this is actually a bug caused by the editing boundary being in a shadow dom, most probably triggered by the rightmostEquivalent change from previousBoundary. Perhaps an incorrect use of parentNode() rather than parentOrHostNode()? Or something more subtle?
Benjamin (Ben) Kalman
Comment 33
2011-01-05 19:52:23 PST
Actually, I'm wrong, it isn't rightmostEquivalent causing the problem but rather the removal of the editing check, causing the text iterator to apparently exit the shadow node but not reenter it as rightmostEquivalent would do in the <div> case.
Benjamin (Ben) Kalman
Comment 34
2011-01-11 16:46:43 PST
Created
attachment 78624
[details]
Patch with parentOrHostNode changed to parentNode
Benjamin (Ben) Kalman
Comment 35
2011-01-11 16:55:23 PST
(In reply to
comment #34
)
> Created an attachment (id=78624) [details] > Patch with parentOrHostNode changed to parentNode
I've uploaded a patch which fixes the test case by not allowing SimplifiedBackwardsTextIterator::advance to advance out of the shadow dom. It's not a nice solution, and probably incorrect so not submittable (though the layout tests all still pass). This means I'll probably have to look at an alternative solution to the rightmostEquivalent thing which makes the iterator always stay at the rightmost equivalent rather than not-doing-it-then-correcting-it-afterwards.
Benjamin (Ben) Kalman
Comment 36
2011-01-17 19:17:30 PST
Created
attachment 79237
[details]
Patch
WebKit Review Bot
Comment 37
2011-01-17 19:19:18 PST
Attachment 79237
[details]
did not pass style-queue: Failed to run "['Tools/Scripts/check-webkit-style', '--diff-files', u'LayoutTests/ChangeLog', u'LayoutTests/edit..." exit_code: 1 Source/WebCore/editing/TextIterator.cpp:1131: Tests for true/false, null/non-null, and zero/non-zero should all be done without equality comparisons. [readability/comparison_to_zero] [5] Total errors found: 1 in 8 files If any of these errors are false positives, please file a bug against check-webkit-style.
Benjamin (Ben) Kalman
Comment 38
2011-01-17 19:20:19 PST
Ugh. After far too much time trying to figure this out, finally done.
Benjamin (Ben) Kalman
Comment 39
2011-01-17 19:24:19 PST
Created
attachment 79238
[details]
Ugh. check-webkit-style.
Ryosuke Niwa
Comment 40
2011-01-17 19:45:00 PST
Comment on
attachment 79238
[details]
Ugh. check-webkit-style. View in context:
https://bugs.webkit.org/attachment.cgi?id=79238&action=review
> Source/WebCore/editing/visible_units.cpp:130 > - if (it.atEnd() && next == 0) { > + if (it.atEnd() && !next) > pos = it.range()->startPosition(); > - } else if (next != 0) { > + else if (next) {
I think it would have been cleaner if you did: if (!next) { if (it.atEnd()) pos = it.range()->startPosition(); return VisiblePosition(pos, DOWNSTREAM); } ...
Benjamin (Ben) Kalman
Comment 41
2011-01-17 19:48:59 PST
Comment on
attachment 79238
[details]
Ugh. check-webkit-style. View in context:
https://bugs.webkit.org/attachment.cgi?id=79238&action=review
Btw I've found that this is actually failing the test again. Very mysterious since all I did, I think, is sync. Maybe I changed something else too. Looking into it now.
>> Source/WebCore/editing/visible_units.cpp:130 >> + else if (next) { > > I think it would have been cleaner if you did: > if (!next) { > if (it.atEnd()) > pos = it.range()->startPosition(); > return VisiblePosition(pos, DOWNSTREAM); > } > ...
This particular change is just surrendering to check-webkit-style and its demanding ways. I can change it if you really want though.
Ryosuke Niwa
Comment 42
2011-01-17 19:54:20 PST
(In reply to
comment #41
)
> >> Source/WebCore/editing/visible_units.cpp:130 > >> + else if (next) { > > > > I think it would have been cleaner if you did: > > if (!next) { > > if (it.atEnd()) > > pos = it.range()->startPosition(); > > return VisiblePosition(pos, DOWNSTREAM); > > } > > ... > > This particular change is just surrendering to check-webkit-style and its demanding ways. I can change it if you really want though.
You can fix the style first in a separate patch.
Benjamin (Ben) Kalman
Comment 43
2011-01-18 16:02:08 PST
Created
attachment 79349
[details]
Patch
Ryosuke Niwa
Comment 44
2011-01-19 15:06:09 PST
Comment on
attachment 79349
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79349&action=review
> Source/WebCore/editing/Editor.cpp:2091 > - VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)); > + VisibleSelection adjacentWords = VisibleSelection(wordStart, endOfWord(wordStart, RightWordIfOnBoundary));
I'm scared of touching this code because it was added by
http://trac.webkit.org/changeset/41496
and I can't tell whether automated tests have been added or not. Could you manually verify that spellchecking works with your patch? Having said that, the only caller of this function seems to be TypingCommand::markMisspellingsAfterTyping and it calls startOfWord so this is probably correct change.
> Source/WebCore/editing/visible_units.cpp:59 > + Position next = position.next(); > + while (position.node() != next.node()) { > + position = next; > + next = position.next(); > + } > + return position;
Could you explain what "rightmost equivalent" mean?
Benjamin (Ben) Kalman
Comment 45
2011-01-19 16:05:50 PST
Comment on
attachment 79349
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79349&action=review
>> Source/WebCore/editing/Editor.cpp:2091 >> + VisibleSelection adjacentWords = VisibleSelection(wordStart, endOfWord(wordStart, RightWordIfOnBoundary)); > > I'm scared of touching this code because it was added by
http://trac.webkit.org/changeset/41496
and I can't tell whether automated tests have been added or not. Could you manually verify that spellchecking works with your patch? > > Having said that, the only caller of this function seems to be TypingCommand::markMisspellingsAfterTyping and it calls startOfWord so this is probably correct change.
Exactly. Not only is the extra startOfWord redundant (based on that single caller*), but it actually results in a bug since apparently startOfWord isn't idempotent if it's on an element boundary. That would be a nice thing to fix actually (unit tests!). There is a test, editing/spelling/spelling-hasspellingmarker. This isn't particularly rigorous (only checks "zz "), perhaps it would be a good idea to augment it with more than just a single word. zzzzzzzz * the fact that the variable is called wordStart implies that there should a precondition (i.e. ASSERT) that wordStart is actually the start of the word. Again -- this would be a good idea, if we had a way of checking that a position is actually the start of a word without "wordStart == startOfWord(wordStart)" which as I said isn't necessarily true due to non-idempotent nature of the function.
>> Source/WebCore/editing/visible_units.cpp:59 >> + return position; > > Could you explain what "rightmost equivalent" mean?
would rightmostVisuallyEquivalent be a more self-explanatory name?
Ryosuke Niwa
Comment 46
2011-01-19 16:09:54 PST
Comment on
attachment 79349
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79349&action=review
>>> Source/WebCore/editing/Editor.cpp:2091 >>> + VisibleSelection adjacentWords = VisibleSelection(wordStart, endOfWord(wordStart, RightWordIfOnBoundary)); >> >> I'm scared of touching this code because it was added by
http://trac.webkit.org/changeset/41496
and I can't tell whether automated tests have been added or not. Could you manually verify that spellchecking works with your patch? >> >> Having said that, the only caller of this function seems to be TypingCommand::markMisspellingsAfterTyping and it calls startOfWord so this is probably correct change. > > Exactly. Not only is the extra startOfWord redundant (based on that single caller*), but it actually results in a bug since apparently startOfWord isn't idempotent if it's on an element boundary. That would be a nice thing to fix actually (unit tests!). > > There is a test, editing/spelling/spelling-hasspellingmarker. This isn't particularly rigorous (only checks "zz "), perhaps it would be a good idea to augment it with more than just a single word. zzzzzzzz > > * the fact that the variable is called wordStart implies that there should a precondition (i.e. ASSERT) that wordStart is actually the start of the word. Again -- this would be a good idea, if we had a way of checking that a position is actually the start of a word without "wordStart == startOfWord(wordStart)" which as I said isn't necessarily true due to non-idempotent nature of the function.
Can we assert that ASSERT(wordStart == startOfWord(endOfWord(wordStart)) ? But I'm fine without this assertion because the argument name makes it pretty obvious.
>>> Source/WebCore/editing/visible_units.cpp:59 >>> + return position; >> >> Could you explain what "rightmost equivalent" mean? > > would rightmostVisuallyEquivalent be a more self-explanatory name?
What do you mean by "rightmost"? We could be either traversing the tree upwards or downwards. What kind of behavior are you expecting here?
Benjamin (Ben) Kalman
Comment 47
2011-01-19 16:28:14 PST
Comment on
attachment 79349
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79349&action=review
>>>> Source/WebCore/editing/Editor.cpp:2091 >>>> + VisibleSelection adjacentWords = VisibleSelection(wordStart, endOfWord(wordStart, RightWordIfOnBoundary)); >>> >>> I'm scared of touching this code because it was added by
http://trac.webkit.org/changeset/41496
and I can't tell whether automated tests have been added or not. Could you manually verify that spellchecking works with your patch? >>> >>> Having said that, the only caller of this function seems to be TypingCommand::markMisspellingsAfterTyping and it calls startOfWord so this is probably correct change. >> >> Exactly. Not only is the extra startOfWord redundant (based on that single caller*), but it actually results in a bug since apparently startOfWord isn't idempotent if it's on an element boundary. That would be a nice thing to fix actually (unit tests!). >> >> There is a test, editing/spelling/spelling-hasspellingmarker. This isn't particularly rigorous (only checks "zz "), perhaps it would be a good idea to augment it with more than just a single word. zzzzzzzz >> >> * the fact that the variable is called wordStart implies that there should a precondition (i.e. ASSERT) that wordStart is actually the start of the word. Again -- this would be a good idea, if we had a way of checking that a position is actually the start of a word without "wordStart == startOfWord(wordStart)" which as I said isn't necessarily true due to non-idempotent nature of the function. > > Can we assert that ASSERT(wordStart == startOfWord(endOfWord(wordStart)) ? But I'm fine without this assertion because the argument name makes it pretty obvious.
Yeah this is a pretty confusing assertion.
>>>> Source/WebCore/editing/visible_units.cpp:59 >>>> + return position; >>> >>> Could you explain what "rightmost equivalent" mean? >> >> would rightmostVisuallyEquivalent be a more self-explanatory name? > > What do you mean by "rightmost"? We could be either traversing the tree upwards or downwards. What kind of behavior are you expecting here?
Well, it should be agnostic to whether the next() position is upwards or downwards. In the sense that foo <span><span>bar |<b></b></span></span> baz is visually equivalent to, and the rightmost visually equivalent position to, foo <span><span>bar <b></b></span></span>| baz but it traverses up and down. is the correct terminology for this "upstream"? actually this function is possibly incorrect, in that i don't think |<div></div> is visually equivalent to <div></div>| sigh. the purpose is to normalise the position as in the former example.
Ryosuke Niwa
Comment 48
2011-01-19 17:01:47 PST
Comment on
attachment 79349
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79349&action=review
> Source/WebCore/editing/visible_units.cpp:140 > - return VisiblePosition(charIt.range()->endPosition(), DOWNSTREAM); > + // Take the rightmost equivalent position so that the correct containing editable region is used if a boundary is reached. > + return VisiblePosition(rightmostEquivalent(charIt.range()->endPosition()), DOWNSTREAM);
Note that a downstream VisiblePosition can be instantiated from a Position implicitly so this can be written as: return rightmostEquivalent(charIt.range()->endPosition()); But per IRC discussion, Kalman is going to experiment with adding a flag to canonicalPosition to ignore editing boundary.
Benjamin (Ben) Kalman
Comment 49
2011-01-19 23:54:13 PST
Gah. Why is this so difficult, it's such a trivial concept but I pull one way and somewhere else in the editing code, it pulls the other. Though at least the entire experience is very enlightening. Allowing editing boundaries to be optionally crossed from VisiblePosition's constructor did fix the problem from previousBoundary, but not nextBoundary; the latter causes a number of tests to fail, some due to a trivial difference in the render tree but others less trivial (about 3 tests like this). I think these are due to now-broken assumptions, so easy to fix, but overall this makes me nervous about the change. So in conclusion, to actually fix this bug... option 1: - submit the main part of the patch (reverting that boundary crossing stuff), - change that startOfWord(wordStart) to just wordStart to keep the incremental spell checking working, and then either - go back to the rightmostEquivalent thing, or something similar (i.e. making sure the Position passed to canonicalPosition is sane), or - keep pulling at the code option 2: - go back to something similar to the first patch I uploaded i.e. don't revert editing boundary stuff, but tweak it to be correct (adding code = sad) I might go with option 2 tomorrow since this is taking way too long.
Benjamin (Ben) Kalman
Comment 50
2011-01-20 22:50:21 PST
Created
attachment 79699
[details]
Patch
Benjamin (Ben) Kalman
Comment 51
2011-01-20 22:52:09 PST
(In reply to
comment #50
)
> Created an attachment (id=79699) [details] > Patch
Ok, much nicer. Looks like there was a subtle bug in SimplifiedBackwardsTextIterator's range checking after all that.
Benjamin (Ben) Kalman
Comment 52
2011-01-20 22:52:30 PST
(In reply to
comment #49
)
> Gah. Why is this so difficult, it's such a trivial concept but I pull one way and somewhere else in the editing code, it pulls the other. Though at least the entire experience is very enlightening. > > Allowing editing boundaries to be optionally crossed from VisiblePosition's constructor did fix the problem from previousBoundary, but not nextBoundary; the latter causes a number of tests to fail, some due to a trivial difference in the render tree but others less trivial (about 3 tests like this). I think these are due to now-broken assumptions, so easy to fix, but overall this makes me nervous about the change. > > So in conclusion, to actually fix this bug... > option 1: > - submit the main part of the patch (reverting that boundary crossing stuff), > - change that startOfWord(wordStart) to just wordStart to keep the incremental spell checking working, > and then either > - go back to the rightmostEquivalent thing, or something similar (i.e. making sure the Position passed to canonicalPosition is sane), or > - keep pulling at the code > > option 2: > - go back to something similar to the first patch I uploaded i.e. don't revert editing boundary stuff, but tweak it to be correct (adding code = sad) > > I might go with option 2 tomorrow since this is taking way too long.
(ignore this)
Ryosuke Niwa
Comment 53
2011-01-20 23:24:08 PST
Comment on
attachment 79699
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79699&action=review
The change looks good but I don't know enough about these classes to r+ this patch.
> Source/WebCore/editing/TextIterator.cpp:1225 > -bool SimplifiedBackwardsTextIterator::crossesEditingBoundary(Node* node) const > +bool SimplifiedBackwardsTextIterator::advanceToIfNonNullAndWithinRange(Node* next)
I'm not sure if advanceToIfNonNullAndWithinRange is the best name here. Maybe moveToNode? moveToNodeWithinRange? setNodeRespectingRange? setNodeIfPossible?
Benjamin (Ben) Kalman
Comment 54
2011-01-21 06:40:39 PST
Comment on
attachment 79699
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=79699&action=review
>> Source/WebCore/editing/TextIterator.cpp:1225 >> +bool SimplifiedBackwardsTextIterator::advanceToIfNonNullAndWithinRange(Node* next) > > I'm not sure if advanceToIfNonNullAndWithinRange is the best name here. Maybe moveToNode? moveToNodeWithinRange? setNodeRespectingRange? setNodeIfPossible?
The notnull part is probably unnecessary, but I used "advance" to mirror the method that called it, and it has more meaning than just "set". Don't feel strongly though.
Benjamin (Ben) Kalman
Comment 55
2011-01-23 16:51:55 PST
Created
attachment 79884
[details]
Change to advanceRespectingRange
Benjamin (Ben) Kalman
Comment 56
2011-01-24 22:28:08 PST
Created
attachment 80023
[details]
nicer factored test
Benjamin (Ben) Kalman
Comment 57
2011-01-24 22:57:37 PST
Created
attachment 80024
[details]
nicer factored test (2)
Benjamin (Ben) Kalman
Comment 58
2011-01-26 17:16:08 PST
Created
attachment 80273
[details]
rebase
Benjamin (Ben) Kalman
Comment 59
2011-02-02 15:45:43 PST
(In reply to
comment #58
)
> Created an attachment (id=80273) [details] > rebase
Could somebody review this please?
Benjamin (Ben) Kalman
Comment 60
2011-02-14 21:20:53 PST
(In reply to
comment #59
)
> (In reply to
comment #58
) > > Created an attachment (id=80273) [details] [details] > > rebase > > Could somebody review this please?
*polite re-ping*.
Benjamin (Ben) Kalman
Comment 61
2011-02-20 20:04:28 PST
Created
attachment 83122
[details]
Patch
Benjamin (Ben) Kalman
Comment 62
2011-02-22 22:00:48 PST
Created
attachment 83444
[details]
Patch
Benjamin (Ben) Kalman
Comment 63
2011-02-22 22:25:52 PST
Comment on
attachment 83444
[details]
Patch
>Subversion Revision: 79367 >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 1f8ef2638cda9a52ecc045b3edc46763f5fd0770..db908ebb1f123f34ceded9b27cf23c657a238f0c 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,15 @@ >+2011-02-23 Benjamin Kalman <
kalman@chromium.org
> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Moving or selecting backwards by words jumps to start of contenteditable region if contenteditable=false span is encountered >+
https://bugs.webkit.org/show_bug.cgi?id=51001
>+ >+ Add regression test. >+ >+ * editing/selection/extend-backward-by-word-over-non-editable-expected.txt: Added. >+ * editing/selection/extend-backward-by-word-over-non-editable.html: Added. >+ > 2011-02-22 Jer Noble <
jer.noble@apple.com
> > > Unreviewed; neglected to update an expected result after changing some >diff --git a/LayoutTests/editing/selection/extend-backward-by-word-over-non-editable-expected.txt b/LayoutTests/editing/selection/extend-backward-by-word-over-non-editable-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b52b0a9e799b23ea8d96a171fa59e247a983fe79 >--- /dev/null >+++ b/LayoutTests/editing/selection/extend-backward-by-word-over-non-editable-expected.txt >@@ -0,0 +1,4 @@ >+PASS for LTR >+PASS for RTL >+foo bar baz qux quux >+ש×Ö¼×¨× ×©×Ö¼×¨× ×©×Ö¼×¨× ×©×Ö¼×¨× ×©×Ö¼×¨× >diff --git a/LayoutTests/editing/selection/extend-backward-by-word-over-non-editable.html b/LayoutTests/editing/selection/extend-backward-by-word-over-non-editable.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6135db74fae40f62a34f59d39f29e7a665630d10 >--- /dev/null >+++ b/LayoutTests/editing/selection/extend-backward-by-word-over-non-editable.html >@@ -0,0 +1,39 @@ >+<!DOCTYPE html> >+<pre id="log"></pre> >+ >+<div id="ltrTextContainer" contenteditable>foo bar <span contenteditable=false>baz</span> qux quux</div> >+<div id="rtlTextContainer" contenteditable dir="rtl">שוּרה שוּרה >+<span contenteditable=false>שוּרה</span> >+שוּרה שוּרה</div> >+ >+<script> >+function log(s) { >+ document.getElementById("log").appendChild(document.createTextNode(s + "\n")); >+} >+ >+function placeCursorAfterFirstNoneditableChild(container) { >+ for (var i = 0; i < container.childNodes.length; i++) { >+ var node = container.childNodes[i]; >+ if (node.isContentEditable !== undefined && !node.isContentEditable) { >+ getSelection().setPosition(node.nextSibling, 0); >+ return node; >+ } >+ } >+ throw "Couldn't find noneditable child of " + container.textContent; >+} >+ >+function extendBackwardByWord(container, bidiName) { >+ noneditableChild = placeCursorAfterFirstNoneditableChild(container); >+ getSelection().modify("extend", "backward", "word"); >+ if (getSelection().toString() === noneditableChild.textContent) >+ log("PASS for " + bidiName); >+ else >+ log("FAIL for " + bidiName + ", selection is \"" + getSelection() + "\" but should be \"" + noneditableChild.textContent + "\""); >+} >+ >+extendBackwardByWord(document.getElementById("ltrTextContainer"), "LTR"); >+extendBackwardByWord(document.getElementById("rtlTextContainer"), "RTL"); >+ >+if (window.layoutTestController) >+ layoutTestController.dumpAsText(); >+</script> >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index af6dc60037807c36724ce6df9520f6f847a3de26..7b3ff2e8dbd982a4ef76a540cdc7e43bd03111a4 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,36 @@ >+2011-02-23 Benjamin Kalman <
kalman@chromium.org
> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Moving or selecting backwards by words jumps to start of contenteditable region if contenteditable=false span is encountered >+
https://bugs.webkit.org/show_bug.cgi?id=51001
>+ >+ Test: editing/selection/extend-backward-by-word-over-non-editable.html >+ >+ Revert some previous changes (the TextIteratorEndsAtEditingBoundary text iteration behaviour) which caused this >+ bug in the first place, and fix SimplifiedBackwardsTextIterator's iteration range check as an alternative fix. >+ >+ The original bug was that double-clicking on an inline editable span at the start of a paragraph would clear the >+ selection (
webkit.org/b/36360
). This was caused by upstream/downstream VisbiblePosition complications. To fix, >+ refuse to iterate beyond the start node (rather than refusing to iterate across editable boundaries, which >+ causes this bug). >+ >+ To see why this is correct, and to make it clearer that is indeed what is happening, the text iterator code has >+ been slightly restructured to express the invariant that the iterator will never advance past the start node. >+ >+ * editing/TextIterator.cpp: >+ (WebCore::TextIterator::TextIterator): Remove references to TextIterationEndsAtEditing boundary. >+ (WebCore::SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator): Remove m_pastStartNode as the >+ mechanism for iteration range checking, and use a flag m_havePassedStartNode instead. >+ (WebCore::SimplifiedBackwardsTextIterator::advance): Clean up, use advanceRespectingRange and >+ m_havePassedStartNode for iteration range checking rather than m_pastStartNode. >+ (WebCore::SimplifiedBackwardsTextIterator::advanceRespectingRange): The new way of modifying m_node >+ which updates m_havePassedStartNode and refuses to continue when it becomes true. >+ * editing/TextIterator.h: Remove TextIteratorEndsAtEditingBoundary, update for new/removed prototypes and >+ member variables. >+ * editing/visible_units.cpp: >+ (WebCore::previousBoundary): Remove references to TextIteratorEndsAtEditingBoundary. >+ > 2011-02-22 Geoffrey Garen <
ggaren@apple.com
> > > Reviewed by Oliver Hunt. >diff --git a/Source/WebCore/editing/TextIterator.cpp b/Source/WebCore/editing/TextIterator.cpp >index d3a65964f7e07286ecb273764324d56f1a5c8125..3b18127552af33b6358e150dc660f3412f8b0dc2 100644 >--- a/Source/WebCore/editing/TextIterator.cpp >+++ b/Source/WebCore/editing/TextIterator.cpp >@@ -194,21 +194,6 @@ static Node* nextInPreOrderCrossingShadowBoundaries(Node* rangeEndContainer, int > return 0; > } > >-static Node* previousInPostOrderCrossingShadowBoundaries(Node* rangeStartContainer, int rangeStartOffset) >-{ >- if (!rangeStartContainer) >- return 0; >- if (rangeStartOffset > 0 && !rangeStartContainer->offsetInCharacters()) { >- if (Node* previous = rangeStartContainer->childNode(rangeStartOffset - 1)) >- return previous; >- } >- for (Node* node = rangeStartContainer; node; node = node->parentOrHostNode()) { >- if (Node* previous = node->previousSibling()) >- return previous; >- } >- return 0; >-} >- > // -------- > > static inline bool fullyClipsContents(Node* node) >@@ -290,9 +275,6 @@ TextIterator::TextIterator(const Range* r, TextIteratorBehavior behavior) > , m_handledFirstLetter(false) > , m_ignoresStyleVisibility(behavior & TextIteratorIgnoresStyleVisibility) > { >- // FIXME: should support TextIteratorEndsAtEditingBoundary
http://webkit.org/b/43609
>- ASSERT(behavior != TextIteratorEndsAtEditingBoundary); >- > if (!r) > return; > >@@ -1052,7 +1034,7 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, > , m_node(0) > , m_positionNode(0) > { >- ASSERT(m_behavior == TextIteratorDefaultBehavior || m_behavior == TextIteratorEndsAtEditingBoundary); >+ ASSERT(m_behavior == TextIteratorDefaultBehavior); > > if (!r) > return; >@@ -1077,7 +1059,7 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, > } > } > >- setCurrentNode(endNode); >+ m_node = endNode; > setUpFullyClippedStack(m_fullyClippedStack, m_node); > m_offset = endOffset; > m_handledNode = false; >@@ -1096,7 +1078,7 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, > m_lastTextNode = 0; > m_lastCharacter = '\n'; > >- m_pastStartNode = previousInPostOrderCrossingShadowBoundaries(startNode, startOffset); >+ m_havePassedStartNode = false; > > advance(); > } >@@ -1108,7 +1090,7 @@ void SimplifiedBackwardsTextIterator::advance() > m_positionNode = 0; > m_textLength = 0; > >- while (m_node && m_node != m_pastStartNode) { >+ while (m_node && !m_havePassedStartNode) { > // Don't handle node if we start iterating at [node, 0]. > if (!m_handledNode && !(m_node == m_endNode && m_endOffset == 0)) { > RenderObject* renderer = m_node->renderer(); >@@ -1125,8 +1107,10 @@ void SimplifiedBackwardsTextIterator::advance() > return; > } > >- Node* next = m_handledChildren ? 0 : m_node->lastChild(); >- if (!next) { >+ if (!m_handledChildren && m_node->hasChildNodes()) { >+ m_node = m_node->lastChild(); >+ pushFullyClippedState(m_fullyClippedStack, m_node); >+ } else { > // Exit empty containers as we pass over them or containers > // where [container, 0] is where we started iterating. > if (!m_handledNode >@@ -1138,11 +1122,12 @@ void SimplifiedBackwardsTextIterator::advance() > m_handledNode = true; > m_handledChildren = true; > return; >- } >+ } > } >+ > // Exit all other containers. > while (!m_node->previousSibling()) { >- if (!setCurrentNode(m_node->parentOrHostNode())) >+ if (!advanceRespectingRange(m_node->parentOrHostNode())) > break; > m_fullyClippedStack.pop(); > exitNode(); >@@ -1153,14 +1138,12 @@ void SimplifiedBackwardsTextIterator::advance() > } > } > >- next = m_node->previousSibling(); > m_fullyClippedStack.pop(); >+ if (advanceRespectingRange(m_node->previousSibling())) >+ pushFullyClippedState(m_fullyClippedStack, m_node); >+ else >+ m_node = 0; > } >- >- if (m_node && setCurrentNode(next)) >- pushFullyClippedState(m_fullyClippedStack, m_node); >- else >- clearCurrentNode(); > > // For the purpose of word boundary detection, > // we should iterate all visible text and trailing (collapsed) whitespaces. >@@ -1240,26 +1223,17 @@ void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node* node, int sta > m_lastCharacter = c; > } > >-bool SimplifiedBackwardsTextIterator::crossesEditingBoundary(Node* node) const >+bool SimplifiedBackwardsTextIterator::advanceRespectingRange(Node* next) > { >- return m_node && m_node->isContentEditable() != node->isContentEditable(); >-} >- >-bool SimplifiedBackwardsTextIterator::setCurrentNode(Node* node) >-{ >- if (!node) >+ if (!next) > return false; >- if (m_behavior == TextIteratorEndsAtEditingBoundary && crossesEditingBoundary(node)) >+ m_havePassedStartNode |= m_node == m_startNode; >+ if (m_havePassedStartNode) > return false; >- m_node = node; >+ m_node = next; > return true; > } > >-void SimplifiedBackwardsTextIterator::clearCurrentNode() >-{ >- m_node = 0; >-} >- > PassRefPtr<Range> SimplifiedBackwardsTextIterator::range() const > { > if (m_positionNode) >diff --git a/Source/WebCore/editing/TextIterator.h b/Source/WebCore/editing/TextIterator.h >index 8b61afe211b4d37b74f9f4a58237e1d28f2dcfb4..b0c310a6fc7e8011b4a44c2afc1cda02dd4249d3 100644 >--- a/Source/WebCore/editing/TextIterator.h >+++ b/Source/WebCore/editing/TextIterator.h >@@ -41,8 +41,7 @@ enum TextIteratorBehavior { > TextIteratorEmitsCharactersBetweenAllVisiblePositions = 1 << 0, > TextIteratorEntersTextControls = 1 << 1, > TextIteratorEmitsTextsWithoutTranscoding = 1 << 2, >- TextIteratorEndsAtEditingBoundary = 1 << 3, >- TextIteratorIgnoresStyleVisibility = 1 << 4 >+ TextIteratorIgnoresStyleVisibility = 1 << 3 > }; > > // FIXME: Can't really answer this question correctly without knowing the white-space mode. >@@ -205,9 +204,7 @@ private: > bool handleReplacedElement(); > bool handleNonTextNode(); > void emitCharacter(UChar, Node*, int startOffset, int endOffset); >- bool crossesEditingBoundary(Node*) const; >- bool setCurrentNode(Node*); >- void clearCurrentNode(); >+ bool advanceRespectingRange(Node*); > > TextIteratorBehavior m_behavior; > // Current position, not necessarily of the text being returned, but position >@@ -238,9 +235,9 @@ private: > > // Used for whitespace characters that aren't in the DOM, so we can point at them. > UChar m_singleCharacterBuffer; >- >- // The node after the last node this iterator should process. >- Node* m_pastStartNode; >+ >+ // Whether m_node has advanced beyond the iteration range (i.e. m_startNode). >+ bool m_havePassedStartNode; > }; > > // Builds on the text iterator, adding a character position so we can walk one >diff --git a/Source/WebCore/editing/visible_units.cpp b/Source/WebCore/editing/visible_units.cpp >index 281bc41c4b7b6383261418a4ac9393bd10a42da5..9cb4d6d0516b4ee24d60e12b41560f7266a938e8 100644 >--- a/Source/WebCore/editing/visible_units.cpp >+++ b/Source/WebCore/editing/visible_units.cpp >@@ -89,7 +89,7 @@ static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch > if (ec) > return VisiblePosition(); > >- SimplifiedBackwardsTextIterator it(searchRange.get(), TextIteratorEndsAtEditingBoundary); >+ SimplifiedBackwardsTextIterator it(searchRange.get()); > unsigned next = 0; > bool inTextSecurityMode = start.deprecatedNode() && start.deprecatedNode()->renderer() && start.deprecatedNode()->renderer()->style()->textSecurity() != TSNONE; > bool needMoreContext = false; >@@ -124,7 +124,7 @@ static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch > return VisiblePosition(Position(node, next), DOWNSTREAM); > > // Use the character iterator to translate the next value into a DOM position. >- BackwardsCharacterIterator charIt(searchRange.get(), TextIteratorEndsAtEditingBoundary); >+ BackwardsCharacterIterator charIt(searchRange.get()); > charIt.advance(string.size() - suffixLength - next); > return VisiblePosition(charIt.range()->endPosition(), DOWNSTREAM); > }
Benjamin (Ben) Kalman
Comment 64
2011-02-22 22:26:31 PST
oops
Benjamin (Ben) Kalman
Comment 65
2011-02-22 22:28:56 PST
Created
attachment 83447
[details]
Patch with correct svn version
Benjamin (Ben) Kalman
Comment 66
2011-02-22 23:00:18 PST
Created
attachment 83450
[details]
Patch for landing
WebKit Commit Bot
Comment 67
2011-02-23 02:08:44 PST
The commit-queue encountered the following flaky tests while processing
attachment 83450
[details]
: fast/css/font-face-download-error.html
bug 51757
(author:
yuzo@google.com
) The commit-queue is continuing to process your patch.
WebKit Commit Bot
Comment 68
2011-02-23 02:10:29 PST
Comment on
attachment 83450
[details]
Patch for landing Clearing flags on attachment: 83450 Committed
r79429
: <
http://trac.webkit.org/changeset/79429
>
WebKit Commit Bot
Comment 69
2011-02-23 02:10:39 PST
All reviewed patches have been landed. Closing bug.
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