WebAPI/KeboardIME: Difference between revisions

Jump to navigation Jump to search
Add comments by me
(Add comments by me)
Line 23: Line 23:
#{{bug|805586}} - [keyboard] keyboard needs a 'hide keyboard' button(main tracking bug)
#{{bug|805586}} - [keyboard] keyboard needs a 'hide keyboard' button(main tracking bug)
#{{bug|844716}} - Enable keyboard Apps to get/set selection range of the input field
#{{bug|844716}} - Enable keyboard Apps to get/set selection range of the input field
#{{bug|860546}} - [keyboard] JS changes to a textfield while keyboard is displayed do not get passed to keyboard  
#{{bug|860546}} - [keyboard] JS changes to a textfield while keyboard is displayed do not get passed to keyboard
#{{bug|861665}} - Allow IME to get notification when text field content is changed
#{{bug|861665}} - Allow IME to get notification when text field content is changed
#{{bug|861515}} - Keyboard should be able to modify the text of the input field directly
#{{bug|861515}} - Keyboard should be able to modify the text of the input field directly
Line 56: Line 56:
     // Input Method Manager contain a few global methods expose to apps
     // Input Method Manager contain a few global methods expose to apps
     readonly attribute InputMethodManager mgmt;
     readonly attribute InputMethodManager mgmt;
 
     // Fired when the input context changes, include changes from and to null.
     // Fired when the input context changes, include changes from and to null.
     // The new InputContext instance will be available in the event object under |inputcontext| property.
     // The new InputContext instance will be available in the event object under |inputcontext| property.
Line 62: Line 62:
     // Note that if the app saves the original context, it might get void; implementation decides when to void the input context.
     // Note that if the app saves the original context, it might get void; implementation decides when to void the input context.
     attribute EventHandler oninputcontextchange;
     attribute EventHandler oninputcontextchange;
 
     // An "input context" is mapped to a text field that the app is allow to mutate.
     // An "input context" is mapped to a text field that the app is allow to mutate.
     // this attribute should be null when there is no text field currently focused.
     // this attribute should be null when there is no text field currently focused.
Line 73: Line 73:
     // OS should ignore this request if the app is currently not the active one.
     // OS should ignore this request if the app is currently not the active one.
     void showAll();
     void showAll();
 
     // Ask the OS to switch away from the current active Keyboard app.
     // Ask the OS to switch away from the current active Keyboard app.
     // OS should ignore this request if the app is currently not the active one.
     // OS should ignore this request if the app is currently not the active one.
     void next();
     void next();
 
     // Clear the focus of the current input field.
     // Clear the focus of the current input field.
     // The OS might respond with hidden of the virtual keyboard and void the input context.
     // The OS might respond with hidden of the virtual keyboard and void the input context.
    // [JJ] What is removeFocus doing here. Everything that interacts with form elements
    //      happens in the inputContext, so this should be there too.
     void removeFocus();
     void removeFocus();
   };
   };
Line 87: Line 89:
  // An "input context" gets void when the app is no longer allowed to interact with the text field,
  // An "input context" gets void when the app is no longer allowed to interact with the text field,
  // e.g., the text field does no longer exist, the app is being switched to background, and etc.
  // e.g., the text field does no longer exist, the app is being switched to background, and etc.
