Hi all,
I've been working on a custom undo manager for medium to work around some of the contenteditable undo inconsistencies. Just wondering if anyone would be interested in having this as a medium-editor plugin.
of course we would be interested :smile:
Cool ... here's what I have for a start: https://gist.github.com/bborn/dacba89e5e466a5398b4
You'd use it like this:
var medium = new MediumEditor('.editable');
var undoManager = new UndoManager(medium.elements[0]);
It binds undo and redo to ctrl+z and ctrl+shift+z, as well as to anything with the .undo and .redo class (i.e. buttons).
Might be slightly buggy, because it's extracted from a larger project. Hopefully I'll have time to turn it into a proper Medium extension with tests, but for now I just wanted to get the code out there for others to look at. :bowtie:
It works by using a DOM Mutation Observer and Rangy to preserve the cursor location through undos/redos. The debounce setting is configurable, but I've found that 100ms is about right.
If you've tried using the browser's undo, you quickly realize it doesn't handle many cases where Medium modifies the DOM programmatically (i.e. when inserting an image, stuff like that). It also is pretty wonky when it comes to cursor position. So those were the main issues I was trying to solve with this.
Nice stuff, I think you should definitely publish as an extension!
I mean, with a repo, npm module etc. :P
def nice, agree. Because coffeescript currently I wouldn't suggesting adopting it offically/proper, but can totally see a usecase for allowing these kinds of extensions (or any extension, rather) 1st-class access to core utility functions/etc. For instance, instead of doing a poll you could monkey-patch/intercept Util.insertHtml and execInternalAction (or editor could provide before/after hooks, or such) that you could just take individual snapshots for each proper "action". eg, clicking a button mutates dom, so take a snapshot when internalAction finishes (or right before, and throttle/defer next snapshot until next internal-canvas-mutating action happens). I've been inspired here, and would love to see this built out more.
I need this, but without jquery.
Shouldn't this be part of core? The editor creates lots of extra undo states.
Yeah, an undo manager that didn't have any dependencies could definitely be added to core.
The implementation that was provided early in this thread had some dependencies on jquery, rangy, etc., plus it's in coffeescript.
Most helpful comment
Cool ... here's what I have for a start: https://gist.github.com/bborn/dacba89e5e466a5398b4
You'd use it like this:
It binds undo and redo to
ctrl+zandctrl+shift+z, as well as to anything with the.undoand.redoclass (i.e. buttons).Might be slightly buggy, because it's extracted from a larger project. Hopefully I'll have time to turn it into a proper Medium extension with tests, but for now I just wanted to get the code out there for others to look at. :bowtie:
It works by using a DOM Mutation Observer and Rangy to preserve the cursor location through undos/redos. The debounce setting is configurable, but I've found that 100ms is about right.
If you've tried using the browser's undo, you quickly realize it doesn't handle many cases where Medium modifies the DOM programmatically (i.e. when inserting an image, stuff like that). It also is pretty wonky when it comes to cursor position. So those were the main issues I was trying to solve with this.