Last Comment Bug 696571 - Less than half selection extends left-range outside of selection across nodes
: Less than half selection extends left-range outside of selection across nodes
Status: UNCONFIRMED
: testcase
Product: Core
Classification: Components
Component: Selection (show other bugs)
: unspecified
: All All
: -- minor with 1 vote (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
:
Mentors:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-10-22 05:30 PDT by John A. Bilicki III
Modified: 2012-06-01 03:59 PDT (History)
3 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
Test Case 1 (758 bytes, application/xhtml+xml)
2011-10-23 06:50 PDT, John A. Bilicki III
no flags Details
Test Case 2 (1.40 KB, application/xhtml+xml)
2011-10-23 10:11 PDT, Mats Palmgren (:mats)
no flags Details
Test case 3, there are four ways to select the text applicable to the bug. (6.54 KB, application/xhtml+xml)
2011-11-03 18:19 PDT, John A. Bilicki III
no flags Details
Test case 3.1, fixed a bug where j-- would make the script attempt to select a node with a negative index. (6.59 KB, application/octet-stream)
2011-11-04 20:45 PDT, John A. Bilicki III
no flags Details
Test case 3.2, JavaScript alert dialogs are now used to clearly inform you of the status of your selection. (8.28 KB, application/octet-stream)
2011-11-04 21:25 PDT, John A. Bilicki III
no flags Details
Test case 3.3, fixed bugs in previous versions of test case 3 and tested extensively. (7.23 KB, application/octet-stream)
2011-11-07 00:26 PST, John A. Bilicki III
no flags Details

Description John A. Bilicki III 2011-10-22 05:30:03 PDT
Let's say you have the following XHTML...

<p>1111 <s>2222</s> 1111 <s>2222</s> 1111 <s>2222</s> </p>

The selection bug occurs when you less-than-half select the last '1' character and drag the mouse right to select part of the 's' element (in part of whole it seems, trivial).

This won't matter if you're trying to work with range and s[0] however Gecko selects s[0] regardless of WHICH s[i] you choose. I have confirmed this using methods such as compareDocumentPosition and offsetLeft/offsetTop.

The problem is that the selection area is very small. Since the character was NOT fully selected (I presume fully means 50% of it's width or greater) that the browser sets the SELECTION to the next character to the right HOWEVER the RANGE seems to consider it part of the selection even though the horizontal width was not sufficient to include it in the SELECTED text. Therefore I think this issue is a disagreement between RANGE and SELECTION. This issue does NOT occur in any of the other browsers.

The reason this bug is very nasty is because there is absolutely no reliable method to determine which s[i] was selected. If none of the s[i] elements have the same toString as the selected s[i] then it might be possible however it is not if there are multiple instances where the s element's textNode match exactly.

I do not have the time to make a test case this morning, I might be able to later today though if anyone wants to test it before then I HIGHLY recommend setting the font-size to 40px or greater in order to make it easy to partially (less than half the width of the character, not making it visually part of the selection but having Gecko add it to the range) select the text (left to right) from s[1] or a later s element.
Comment 1 John A. Bilicki III 2011-10-23 06:50:24 PDT
Created attachment 568948 [details]
Test Case 1

The test case is very simple, simply select the text just to the left of the red border (without the visual selection including the space to the left) or do the same from the right side and click the button. In Opera 11.5, Safari 5.1 and Chrome 14 the node.childNodes.length is 1 unless the selection visually includes the space in which case then yes it is correct to have two childNodes selected. This test case was tested on Windows XP 64 Bit.
Comment 2 Mats Palmgren (:mats) 2011-10-23 10:11:19 PDT
Created attachment 568956 [details]
Test Case 2

I think the range is more correct in Firefox than in Chrome given how
the selection is being done.  The result in Chrome misses the fact
the selection gesture passed over the <em> start boundary so the
resulting cloneContents() fragment doesn't have <em>2</em> just "2"
which might matter in an editing context.

I guess we could avoid the empty text node in the result by setting
the start position between the first text node and the <em> (at <p> / 1).

Consider also what happens when selecting the text as suggested and
then typing DEL vs. BACKSPACE and then typing text.  Chrome inserts
text before the <em> in both cases which seems wrong for BACKSPACE.

(tested with Firefox trunk / Chrome 16, both on Linux)
Comment 3 John A. Bilicki III 2011-10-23 10:22:54 PDT
Actually this is a normal level bug because mot people are not going to be aware of a bug where (at normal / low text size levels) that users have unknowingly selected more nodes then they intended.

The most important part of the bug problem is that if you have more than one child element (say an 's' element) that have the EXACT same nodeValues (e.g. <s>111</s> 222 <s>111</s>) Gecko does NOT correctly select the second 's' element, it instead selects the first 's' element in those circumstances. So there is NO work around in such cases for correctly working with the DOM if there are other elements with the exact same nodeValue, the script has no choice but to ignore the request. I can create another test case (either later today or sometime tomorrow) to demonstrate this with and without patching.
Comment 4 Mats Palmgren (:mats) 2011-10-27 22:23:00 PDT
(In reply to John A. Bilicki III from comment #3)
> The most important part of the bug problem is that if you have more than one
> child element (say an 's' element) that have the EXACT same nodeValues (e.g.
> <s>111</s> 222 <s>111</s>) Gecko does NOT correctly select the second 's'
> element, it instead selects the first 's' element in those circumstances.

Do you have a test that demonstrates this problem?
Comment 5 John A. Bilicki III 2011-10-28 11:44:17 PDT
Mats, your modification to my test case is brilliant, thank you for creating a visual example.

I can't make a full test case just yet however I can at least clarify how I'm approaching the issue and how it's causing problems...

I'm building a rich text editor. For text editing I essentially have to start with determining how many nodes are selected...

**********

var c = window.getSelection().getRangeAt(0).cloneContents();

if (c.childNodes.length==1) {alert('Selected one node.');}
else if (c.childNodes.length==2) {alert('Selected two nodes.');}
else if (c.childNodes.length==3) {alert('Selected three nodes.');}
else {alert('Selected '+c.childNodes.length+' nodes.');}

**********

The problem for me is that when a single node (the red bordered em element in the test cases) is selected the user might unintentionally overshoot their selection in a Gecko browser. That immediately changes the condition from (c.childNodes.length==1) in other browsers to (c.childNodes.length==2) for Gecko alone. This has ended up being a much nastier bug for me to deal with than a very large percentage of early Trident issues.

The ranges should be limited to ONLY the actually selected text and they are not in Gecko. I will try to find some time sometime next week (busy until then) to produce a new test case to demonstrate how I have had to determine which element was intended for selection, count the selection length, remove all ranges and manually reselect the correct range for the user in order to make this work.
Comment 6 John A. Bilicki III 2011-11-03 18:19:48 PDT
Created attachment 571862 [details]
Test case 3, there are four ways to select the text applicable to the bug.

I've attached a test case demonstrating the large amount of code needed to work around this bug. I've added a visual status that displays what has been selected.

There are four applicable scenarios...

1.) The user selects the left portion of an emphasis element, selection made left-to-right.

2.) The user selects the left portion of an emphasis element, selection made right-to-left.

3.) The user selects the right portion of an emphasis element, selection made right-to-left.

