I still have not decided if I want to keep last night's focus tests. I wrote a bunch of tests for the ICE Code Editor, but only ended up verifying that most everything worked already. Admittedly this was more of a noticeable problem in the old JavaScript version of ICE, but I had expected more trouble than I found.
I do not think it is so much Dart that made things better as being more consistent in the approach that I took towards buttons, menus and dialogs. Of course, Dart's static typing encourages consistency, but then again so does a strong #pairwithme partner and I have been blessed with many.
At any rate, I did leave off last night with a single failing focus test:
ERROR: Focus- editor has focus after closing a dialog
Focus- editor has focus after closing a dialog: Test setup failed: Expected: TextAreaElement:<textarea>
But: was BodyElement:<body>.
Unlike most of the other tests from yesterday, this was a “good” one in that it reproduced buggy behavior that I can see in the application.My initial instinct for fixing the bug was to add an
ice.focus()
call in the hideDialog method:_hideDialog() { queryAll('.ice-menu').forEach((e)=> e.remove()); queryAll('.ice-dialog').forEach((e)=> e.remove()); ice.focus(); }If that was all that was necessary to fix it, I would have been done with it last night. The trouble is that the
_hideDialog()
method is not so much a method on the full-screen version of ICE as it is a helper function. In other words, it does not have access to an instance of ICE nor do the calling contexts always have access.So to make this pass, I think that I have to have
_hideDialog()
trigger an event on the main DOM element that holds the editor. The constructor for the full-screen version of the editor creates an #ice
<div>
:Full({enable_javascript_mode: true}) { el = new Element.html('<div id=ice>'); document.body.nodes.add(el); ice = new Editor('#ice', enable_javascript_mode: enable_javascript_mode); store = new Store(); // ... }So sending a focus event to the
#ice
element seems the best course of action:_hideDialog() { queryAll('.ice-menu').forEach((e)=> e.remove()); queryAll('.ice-dialog').forEach((e)=> e.remove()); query('#ice').focus(); }A listener on the
onFocus
event stream should then do the trick: el.onFocus.listen((e)=> ice.focus());
It ought to work (at least in my mind), but it does not. The on-focus event is never fired. I could rail against the focus()
method failing to generate a focus event, but that will get me no closer to solving my problem.Instead of telling the element to focus, perhaps I can send a custom event? Or better yet, I try sending a focus event since that is really what I am trying to do:
_hideDialog() { queryAll('.ice-menu').forEach((e)=> e.remove()); queryAll('.ice-dialog').forEach((e)=> e.remove()); query('#ice').dispatchEvent(new UIEvent('focus')); }That is an uglyish constructor signature, but it does the trick. The event is received by the
<div id=ice>
element, which in turns tells the underlying ICE editor that it has focus. Yesterday's work, which turns out to not be a complete waste after all, ensures that the proper part of ICE—the code editor or the preview layer—gets focus. The bottom line is that I have a passing test:PASS: Focus- editor has focus after closing a dialog PASS: Focus- hiding code after update preview has focusI do believe that closes another issues on the ICE Code Editor tracker, which is a fine stopping point for tonight.
Day #785
No comments:
Post a Comment