Triple-clicking <dd> element and copying includes stray non-rendered whitespace




2 years ago
25 days ago


(Reporter: emorley, Unassigned)




Firefox Tracking Flags

(firefox50 affected)



(1 attachment)

Created attachment 8767960 [details]

In Treeherder we have a API key credentials management page, where people can request an API key, and then copy the key from the page.

However the keys contain hyphens, so a typical "double click to select text" doesn't work - so a triple-click is required instead.

However doing so in Firefox results in leading whitespace, which causes auth failures if people paste this directly in without checking.


1) Load testcase.html
2) Triple-click the api key secret to select it
3) Ctrl+C
4) Paste somewhere

Pasted string is: "abcdef-123456"

Pasted string is: "    abcdef-123456"

Using Nightly on Windows 10.

See also bug 819266, bug 1042630.
Attachment #8767960 - Attachment mime type: text/plain → text/html
Whereas in Chrome 52.0.2743.60 beta-m, there is no leading whitespace.

Boris/Ehsan, could you suggest who might be a good candidate to ask about this? :-)
Possibly related to Android longtouch selection initiation:

Bug 1241276 - Interesting edge case - both AccessibleCaret Handles visible with collapsed selection
The big difference is what exactly triple-clicking selects, not the copying.  In Gecko, after triple-clicking:

> getSelection().getRangeAt(0)
Range { startContainer: <dd>, startOffset: 0, endContainer: <dd>, endOffset: 1, collapsed: false, commonAncestorContainer: <dd> }

whereas in Chrome:

> getSelection().getRangeAt(0)
Range {startContainer: text, startOffset: 0, endContainer: text, endOffset: 13, collapsed: false…}

So in Gecko the selected bit is "all the contents of this <dd>" and in Chrome it's "the first 13 characters of this textnode".

Anyway, then we go to serialize to plaintext and I expect end up at nsPlainTextSerializer::DoOpenContainer which does:

  mIndent += kIndentSizeDD;

kIndentSizeDD is 4, which is what you're seeing.

This actually seems a bit fishy to me.  Why are we ending up in DoOpenContainer for this thing that's not really in our range?
Hmm.  So when I stop in a debugger during serialization, the range we're using has the <dl> as the start/endContainer and offsets that mean it's selecting the whole <dd>, not just the contents of the <dd>.  That explains why we reach DoOpenContainer for the <dd>.

I see what happened here.  nsHTMLCopyEncoder::SetSelection does this bit:

1514        // adjust range to include any ancestors who's children are entirely selected
1515        rv = PromoteRange(myRange);

which is how we end up with a range containing the <dd> as well.  <sigh>.
Thank you for taking a look at this Boris :-)
Reproducible with latest Nightly:
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0
Built from
You need to log in before you can comment on or make changes to this bug.