4.) The user selects the right portion of an emphasis element, selection made left-to-right.

When selecting the text in the applicable way the status text will update letting you know which side of the element you've selected and which direction (left-to-right or right-to-left) you made when selecting the text. If someone testing test case file #3 does not see this when selecting the text and pressing the button then they are not partially selecting (less than half though greater than 0 pixels) of the adjacent text node.

Each scenario requires some slight modification further complicating the fix specific to Gecko browsers. All other browsers I've tested only select a single node thus bypassing any need for this fix. This bug took roughly a week and a half to make transparent at a user level. Since text on websites is usually smaller it's very likely that numerous developers and end-users have encountered this issue and are NOT able to explain what is happening in Gecko based browsers so under the given circumstances I would consider this a normal bug instead of a minor bug.
Comment 7 Mats Palmgren (:mats) 2011-11-04 00:53:44 PDT
John, do you have a test that demonstrates the problem in comment 4?
Comment 8 John A. Bilicki III 2011-11-04 01:03:21 PDT
Mat, lines 40-96 exist ONLY for this bug. Line 40 starts with...

else if (c.childNodes.length==2)

Try the third test case file in Chrome, IE9+, Opera, or Safari and it should tell you that there is only one node in the selection, they will all use the FIRST condition (c.childNodes.length==1).

