Look at UI's dialog for an example.
So, I looked at the code in UI, and it seems that, at its heart, the code uses the selector ":tabbable". This selector is implemented in UI core along with another, less specific selector called ":focusable". Rather than copying the code, we should probably find a way to factor out the code for these selectors either into a separate file which we can then copy into mobile (like we do with jquery.ui.widget.js) or we should move the code into core - which will no doubt increase core's wire weight, so that may not be feasible.
Another observation is that, in addition to these selectors, the focus restriction code relies on listening to keyboard events such as Tab and Shift+Tab and assuming that those events exert influence on which element will be focused next. While this is almost always true, it is not a focus-handling-agnostic implementation. Such an implementation would rely solely on .focus() and .blur() to accomplish the task of focus restriction.
So, if we do choose to implement focus restriction the UI way, we should probably find a way to reuse the code, so that we can benefit from future improvements to their code.
Outside of user-generated scripts, in what cases does pressing tab not move focus? Focus restriction is hard, and after 5 years of implementing different solutions, I have yet to find a solution that I like :-/
You're right. I have yet to find a browser where pressing Tab does something else. Nevertheless, focus can also be altered by other means. One example is the type-to-search feature in Firefox. If you type the text of a link, it gains focus, and if you press Enter while the Quick Search bar is still open, the link gets clicked. All this happens without any focusout/blur/keydown whatsoever.
Now, in UI's modal dialog demo, there is a mechanism in place for preventing the click. I'm not yet sure what it is, but you can try it for yourself.
If you add a text input to the modal dialog demo page containing some initial text, you can reach the input by following the above steps and typing the text in the page input at step 3. Focus is transferred to the input and you can modify its contents if you wait for the quick search bar to disappear. However, it seems you can't type just anything. Only space, -, and = seem to work. Anyway, the bottom line is that you can reach an input "beneath" the modal dialog and modify its contents.
Try it here.
[popup] Restrict focus to elements inside the popup -- Fixes #5130
Caveat: This kind of focus restriction can still be circumvented using FF's type-to-search feature