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