Opened 6 years ago

Closed 6 years ago

#16726 closed defect (fixed)

focus manager sets activeStack if nothing changes which cases focus issues on IPad when inside an IFrame

Reported by: Mark DeMichele Owned by: bill
Priority: undecided Milestone: 1.9
Component: Dijit Version: 1.8.3
Keywords: Cc:
Blocked By: Blocking:

Description (last modified by bill)

After applying the fix for #16725 and testing it on a IPad, I noticed that if the textbox has the focus and you click on it again to move the caret, you sometimes lose the focus and can't type any more even though the keyboard is still visible. There is also strange behavior when you try to move the caret around.

I narrowed down the issue to the _setStack method of dijit/focus. The code already determine what has changed in the stack and by the nature of the existing logic, pretty much does nothing if the stack doesn't change, with one exception.

It still calls this.set("activeSatck", newStack).

This call is causing the issue. I really can't say why and ran out of time to debug it further, but it does mess up the IPad when your page is in an IFrame.

I figure this out by applying the following logic.

if (nCommon == newStack.length && newStack.length == oldStack.length)
    return;

Please see dijit/tests/form/test_TextBoxIFrame.html (this was uploaded via a patch in #16725).

Attachments (1)

focus.js.patch (925 bytes) - added by Mark DeMichele 6 years ago.
Here is my fix. Though after testing it, I'm realizing that this fix addresses the issue I was having with my custom dijit, It actually does not fix the TextBox?. Im uploading it anyway since, on it's own, it makes sense to not set activeStack. However, I need to investigate this further to see if I can narrow down the TextBox? behanior.

Download all attachments as: .zip

Change History (6)

Changed 6 years ago by Mark DeMichele

Attachment: focus.js.patch added

Here is my fix. Though after testing it, I'm realizing that this fix addresses the issue I was having with my custom dijit, It actually does not fix the TextBox?. Im uploading it anyway since, on it's own, it makes sense to not set activeStack. However, I need to investigate this further to see if I can narrow down the TextBox? behanior.

comment:1 Changed 6 years ago by Mark DeMichele

Sorry, I should have set the component to Dijit - Form and now it doesn't seem that I can edit it, unless I'm missing something.

comment:2 Changed 6 years ago by Mark DeMichele

I just went back to my original internal test. With this fix, my custom widget that houses a hidden input control, works perfectly when you click it a second time. The TextBox and for that matter, a plain old input field does not.

If you click, hold and drag to move the caret around in the little magnifying glass, and then let go, you wind up with no caret, and if you type in the keyboard nothing happens.

I'm running out of time to debug this so I will describe how my custom widget may be different from the TextBox and maybe that may lead to a clue as to why the TextBox has these issues.

I believe what got my behaving properly was to handle the "mouseup". Yes, not a touch event, but the "mouseup". On "mouseup", I set the focus to my focusNode. This did the trick and seems to work everywhere.

comment:3 Changed 6 years ago by bill

Component: GeneralDijit
Description: modified (diff)
Owner: set to bill

I'll mark it as Dijit (rather than Dijit - form) since it's about the dijit/focus code.

comment:4 Changed 6 years ago by bill

Milestone: tbd1.9
Status: newassigned

I also see the problem where using the magnifying glass causes the TextBox to lose focus even though the keyboard is still shown, but the focus.js change doesn't fix it (for me). Plus, I traced through the code of what focus.js does when newStack is the same as the old stack, and it doesn't do anything significant, it just triggers:

focus.watch("activeStack", function(name, oldVal, newVal){
	dijit._activeStack = newVal;
});

and

singleton.watch(function(attr, oldVal, newVal){
	dijit.focus[attr] = newVal;
});

So it's just setting dijit._activeStack and dijit.focus.activeStack to the same value as before, which isn't useful but (in theory) shouldn't hurt anything either.

I guess in the case that someone else was watching activeStack, the guard code you added will avoid spurious notifications about changes, at the expense of a few more lines of code. So it's a toss up, but I'll add it, or rather, a slightly modified version.

comment:5 Changed 6 years ago by bill

Resolution: fixed
Status: assignedclosed

In [30610]:

Avoid spurious notifications about changes to activeStack, fixes #16726 !strict. Also streamlined logic for detecting what part of stack has changed.

Note: See TracTickets for help on using tickets.