webodf / WebODF

WebODF - JavaScript Document Engine
http://webodf.org/
787 stars 165 forks source link

On-screen keyboard doesn't display on an iPad #332

Closed peitschie closed 10 years ago

peitschie commented 10 years ago

Due to some magical focus-ignoring code Apple has decided to put in Safari, calls to element.focus() have no effect unless they are fired within a click event or similar (see http://www.quora.com/Mobile-Safari-iPhone-or-iPad-with-JavaScript-how-can-I-launch-the-on-screen-keyboard/answer/Han-Wei).

Currently, this means that the on-screen keyboard is never activated on an iPad.

Virtual cursors would help somewhat with this as event trap would not be removed & re-added after each cursor move (as currently happens). They would still not solve the issue with how to capture the focus on page-load however.

One library I found seemed to hint that the focus event could be captured from a synthetic click event, but so far I haven't been able to reproduce this: http://ftlabs.github.io/fastclick/examples/focus.html.

I've put together a test page to help with diagnosis of this issue here: https://github.com/peitschie/WebODF/compare/ipad-focus?expand=1

peitschie commented 10 years ago

Another related link with some information: http://4pcbr.com/topic/how_to_open_keyboard_on_ipad_with_js

peitschie commented 10 years ago

Some more playing around with the 4pcbr link:

Design proposal

One possible way to skirt this issue is:

  1. Assume an iPad can't generate composition events. This would negate the need for an inline event trap (achieved by overriding behaviour in the InputMethodEditor)
  2. Override focus & blur methods in the EventManager to be no-ops
  3. When focus is lost from the document, provide a translucent overlay instructing the user to click in order to resume editing (note, this is only an escape hatch should some unplanned mechanism steal focus)
  4. For all planned focus transitions, as long as they are performed within mouse-down type events (e.g., closing a Dojo overlay or clicking a button), the focus should be correctly transferred back to the document. (can be demonstrated by trying to insert an annotation, which behaves just fine!)
adityab commented 10 years ago

A catch: after any OpInsertText execution, focus is lost and is always restored thanks to odtDocument.subscribe(ops.OdtDocument.signalOperationEnd, restoreFocus);

There is no way to get this to work in iOS, so you can enter only 1 character after which the keyboard hides.

peitschie commented 10 years ago

Solving that issue is the primary purpose of point 1 & 2.

The blur/focus required before/after every op for performance and stability reasons as a result of the event trap (and hence window selection) being inside the cursor node. Removing and re-adding the cursor node with an active selection causes significant performance problems (8de8dde), and can even throw errors in Firefox (c665b1a).

The ONLY reason for placing the event trap inline in the cursor is to accurately position the IME menus on various operating systems when a composition event occurs. If iOS has no IME system (or we choose to not support it for now), there is no compelling reason for the event trap to be inside the cursor, which allows the trap to be moved outside the main document content. This negates the need for the blur/focus after every operation, allowing continuous typing to occur.

adityab commented 10 years ago

Fixed by #390 and #410.