textarea execcommand insertText not working properly

NEW
Assigned to

Status

()

defect
4 years ago
19 days ago

People

(Reporter: daniel.didusch, Assigned: masayuki)

Tracking

({parity-chrome, parity-edge})

50 Branch
All
Other
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)

Details

(Whiteboard: [specification][type:bug], URL)

Attachments

(1 attachment)

(Reporter)

Description

4 years ago
What did you do?
================
<!doctype html>
<html>
	<head>
		<title>Test</title>
	</head>
	<body>
		<textarea designMode="on" id="textarea"></textarea>
		<a href="#" onclick="document.getElementById('textarea').focus(); document.execCommand('insertText', false, 'Text'); return false;">Insert text</a>
		<a href="#" onclick="document.getElementById('textarea').value = ''; return false;">Reset</a>
	</body>
</html>

What happened?
==============
Insert text works properly as long you don't change it's value

What should have happened?
==========================
Should also work after editing text

Is there anything else we should know?
======================================
Sounds like you're trying to report a bug in Firefox.
Component: General → General
Product: Mozilla Developer Network → Firefox
(Reporter)

Comment 2

4 years ago
You're right Luke Crouch, I missed that one, sorry for any inconvenience!

Updated

3 years ago
Blocks: 748307
Component: General → Editor
Product: Firefox → Core
Summary: textarea execcommand not working properly → textarea execcommand insertText not working properly

Comment 3

3 years ago
Here is a jsFiddle that I created that illustrates the bug, https://jsfiddle.net/dvo5pnvy/3/.

In chrome, safari, and edge, when pasting into the input text box, the string "This should be pasted." is pasted in, no matter what is in your clipboard. In firefox, however, whatever is in your clipboard is pasted in, even though the event fires.
(Reporter)

Updated

3 years ago
Component: Editor → Untriaged
Product: Core → Firefox
Version: unspecified → 50 Branch
Firefox: 50.0a1, Build ID: 20160626030213
User Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0

I have tested this issue on the latest Firefox (47.0) release and latest Nightly (50.0a1) build. When testing this I have used both provided test cases.
In the test case from comment 0, when pressing the "Insert Text" link, nothing happens. In Chrome when pressing the "Insert Text" link in the text box the "Text" string is displayed.
In the test case from comment 3, any copied string is pasted in the text box, but the "This should be pasted." string should be pasted.
Status: UNCONFIRMED → NEW
Component: Untriaged → Editor
Ever confirmed: true
Product: Firefox → Core
Flags: needinfo?(masayuki)
I'm not sure if comment 3's testcase is exactly same bug as this.

Here is the simplest testcase: https://jsfiddle.net/d_toybox/prkt4yhd/1/

Anyway, according to MDN, document.execCommand() is designed only for designMode="on" or "contenteditable". So, it's not working with <input> nor <textarea> must be intentional behavior in Gecko.
https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

However, indeed, it makes incompatibility between other browsers. This is too bad. I guess that it's not so difficult to implement this, but I don't have much time because there are a lot of bugs in my queue...
Flags: needinfo?(masayuki)
According to the debugger, we hit here because there is no HTML editor in the testcase:
https://dxr.mozilla.org/mozilla-central/rev/6608e5864780589b25d5421c3d3673ab30c4c318/dom/html/nsHTMLDocument.cpp#3146-3149

And I guess we need to hack here:
https://dxr.mozilla.org/mozilla-central/rev/6608e5864780589b25d5421c3d3673ab30c4c318/dom/html/nsHTMLDocument.cpp#3193-3199

We need to use command manager for <input> or <textarea> instead of HTML editor's.

