Confirmed users
4
edits
Janjongboom (talk | contribs) (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 | ||
* 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, |