Javascript textarea undo redo
Asked Answered
P

2

20

I'm making a small javascript editor (for a chrome extension) somewhat like the one on SO.

There's a toolbar for manipulation of the text in the textarea. (e.g. surround the selected text with some template)

I was wondering if there is a easy way to achieve this, currently when using the system undo/redo, it messes the text up (I think the system is only keeping track of deltas between edits).

Parkerparkhurst answered 26/9, 2011 at 9:58 Comment(1)
Related: #16196144Katrinka
C
20

You can probably simulate textInput events to manipulate the contents of the textarea. The changes made that way are respected by undo/redo, I think (I know they are in Safari)

var element = document.getElementById('someTextarea');
var text = 'This text will be inserted in the textarea';
var event = document.createEvent('TextEvent');

event.initTextEvent('textInput', true, true, null, text);
element.dispatchEvent(event); // fire the event on the the textarea

Basically, the text is inserted as though you pasted it yourself. So if something is selected, it'll be be replaced with the text. If there's no selection, the text will be inserted at the caret's position. And undo/redo should work normally (undoing/redoing the entire inserted string in one go), because the browser acts as if you typed/pasted it yourself.

As I said, I know this works like a charm with undo/redo in Safari, so I'd assume it works in Chrome as well.

Cussedness answered 26/9, 2011 at 11:20 Comment(2)
In firefox you can replace the textarea value with element.value = substring + data + substring; and undo will still workKatrinka
As of Chrome 53 this won't work, because document.createEvent creates an untrusted event. See: #39948375British
A
21

If the textarea has focus and its caret is at the correct position,

document.execCommand("insertText", false, "the text to insert");

will insert the text "the text to insert", preserving the browser's native undo stack. (See the work in progress HTML Editing API spec.) Chrome 18 supports this, but I'm unsure of the exact version it was introduced.

Airman answered 27/4, 2012 at 6:8 Comment(4)
Undo works, but redo doesn't. It seems to forget the newest history item... jsfiddle.net/rudiedirkx/k4spa0dv (Chrome only)Deandreadeane
can't figure out what the false is?Aspirator
Note that the HTML Editing API spec, while it would be useful, is now obsolete (and unsupported in most browsers: caniuse.com/#feat=ime). However, this apparently does not mean that execCommand("insertText", ...) is unsupported!Uproar
According to MDN, execCommand() is depricated. developer.mozilla.org/en-US/docs/Web/API/Document/execCommandForging
C
20

You can probably simulate textInput events to manipulate the contents of the textarea. The changes made that way are respected by undo/redo, I think (I know they are in Safari)

var element = document.getElementById('someTextarea');
var text = 'This text will be inserted in the textarea';
var event = document.createEvent('TextEvent');

event.initTextEvent('textInput', true, true, null, text);
element.dispatchEvent(event); // fire the event on the the textarea

Basically, the text is inserted as though you pasted it yourself. So if something is selected, it'll be be replaced with the text. If there's no selection, the text will be inserted at the caret's position. And undo/redo should work normally (undoing/redoing the entire inserted string in one go), because the browser acts as if you typed/pasted it yourself.

As I said, I know this works like a charm with undo/redo in Safari, so I'd assume it works in Chrome as well.

Cussedness answered 26/9, 2011 at 11:20 Comment(2)
In firefox you can replace the textarea value with element.value = substring + data + substring; and undo will still workKatrinka
As of Chrome 53 this won't work, because document.createEvent creates an untrusted event. See: #39948375British

© 2022 - 2024 — McMap. All rights reserved.