// [JJ] I doubt whether we should have 'name', 'type', etc. here. In the manifest we should
//      have entry points where the keyboard specifies which view to load when going into a
//      certain context. Requiring to do this manually will give extra work.
//      The system should guarantee that the right view is rendered based on entry_points in
//      in manifest (e.g. navigate keyboard to #text/en, or something, based on manifest.
  interface InputContext {
  interface InputContext {
     // The tag name of input field, which is enum of "input", "textarea", or "contenteditable"
     // The tag name of input field, which is enum of "input", "textarea", or "contenteditable"
     DOMString name;
     DOMString name;
 
     // The type of the input field, which is enum of text, number, password, url, search, email, and so on.
     // The type of the input field, which is enum of text, number, password, url, search, email, and so on.
     // See http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#states-of-the-type-attribute
     // See http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#states-of-the-type-attribute
     DOMString type;
     DOMString type;
 
 
     /*
     /*
     * The inputmode string, representing the input mode.
     * The inputmode string, representing the input mode.
Line 100: Line 107:
     */
     */
     DOMString inputmode;
     DOMString inputmode;
 
 
     /*
     /*
     * The primary language for the input field.
     * The primary language for the input field.
Line 107: Line 114:
     */
     */
     DOMString lang;
     DOMString lang;
 
 
     /*
     /*
     * Get the whole text content of the input field.
     * Get the whole text content of the input field.
     * App is encouraged to use getSurroundingText() below to prevent getting to much things clogged in memory.
     * App is encouraged to use getSurroundingText() below to prevent getting to much things clogged in memory.
    * [JJ] Do we have any case where loading the full text is required?
    *      I don't see it in the example code.
     */
     */
     Promise<DOMString> getText();
     Promise<DOMString> getText();
 
 
     // The start and stop position of the selection.
     // The start and stop position of the selection.
     readonly attribute long selectionStart;
     readonly attribute long selectionStart;
     readonly attribute long selectionEnd;
     readonly attribute long selectionEnd;
 
     /*
     /*
       * Set the selection range of the the editable text.
       * Set the selection range of the the editable text.
Line 127: Line 136:
       * Note that the start position should be less or equal to the end position.
       * Note that the start position should be less or equal to the end position.
       * To move the cursor, set the start and end position to the same value.
       * To move the cursor, set the start and end position to the same value.
      *
      * [JJ] I think that this method should return the same info as the selectionchange event
      *      rather than a boolean.
       */
       */
     Promise<boolean> setSelectionRange(long start, long length);
     Promise<boolean> setSelectionRange(long start, long length);
 
     // User moves the cursor, changes the selection, or alters the composing text length
     /* User moves the cursor, changes the selection, or alters the composing text length
    // TODO: dup with the onsurroundingtextchange event/callback below for cursor moment?
      * TODO: dup with the onsurroundingtextchange event/callback below for cursor moment?
      *
      * [JJ] I would merge this with onsurroundingtextchange to have 1 state event.
      *      in the end, every onselectionchange event will also generate a surrounding
      *      text change event.
     attribute EventHandler onselectionchange;
     attribute EventHandler onselectionchange;
 
     /*
     /*
     * Get the text content around the cursor of the input field.
     * Get the text content around the cursor of the input field.
Line 139: Line 155:
     * App is encouraged to use this instead of getText() above to prevent getting to much things clogged in memory.
     * App is encouraged to use this instead of getText() above to prevent getting to much things clogged in memory.
     * TODO: how to return two values in one Promise object? as two arguments to the callback?
     * TODO: how to return two values in one Promise object? as two arguments to the callback?
    *
    * [JJ] Would be useful to also include other state info (cursor position, selection pos, etc.)
    *      So we have 1 state object that gets returned regardless of operation
    *      (same one as in the change handlers and setSelectionRange)
     */
     */
     Promise<DOMString beforeText, DOMString afterText> getSurroundingText();
     Promise<DOMString beforeText, DOMString afterText> getSurroundingText();
 
 
     /*
     /*
       *
       *
Line 148: Line 168:
       * @param length The length of text to delete.
       * @param length The length of text to delete.
       * TODO: maybe updateSurroundingText(DOMString beforeText, DOMString afterText); ?
       * TODO: maybe updateSurroundingText(DOMString beforeText, DOMString afterText); ?
      * [JJ] Rather do a replaceSurroundingText(long offset, long length, optional DOMString text)
      *      If text is null or empty, it behaves the same
       */
       */
     Promise<boolean> deleteSurroundingText(long offset, long length);
     Promise<boolean> deleteSurroundingText(long offset, long length);
 
     /*
     /*
     * This event is sent when the text around the cursor is changed, due to either text
     * This event is sent when the text around the cursor is changed, due to either text
     * editing or cursor movement.  
     * editing or cursor movement.
     *
     *
     * The event handler function is specified as:
     * The event handler function is specified as:
Line 165: Line 187:
     */
     */
     attribute SurroundingTextChangeEventHandler onsurroundingtextchange;
     attribute SurroundingTextChangeEventHandler onsurroundingtextchange;
 
 
     /*
     /*
       * send a character with its key events.
       * send a character with its key events.
Line 171: Line 193:
       * TODO2: what are the modifiers?
       * TODO2: what are the modifiers?
       * Alternative: sendKey(KeyboardEvent event), but we will likely waste memory for creating the KeyboardEvent object.
       * Alternative: sendKey(KeyboardEvent event), but we will likely waste memory for creating the KeyboardEvent object.
       */  
      * [JJ] Why does this return anything?
       */
     Promise<boolean> sendKey(long keyCode, long charCode, long modifiers);
     Promise<boolean> sendKey(long keyCode, long charCode, long modifiers);
 
     /*
     /*
       * Set current composition. It will start or update composition.
       * Set current composition. It will start or update composition.
       * @param cursor Position in the text of the cursor.
       * @param cursor Position in the text of the cursor.
      * [JJ] Dont really know about this, but what if endComposition is never called
      *      maybe because unhandled exception?
       */
       */
     Promise<boolean> setComposition(DOMString text, long cursor);
     Promise<boolean> setComposition(DOMString text, long cursor);
 
     /*
     /*
       * endComposition and actually commit the text.
       * endComposition and actually commit the text.
Line 205: Line 230:
If the field is a numeric field, it will fill "1337".
If the field is a numeric field, it will fill "1337".


  var timer;  
  var timer;
  function startTyping(inputContext) {
  function startTyping(inputContext) {
   clearTimeout(timer);
   clearTimeout(timer);
   timer = setInterval(function typing() {
   timer = setInterval(function typing() {
    /* [JJ] So I think that this code shouldn't be here, because you'll get lots of clutter
      *      as you'll also have to take languages into account.
      *      Rather rely on entry points in manifest...
      */
     if (inputContext.inputmode === 'numeric' || inputContext.type === 'number') {
     if (inputContext.inputmode === 'numeric' || inputContext.type === 'number') {
       ['1', '3', '3', '7'].forEach(function (k) {
       ['1', '3', '3', '7'].forEach(function (k) {
Line 225: Line 255:
   }, 1000);
   }, 1000);
  }
  }
 
  function stopTyping() {
  function stopTyping() {
   clearTimeout(timer);
   clearTimeout(timer);
  }
  }
 
  var im = navigator.inputMethod;
  var im = navigator.inputMethod;
 
  im.addEventListener('inputcontextchange', function contextchanged(evt) {
  im.addEventListener('inputcontextchange', function contextchanged(evt) {
   if (evt.inputcontext) {
   if (evt.inputcontext) {
Line 241: Line 271:
   }
   }
  });
  });
 
  if (im.inputcontext) {
  if (im.inputcontext) {
   // The webpage here is loaded *after* the user has place the focus on the text field,
   // The webpage here is loaded *after* the user has place the focus on the text field,
Confirmed users
4

edits

Navigation menu