I guess that this bug is useful for Gecko Hands-on which will be held in Japan late this month. I'll research the detail more and new hacker should fix this bug if it's possible.
Assignee: nobody → masayuki
Thank you for looking into this!  Do you know what, if anything, the spec says here?
(In reply to Boris Zbarsky [:bz] from comment #7)
> Thank you for looking into this!  Do you know what, if anything, the spec
> says here?

Although, not yet reading whole of the the Editing API draft, I don't find about the target of execCommand. I feel odd to use "document."execCommand for an editable element, though. (<input>.execCommand makes sense for me...)
Duplicate of this bug: 241182

Comment 10

2 years ago
This bug becomes more important since setting `.value` now nukes undo history for <textarea>s and <input>s.

If developers want to preserve undo history for <textarea>s and <input>s, they would use `execcommand` on Webkit and directly use .value on Firefox.  Now, there is no way for preserving undo history while programmatically changing <textarea> or <input> values.

Comment 11

2 years ago
Please also refer to https://twitter.com/FakeU/status/901671863851429889 for illustration.
Whiteboard: [specification][type:bug] → [specification][type:bug][parity-blink][parity-edge]

Comment 12

a year ago
Here is a simple editor with two buttons inserting text to either a `textarea` or a `contenteditable` element:
http://jsbin.com/baxusiw/edit?html,js,console,output

Same thing exported to Gist:
https://gist.github.com/Eccenux/4adb35f3a319c1df605690b2d6020e7a

Inserting Bold/Italic to textarea:
* FF (60): Doesn't work.
* Chrome (66): Works. Undo works.
* Opera (52): [same as Chrome].
* Edge (41): Works. Undo works.
* Safari: ? (untested, but other sources suggest it works)

Inserting Bold/Italic to contenteditable:
* FF (60): Works. Undo works.
* Chrome (66): Works. Undo works, but all changes are cumulated (all changes are reverted with one CTRL+Z).
* Opera (52): [same as Chrome].
* Edge (41): Works. Undo works.
* Safari: ?

So it seem like FF is left alone with IE, but in IE you can insert text into range and undo will work.
Thank you for comparing with the other browsers. I still think that "document." is odd. However, we should take same behavior.
I checked current design roughly, but I have no idea how to implement.

Currently, HTML edit commands registers with HTMLEditor instance as their context. If we take same approach, we need to register every supported command *per* <input> or <textarea> element. So, this wastes memory a lot and makes page load speed slower especially when there are a lot of <input> and <textarea> elements.

Perhaps, when active element of nsHTMLDocument has TextEditor, we should redirect the command to new command handler in editor? I don't want to separate the command handling path between HTMLEditor and TextEditor...
(In reply to Masayuki Nakano [:masayuki] (JST, +0900) from comment #14)
> I checked current design roughly, but I have no idea how to implement.
> 
> Currently, HTML edit commands registers with HTMLEditor instance as their
> context. If we take same approach, we need to register every supported
> command *per* <input> or <textarea> element. So, this wastes memory a lot
> and makes page load speed slower especially when there are a lot of <input>
> and <textarea> elements.
> 
> Perhaps, when active element of nsHTMLDocument has TextEditor, we should
> redirect the command to new command handler in editor? I don't want to
> separate the command handling path between HTMLEditor and TextEditor...

If not contenteditable, this line always return false due to IsEditingOnAfterFlush

https://searchfox.org/mozilla-central/rev/11a2ae294f50049e12515b5821f5a396d951aacb/dom/html/nsHTMLDocument.cpp#2859

nsHTMLEdocument::execCommand looks for nsICommandManager of editor. And TextEditor has/registers EditorController and EditorCommands (*Element::GetController can return editor's controller).  But nsHTMLEditor::execCommand cannot find InsertPlaintextCommand::DoCommand in EditorCommands.

Although it isn't clear, since cmd_insertText doesn't register XUL's keyboard handler by XUL file, nsHTMLEdocument::execCommand cannot find/call EditorCommands's InsertPlaintextCommand.  (cmd_copy, cmd_paste and etc has XUL's keyboard handler).  But since it isn't clear, we need investigate more.
Since we don't have a list what command for execCommand we should allowed in textarea/input text.  At least, we might have to allow undo, redo and insertText on textarea/input
(In reply to Makoto Kato [:m_kato] from comment #16)
> Since we don't have a list what command for execCommand we should allowed in
> textarea/input text.  At least, we might have to allow undo, redo and
> insertText on textarea/input

Yeah, and perhaps, insertParagraphSeparator, insertLineBreak (only <textarea>), delete, forwarddelete and selectAll.
Posted patch WIPSplinter Review
Mass bug change to replace various 'parity' whiteboard flags with the new canonical keywords. (See bug 1443764 comment 13.)
Whiteboard: [specification][type:bug][parity-blink][parity-edge] → [specification][type:bug]
This caused an issue with pasting text into comments on Youtube in bug #1466391. 

Google also provided a test case: https://codepen.io/cheng-lee/pen/rKzbPx
See Also: → 1466391
Blocks: 1443902

Comment 21

7 months ago
I noticed on FF 65.0a1 the issue is still present and fails to insert text into textarea

const insert = document.execCommand('insertText', false, text);
console.log(insert); // false

Are there any updates?
(In reply to erosman from comment #21)
> I noticed on FF 65.0a1 the issue is still present and fails to insert text
> into textarea
> 
> const insert = document.execCommand('insertText', false, text);
> console.log(insert); // false
> 
> Are there any updates?

Just curious, although it's not standardized, why do you think that this bug is important? If the reason is serious and technical one, we should implement this as soon as possible.

Comment 23

7 months ago
I can't speak for erosman but I'm currently working on an extension that provides keyboard shortcuts to manipulate text in textarea, input and contenteditable elements. Changing the value of textareas using `elem.value = newvalue` seems to destroy history but using document.execCommand("insertText", ...) doesn't. Thus I'd find it nice if I was able to use document.execCommand on textareas.

I wouldn't say that this is very important to me though :).

Comment 24

7 months ago
> Just curious, although it's not standardized, why do you think that this bug is important? If the reason is serious and technical one, we should implement this as soon as possible.

It is not imperative as I worked around it but MDN does not mention that it is not supported.
https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

The paste into textarea from an extension without above, involves getting textarea, cursor position and break textarea value, add new text and put it back together. It is a long way round, which would have been made easier with above API.
> seems to destroy history

Amusingly enough, it used to not do that in Firefox, but none of the other browsers were willing to support undo across .value sets, so we disabled it too...

Comment 26

7 months ago
>but none of the other browsers were willing to support undo across .value sets

That's interesting, has there been discussion about it or was it more like "we waited for others to do the same thing and they didn't"? If there were discussions, do you know if/where I could read them? I'd like to understand their rationale, Firefox clearly used to do the right thing IMO.
> I'd like to understand their rationale

It slowed down benchmarks like Speedometer that set .value repeatedly and measure the performance of the setter.

I'm not sure offhand whether the discussions were public.

Comment 28

7 months ago
To preserve textarea history, for Chrome I used to do execCommand and for Firefox just set .value, but now I am left with no other solution than changing the textarea to a contenteditable (with a lot of side effects) for preserving the undo stack in Firefox.

If execcommand on input elements works without needing a contenteditable, that would make programmatic manipulation of values in input/textarea much easier.
Thanks for the answers! I understand, not breaking undo stack is important for UX of Firefox users if execCommand() is used only for the other browsers since we've stopped appending history of .value setting as bzbarsky said.

Comment 30

7 months ago
I also came across another consideration. The work around I mentioned in Comment 24 works only for textarea & text input. It requires more code for contenteditable elements.
However, document.execCommand('insertText', false, text) works for all of them.

Comment 31

7 months ago
Sorry.. never mind Comment 30 document.execCommand('insertText', false, text) works for contenteditable elements

Comment 32

6 months ago
@erosman Could you share a fiddle with the workaround you talk about? I don't understand what do you mean by: "break textarea value, add new text and put it back together". Are you saying that it is possible to insert some text in textarea in Firefox and undo this (with CTLR+Z)?

Comment 33

6 months ago
@Maciej Jaros I meant break the textarea value into segments e.g. node.value.substring(), node.selectionStart & node.selectionEnd add the text in between and reset the textarea.value to the new text. This is nothing new and works for my intended purpose but it does not work for your purpose since it can not be undone. I haven't found a way for Firefox to keep the undo history.
I would have also preferred the simpler document.execCommand('insertText',..) that is supported by all other browsers and would have kept the undo history.

I even tried document.execCommand('paste') but that doesn't work at all for inserting text into editable elements.

Comment 34

6 months ago
+1, same issues as mentioned above - currently working on an editor (textarea) with markdown support and e.g. buttons / keyboard shortcuts like cmd+b to make it **bold**.
A very good example is to compare/use the github text editor (github issues, ...).
Make text bold via the menu or [cmd+b] - then try to undo/redo [cmd+z] ... not working in Firefox due to the simple value replace is used as a fallback to `document.execCommand('insertText', false, text)`

Perhaps, after fixing bug 1529884, we could fix this easier than current design. I'll try to fix this in 69.

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