marijnh/CodeMirror2 — pull request #495 by njx (2012-04-17 01:41:20+00:00)
Title: For review: Simpler flicker fix

This is a different implementation of the scrolling "flicker fix" along the lines you suggested in your comments on https://github.com/marijnh/CodeMirror2/pull/473. Rather than creating a separate scrollbar div, we just move the "mover" div out of the main scroller div, so it's now a sibling that sits behind the main scroller.

The logic for actually updating the position of the "mover" div is similar to the logic in the previous version. Most of the differences in this version have to do with the fact that the actual lineSpace is no longer a child of the scroller. That required a few major changes:

* I renamed the child of the scroller from "code" to "scrollerInner", since its only function now is to set the virtual scrollWidth/scrollHeight of the scroller.
* We can't rely on the scroller automatically calculating its scrollWidth based on the width of the lineSpace div. Instead, we have to manually set the width of the scrollerInner to match the lineSpace (unless the lineSpace fits entirely within the width of the scroller, in which case we just set scrollerInner to 100%).
* The theme class now has to be applied directly to the mover instead of the scroller.
* The scroller was already handling most events. However, in IE, a fully empty div doesn't get mouse events. So we have to give the scrollerInner a background color and a 0 opacity. (We can't do this on the scroller because in IE <9 we can't just set the background's opacity--we have to set the opacity of the whole div using IE-specific markup.)

There are still a couple of major issues with this implementation, but I wanted to put it up for you to see if you think it makes sense before I did more work on it. The two major issues are:

* This implementation doesn't work properly with drag-and-drop in IE9 (I have it commented out in this pull request). In CodeMirror master, there's already an issue where if you select some text and then click on the selection (without dragging), it stays selected. With my implementation, the behavior is worse: the input div actually loses focus. I'm not sure why this is happening, because I can't figure out where the onBlur() is coming from. (We do actually get into the code in onDrop() that calls focusInput(), but the onBlur() happens later.)
* A more minor issue is that if you mouse over the gutter, you get a text cursor instead of an arrow cursor. This is because the scroller is above the gutter as well as the text, so we can't just set CSS rules to set the cursor differently between the two. I can't think of a good way to deal with this--we either have to explicitly handle mousemoves (which seems like it might be expensive), or create a transparent div above the scroller that mimics the size of the gutter (which seems hacky).

There are a few other issues noted as TODOs in the code. I'll add some comments to the diffs in the pull request to explain various bits of the code.

I haven't done extensive testing, but I've at least looked at it on: Chrome/Safari/Firefox (Mac OS 10.6), Chrome (Mac OS 10.7), IE 7/8 (Win XP), IE 9 (Win 7)--though I might have made some changes since I looked at it last in any given browser. I also looked at it in IE 6, but there are a number of bugs in CodeMirror master that made it so I can't really test it there (in particular, scrollbars never seem to show up in IE 6 even with CodeMirror master--the content just makes the overall editor bigger).

Let me know if you think this is a better approach than the original pull (and if you'd be willing to accept something along these lines :)).

=====

Legalese: The attached code is covered by the MIT license as follows.

Copyright ©2012 Adobe Systems Incorporated. All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.