Remember, you need to select just outside of an emphasis element (regardless of which side) just enough that Gecko selects two nodes though not so much that a space character is selected. The status text field is used to tell you if your selection is applicable to the concerns of this bug report. If you need further clarification I'll be happy to help however I can.
Comment 9 Mats Palmgren (:mats) 2011-11-04 01:26:59 PDT
I'm not talking about the latest test.  You claimed in comment 3 that selecting
two *different* DOM text nodes that happened to have the same text contents "111"
resulted in a range with only one text node... or something.  I want to know if you
have a test that demonstrates this, or if it just a mistake.
Comment 10 Mats Palmgren (:mats) 2011-11-04 02:07:19 PDT
As far as I can tell, Test case 3 doesn't show anything new compared to
the earlier tests which I've already commented on in comment 2.
To be clear, I don't consider this to be a bug.

Looking at Test case 3, are you trying to delete the selected text?
In that case, why not simply use Range.deleteContents() - it should work
in all browsers regardless of what the range looks like.
http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-range
Comment 11 John A. Bilicki III 2011-11-04 20:45:13 PDT
Created attachment 572165 [details]
Test case 3.1, fixed a bug where j-- would make the script attempt to select a node with a negative index.

I fixed a bug where if you selected text in the FIRST paragraph (p[0]) the j variable in the script would become a negative value thus breaking the script as JavaScript does not allow nodes to have negative index numbers.
Comment 12 John A. Bilicki III 2011-11-04 20:50:47 PDT
Mats, the ENTIRE second condition (else if (c.childNodes.length==2)) in the function editor_text(e) exists SOLELY because of this bug. Add an alert to the first line of each condition to note how many nodes are selected and then run the test in every browser (Firefox, Internet Explorer, Opera and Safari). Only Gecko browsers will select two nodes when slightly selecting text outside of an emphasis element but not enough to have the space on either side become part of the VISUAL selection. Keep in mind that you shouldn't select the ENTIRE emphasis element, only part of it (there are 13 characters, select 12 or less and start or end the selection by selecting only a few pixels of a space in either adjacent textNode to the right or left). This bug requires very astute attention to detail to catch though before I realized I had found a bug I had no problem encountering it while testing the editor I'm working on from an end-users perspective.
Comment 13 John A. Bilicki III 2011-11-04 21:25:36 PDT
Created attachment 572172 [details]
Test case 3.2, JavaScript alert dialogs are now used to clearly inform you of the status of your selection.

Mats, to make test case 3 as clear as possible I have added JavaScript alert dialogs to help clarify the status of your selection. There are two notice types, normal notice and bug notice. Normal notice merely alerts you that your current selection does not involve this bug. Bug notice alert dialogs (four of them) will only occur if your current text selection correlates with this bug. If this does not clarify the bug enough I will be happy to produce a video with the cursor video to visually demonstrate how the text needs to be selected in order to trigger this bug.
Comment 14 John A. Bilicki III 2011-11-05 03:09:12 PDT
After doing some test I've noticed some issues with selecting an emphasis element from left-to-right on the left side of the element. I have an idea of what is causing this and will upload test case 3.3 soon, likely in a day or two. The other ways to select text seem to work fine in test case 3.2 (left side: right-to-left and right side: left-to-right and right-to-left).
Comment 15 John A. Bilicki III 2011-11-07 00:26:29 PST
Created attachment 572402 [details]
Test case 3.3, fixed bugs in previous versions of test case 3 and tested extensively.

I have fixed all the remaining bugs I can find in test case 3 in version 3.3 and have done extensive testing to ensure there aren't any errors in the console regardless of how you select the text.

The JavaScript alert dialogs should help clarify when you have or have not selected text in a way that is applicable to this bug.

Note You need to log in before you can comment on or make changes to this bug.