Closed Bug 1930277 Opened 1 year ago Closed 1 year ago

Drag-and-drop in `<span contenteditable>` generates a new nested span around the dragged text

Categories

(Core :: DOM: Serializers, defect)

defect

Tracking

()

RESOLVED FIXED
134 Branch
Tracking Status
firefox134 --- fixed

People

(Reporter: dholbert, Assigned: masayuki)

References

Details

(Keywords: webcompat:platform-bug)

Attachments

(4 files)

STR:

  1. Load attached testcase in Firefox on Windows or macOS.
  2. Double-click to select the text "def"
  3. Click and drag that selected text to somewhere else in the string -- e.g. drop it between "b" and "c".

ACTUAL RESULTS:
Firefox generates a new nested <span> to wrap the dragged text, as can be seen by:

  • An extra border is added around the drag-and-dropped text.
  • The text suddenly gets bigger (its font-size: 2em is now resolving against the outer span's already-doubled font-size, instead of resolving against the outer font-size).

EXPECTED RESULTS:
No duplicate span -- no extra border, no change in font-size.

This is specific to Windows & macOS because drag-and-drop of text in a contenteditable doesn't seem to work on Ubuntu Linux, as mentioned in bug 1891427 comment 0.

Chrome gives EXPECTED RESULTS, though they do insert a <br> linebreak around the insertion point for some reason. (Though that linebreak can be suppressed in Chrome with -webkit-user-modify: read-write-plaintext-only, which I'll file a separate bug about EDIT: I'll hold off on filing a bug on that for now, since here at least, that prefixed property serves as a paper-over for a problem that we don't currently have.)

Attached file testcase 1
Blocks: 1891427
Summary: Drag-and-drop in <span contenteditable> generates a new nested span around the dragged text → Drag-and-drop in `<span contenteditable>` generates a new nested span around the dragged text
Attachment #9436552 - Attachment mime type: text/plain → text/html
Attachment #9436553 - Attachment mime type: text/plain → text/html

Our behavior here seems to specifically affect span but not div -- this is regardless of the display value. So Firefox gives me ACTUAL RESULTS on each part of testcase 2, vs. EXPECTED RESULTS on each part of testcase 3.

masayuki: do you know why our behavior here happens to depend on the tag name being span vs div? (And should we remove one of our behaviors here?)

(In contrast, Chrome's <br>-insertion behavior (mentioned at the end of comment 0) seems to be dependent on the display value. So they insert linebreaks on the first two parts of testcase 2 and 3, vs. don't-insert-linebreaks in the bottom part of testcase 3. I don't know if that linebreak-insertion-behavior itself is useful, but it's at least intuitive that it switches based on the display value rather than on the tag-name.)

Flags: needinfo?(masayuki)

(If this isn't something we can fix soonish, we could address the associated webcompat bug (bug 1891427) by asking Google to switch to a div here. But I'd rather not do that until I understand the reason span/div have different behaviors in the first place here, and whether that's something we can just fix.)

I'll be back tomorrow so that I cannot investigate this today. However, I guess that keeping <span> is intended to keep the style/semantics of the dropped text. The block elements are treated as a part of structure of the document, but the inline elements are treated as a part of decoration of the text.

Flags: needinfo?(masayuki)

Masayuki, can you assign a severity to this?

Flags: needinfo?(masayuki)
Severity: -- → S3
Flags: needinfo?(masayuki)

One of the problems is, we copy style attribute value as-is into the clipboard. It seems that Chrome generates style attribute with computed values to preserve the original style. Therefore, 2em is copied as 32px. This prevents the inflation of the font-size in attachment 9436551 [details].

Assignee: nobody → masayuki
Status: NEW → ASSIGNED
Component: DOM: Editor → DOM: Serializers
OS: Unspecified → All
Hardware: Unspecified → All

It treats some inline elements as contextual elements. Then, they will be
preserved in copied HTML fragment. However, if an inline element is an editing
host, we don't want to contain it to the copied fragment because pasting it
causes duplicating same style into same editing host. So, if the style includes
relative style like font-size: 2em, it will cause bigger text than the
surrounding text. Additionally, the inline editing host usually has a border
but we don't want to make it appear in editable text.

Unfortunately, with this change, we stop copying the text style specified to
the inline editing host. However, this is same behavior as when the editing
host is a block element like <div>. Note that pasted text will be merged into
the inline editing host style. Therefore, if and only if the destination has
different style from the editing host, the result might be different from the
expected one by the user. However, this is a long standing issue, see
bug 1428046, for example.

edgar: Could you review the patch? This is a web-compat issue in the wild.

Flags: needinfo?(echen)

(Replied in Phabricator)

Flags: needinfo?(echen)
Pushed by masayuki@d-toybox.com: https://hg.mozilla.org/integration/autoland/rev/060a278ac9c9 Make `nsHTMLCopyEncoder::RangeNodeContext::IncludeInContext` not treat inline editing host as an contextual inline element r=edgar,dom-core
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/49287 for changes under testing/web-platform/tests
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 134 Branch
Upstream PR merged by moz-wptsync-bot
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: