summaryrefslogtreecommitdiff
path: root/dom/webidl/InputMethod.webidl
blob: ca22dcc1b692f2ca0351b644d5609f7c5237e9cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/.
 */

/**
 * InputMethod API implements a bridge between the web content hosting an input
 * element and the input content (a.k.a. input app, virtual keyboard app,
 * or IME). This API is input content facing in order for it to interact with
 * the remote input element.
 * The API also contains a few Gaia System app only methods
 * (marked with "input-manage" permission) for Gaia System app to interact with
 * some types of inputs and to regulate the input apps.
 */
[JSImplementation="@mozilla.org/b2g-inputmethod;1",
 NavigatorProperty="mozInputMethod",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozInputMethod : EventTarget {
  /**
   * Activate or decactive current API instance.
   * Gaia System app call this method via BrowserElement#setInputMethodActive.
   */
  [ChromeOnly]
  void setActive(boolean isActive);

  /**
   * InputMethodManager contain a few global methods expose to input apps.
   */
  readonly attribute MozInputMethodManager mgmt;

  /**
   * 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.  When it changes to null it
   * means the app (the user of this API) no longer has the control of
   * the original focused input field.
   * Note that if the app saves the original context, it might get
   * void; implementation decides when to void the input context.
   */
  attribute EventHandler oninputcontextchange;

  /**
   * 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.
   */
  readonly attribute MozInputContext? inputcontext;

  /**
   * Add a dynamically declared input.
   *
   * The id must not be the same with any statically declared input in the app
   * manifest. If an input of the same id is already declared, the info of that
   * input will be updated.
   */
  Promise<void> addInput(DOMString inputId,
                         MozInputMethodInputManifest inputManifest);

  /**
   * Remove a dynamically declared input.
   *
   * The id must not be the same with any statically declared input in the app
   * manifest. Silently resolves if the input is not previously declared;
   * rejects if attempt to remove a statically declared input.
   */
  Promise<void> removeInput(DOMString id);

  /**
   * Remove focus from the current input, usable by Gaia System app, globally,
   * regardless of the current focus state.
   */
  void removeFocus();

  /**
   * The following are internal methods for Firefox OS System app only,
   * for handling the "option" group inputs.
   */

  /**
   * Set the value on the currently focused element. This has to be used
   * for special situations where the value had to be chosen amongst a
   * list (type=month) or a widget (type=date, time, etc.).
   * If the value passed in parameter isn't valid (in the term of HTML5
   * Forms Validation), the value will simply be ignored by the element.
   */
  void setValue(DOMString value);

  /**
   * Select the <select> option specified by index.
   * If this method is called on a <select> that support multiple
   * selection, then the option specified by index will be added to
   * the selection.
   * If this method is called for a select that does not support multiple
   * selection the previous element will be unselected.
   */
  void setSelectedOption(long index);

  /**
   * Select the <select> options specified by indexes. All other options
   * will be deselected.
   * If this method is called for a <select> that does not support multiple
   * selection, then the last index specified in indexes will be selected.
   */
  void setSelectedOptions(sequence<long> indexes);
};

/**
 * InputMethodManager contains a few of the global methods for the input app.
 */
[JSImplementation="@mozilla.org/b2g-imm;1",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozInputMethodManager : EventTarget {
  /**
   * Ask the OS to show a list of available inputs for users to switch from.
   * OS should sliently ignore this request if the app is currently not the
   * active one.
   */
  void showAll();

  /**
   * Ask the OS to switch away from the current active input app.
   * OS should sliently ignore this request if the app is currently not the
   * active one.
   */
  void next();

  /**
   * If this method returns true, it is recommended that the input app provides
   * a shortcut that would invoke the next() method above, for easy switching
   * between inputs -- i.e. show a "global" button on screen if the input app
   * implements an on-screen virtual keyboard.
   *
   * The returning value is depend on the inputType of the current input context.
   */
  boolean supportsSwitching();

  /**
   * Ask the OS to remove the input focus, will cause the lost of input context.
   * OS should sliently ignore this request if the app is currently not the
   * active one.
   */
  void hide();

  /**
   * Update Gecko with information on the input types which supportsSwitching()
   * should return ture.
   *
   * @param types Array of input types in which supportsSwitching() should
   *              return true.
   */
  void setSupportsSwitchingTypes(sequence<MozInputMethodInputContextInputTypes> types);

  /**
   * CustomEvent dispatches to System when there is an input to handle.
   * If the API consumer failed to handle and call preventDefault(),
   * there will be a message printed on the console.
   *
   * evt.detail is defined by MozInputContextFocusEventDetail.
   */
  attribute EventHandler oninputcontextfocus;

  /**
   * Event dispatches to System when there is no longer an input to handle.
   * If the API consumer failed to handle and call preventDefault(),
   * there will be a message printed on the console.
   */
  attribute EventHandler oninputcontextblur;

  /**
   * Event dispatches to System when there is a showAll() call.
   * If the API consumer failed to handle and call preventDefault(),
   * there will be a message printed on the console.
   */
  attribute EventHandler onshowallrequest;

  /**
   * Event dispatches to System when there is a next() call.
   * If the API consumer failed to handle and call preventDefault(),
   * there will be a message printed on the console.
   */
  attribute EventHandler onnextrequest;

  /**
   * Event dispatches to System when there is a addInput() call.
   * The API consumer must call preventDefault() to indicate the event is
   * consumed, otherwise the request is not considered handled even if
   * waitUntil() was called.
   *
   * evt.detail is defined by MozInputRegistryEventDetail.
   */
  attribute EventHandler onaddinputrequest;

  /**
   * Event dispatches to System when there is a removeInput() call.
   * The API consumer must call preventDefault() to indicate the event is
   * consumed, otherwise the request is not considered handled even if
   * waitUntil() was called.
   *
   * evt.detail is defined by MozInputRegistryEventDetail.
   */
  attribute EventHandler onremoveinputrequest;
};

/**
 * Detail of the inputcontextfocus event.
 */
[JSImplementation="@mozilla.org/b2g-imm-focus;1",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozInputContextFocusEventDetail {
  /**
   * The type of the focused input.
   */
  readonly attribute MozInputMethodInputContextTypes type;
  /**
   * The input type of the focused input.
   */
  readonly attribute MozInputMethodInputContextInputTypes inputType;

  /**
   * The following is only needed for rendering and handling "option" input types,
   * in System app.
   */

  /**
   * Current value of the input.
   */
  readonly attribute DOMString? value;
  /**
   * An object representing all the <optgroup> and <option> elements
   * in the <select> element.
   */
  [Pure, Cached, Frozen]
  readonly attribute MozInputContextChoicesInfo? choices;
  /**
   * Max/min value of <input>
   */
  readonly attribute DOMString? min;
  readonly attribute DOMString? max;
};

/**
 * Information about the options within the <select> element.
 */
dictionary MozInputContextChoicesInfo {
  boolean multiple;
  sequence<MozInputMethodChoiceDict> choices;
};

/**
 * Content of the option header (<optgroup>) or an option (<option>).
 */
dictionary MozInputMethodChoiceDict {
  boolean group;
  DOMString text;
  boolean disabled;
  boolean? inGroup;
  boolean? selected;
  long? optionIndex;
};

/**
 * detail of addinputrequest or removeinputrequest event.
 */
[JSImplementation="@mozilla.org/b2g-imm-input-registry;1",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozInputRegistryEventDetail {
  /**
   * Manifest URL of the requesting app.
   */
  readonly attribute DOMString manifestURL;
  /**
   * ID of the input
   */
  readonly attribute DOMString inputId;
  /**
   * Input manifest of the input to add.
   * Null for removeinputrequest event.
   */
  [Pure, Cached, Frozen]
  readonly attribute MozInputMethodInputManifest? inputManifest;
  /**
   * Resolve or Reject the addInput() or removeInput() call when the passed
   * promises are resolved.
   */
  [Throws]
  void waitUntil(Promise<any> p);
};

/**
 * The input context, which consists of attributes and information of current
 * input field. It also hosts the methods available to the keyboard app to
 * mutate the input field represented. 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.
 */
[JSImplementation="@mozilla.org/b2g-inputcontext;1",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozInputContext: EventTarget {
  /**
   * Type of the InputContext. See MozInputMethodInputContextTypes
   */
  readonly attribute MozInputMethodInputContextTypes? type;

  /**
   * InputType of the InputContext. See MozInputMethodInputContextInputTypes.
   */
  readonly attribute MozInputMethodInputContextInputTypes? inputType;

  /**
   * The inputmode string, representing the inputmode of the input.
   * See http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#input-modalities:-the-inputmode-attribute
   */
  readonly attribute DOMString? inputMode;

  /**
   * The primary language for the input field.
   * It is the value of HTMLElement.lang.
   * See http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#htmlelement
   */
  readonly attribute DOMString? lang;

  /**
   * Get the whole text content of the input field.
   * @return DOMString
   */
  Promise<DOMString> getText(optional long offset, optional long length);

  /**
   * The start and stop position of the current selection.
   */
  readonly attribute long selectionStart;
  readonly attribute long selectionEnd;

  /**
   * The text in the current input.
   */
  readonly attribute DOMString? text;

  /**
   * The text before and after the begining of the selected text.
   *
   * You should use the text property instead because these properties are
   * truncated at 100 characters.
   */
  readonly attribute DOMString? textBeforeCursor;
  readonly attribute DOMString? textAfterCursor;

  /**
   * Set the selection range of the the editable text.
   * Note: This method cannot be used to move the cursor during composition. Calling this
   * method will cancel composition.
   * @param start The beginning of the selected text.
   * @param length The length of the selected text.
   *
   * 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.
   *
   * @return boolean
   */
  Promise<boolean> setSelectionRange(long start, long length);

  /* User moves the cursor, or changes the selection with other means. If the text around
   * cursor has changed, but the cursor has not been moved, the IME won't get notification.
   *
   * evt.detail is defined by MozInputContextSelectionChangeEventDetail.
   */
  attribute EventHandler onselectionchange;

  /**
   * Commit text to current input field and replace text around
   * cursor position. It will clear the current composition.
   *
   * @param text The string to be replaced with.
   * @param offset The offset from the cursor position where replacing starts. Defaults to 0.
   * @param length The length of text to replace. Defaults to 0.
   * @return boolean
   */
  Promise<boolean> replaceSurroundingText(DOMString text, optional long offset, optional long length);

  /**
   * Delete text around the cursor.
   * @param offset The offset from the cursor position where deletion starts.
   * @param length The length of text to delete.
   * TODO: maybe updateSurroundingText(DOMString beforeText, DOMString afterText); ?
   * @return boolean
   */
  Promise<boolean> deleteSurroundingText(long offset, long length);

  /**
   * Notifies when the text around the cursor is changed, due to either text
   * editing or cursor movement. If the cursor has been moved, but the text around has not
   * changed, the IME won't get notification.
   *
   * evt.detail is defined by MozInputContextSurroundingTextChangeEventDetail.
   */
  attribute EventHandler onsurroundingtextchange;

  /**
   * Send a string/character with its key events. There are two ways of invocating
   * the method for backward compability purpose.
   *
   * (1) The recommended way, allow specifying DOM level 3 properties like |code|.
   * @param dictOrKeyCode See MozInputMethodKeyboardEventDict.
   * @param charCode disregarded
   * @param modifiers disregarded
   * @param repeat disregarded
   *
   * (2) Deprecated, reserved for backward compability.
   * @param dictOrKeyCode keyCode of the key to send, should be one of the DOM_VK_ value in KeyboardEvent.
   * @param charCode charCode of the character, should be 0 for non-printable keys.
   * @param modifiers this paramater is no longer honored.
   * @param repeat indicates whether a key would be sent repeatedly.
   *
   * @return A promise. Resolve to true if succeeds.
   *                    Rejects to a string indicating the error.
   *
   * Note that, if you want to send a key n times repeatedly, make sure set
   * parameter repeat to true and invoke sendKey n times, and invoke keyup
   * after the end of the input.
   */
  Promise<boolean> sendKey((MozInputMethodRequiredKeyboardEventDict or long) dictOrKeyCode,
                           optional long charCode,
                           optional long modifiers,
                           optional boolean repeat);

  /**
   * Send a string/character with keydown, and keypress events.
   * keyup should be called afterwards to ensure properly sequence.
   *
   * @param dict See MozInputMethodKeyboardEventDict.
   *
   * @return A promise. Resolve to true if succeeds.
   *                    Rejects to a string indicating the error.
   */
  Promise<boolean> keydown(MozInputMethodRequiredKeyboardEventDict dict);

  /**
   * Send a keyup event. keydown should be called first to ensure properly sequence.
   *
   * @param dict See MozInputMethodKeyboardEventDict.
   *
   * @return A promise. Resolve to true if succeeds.
   *                    Rejects to a string indicating the error.
   */
  Promise<boolean> keyup(MozInputMethodRequiredKeyboardEventDict dict);

  /**
   * Set current composing text. This method will start composition or update
   * composition if it has started. The composition will be started right
   * before the cursor position and any selected text will be replaced by the
   * composing text. When the composition is started, calling this method can
   * update the text and move cursor winthin the range of the composing text.
   * @param text The new composition text to show.
   * @param cursor The new cursor position relative to the start of the
   * composition text. The cursor should be positioned within the composition
   * text. This means the value should be >= 0 and <= the length of
   * composition text. Defaults to the lenght of composition text, i.e., the
   * cursor will be positioned after the composition text.
   * @param clauses The array of composition clause information. If not set,
   * only one clause is supported.
   * @param dict The properties of the keyboard event that cause the composition
   * to set. keydown or keyup event will be fired if it's necessary.
   * For compatibility, we recommend that you should always set this argument
   * if it's caused by a key operation.
   *
   * The composing text, which is shown with underlined style to distinguish
   * from the existing text, is used to compose non-ASCII characters from
   * keystrokes, e.g. Pinyin or Hiragana. The composing text is the
   * intermediate text to help input complex character and is not committed to
   * current input field. Therefore if any text operation other than
   * composition is performed, the composition will automatically end. Same
   * apply when the inputContext is lost during an unfinished composition
   * session.
   *
   * To finish composition and commit text to current input field, an IME
   * should call |endComposition|.
   */
  Promise<boolean> setComposition(DOMString text,
                                  optional long cursor,
                                  optional sequence<CompositionClauseParameters> clauses,
                                  optional MozInputMethodKeyboardEventDict dict);

  /**
   * End composition, clear the composing text and commit given text to
   * current input field. The text will be committed before the cursor
   * position.
   * @param text The text to commited before cursor position. If empty string
   * is given, no text will be committed.
   * @param dict The properties of the keyboard event that cause the composition
   * to end. keydown or keyup event will be fired if it's necessary.
   * For compatibility, we recommend that you should always set this argument
   * if it's caused by a key operation.
   *
   * Note that composition always ends automatically with nothing to commit if
   * the composition does not explicitly end by calling |endComposition|, but
   * is interrupted by |sendKey|, |setSelectionRange|,
   * |replaceSurroundingText|, |deleteSurroundingText|, user moving the
   * cursor, changing the focus, etc.
   */
  Promise<boolean> endComposition(optional DOMString text,
                                  optional MozInputMethodKeyboardEventDict dict);

  /**
   * The interface used to receive the native events from hardware keyboard
   */
  readonly attribute MozHardwareInput? hardwareinput;
};

/*
 * This interface will be added into inputcontext and used to receive the
 * events from the hardware keyboard.
 * Example:
 *   mozInputMethod.inputcontext.hardwareinput.addEventListener('keyup', this);
 *   mozInputMethod.inputcontext.hardwareinput.removeEventListener('keyup', this);
 */
[JSImplementation="@mozilla.org/b2g-hardwareinput;1",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozHardwareInput: EventTarget {
};

/**
 * Detail of the selectionchange event.
 */
[JSImplementation="@mozilla.org/b2g-imm-selectionchange;1",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozInputContextSelectionChangeEventDetail {
  /**
   * Indicate whether or not the change is due to our own action from,
   * for example, sendKey() call.
   *
   * Note: this property is untrustworthy because it would still be true even
   * if script in the page changed the text synchronously upon responding to
   * events trigger by the call.
   */
  readonly attribute boolean ownAction;

  /**
   * The start and stop position of the current selection.
   */
  readonly attribute long selectionStart;
  readonly attribute long selectionEnd;
};

/**
 * Detail of the surroundingtextchange event.
 */
[JSImplementation="@mozilla.org/b2g-imm-surroundingtextchange;1",
 Pref="dom.mozInputMethod.enabled",
 ChromeOnly]
interface MozInputContextSurroundingTextChangeEventDetail {
  /**
   * Indicate whether or not the change is due to our own action from,
   * for example, sendKey() call.
   *
   * Note: this property is untrustworthy because it would still be true even
   * if script in the page changed the text synchronously upon responding to
   * events trigger by the call.
   */
  readonly attribute boolean ownAction;

  /**
   * The text in the current input.
   */
  readonly attribute DOMString? text;

  /**
   * The text before and after the begining of the selected text.
   *
   * You should use the text property instead because these properties are
   * truncated at 100 characters.
   */
  readonly attribute DOMString? textBeforeCursor;
  readonly attribute DOMString? textAfterCursor;
};

enum CompositionClauseSelectionType {
  "raw-input",
  "selected-raw-text",
  "converted-text",
  "selected-converted-text"
};

dictionary CompositionClauseParameters {
  CompositionClauseSelectionType selectionType = "raw-input";
  long length;
};

/**
 * Types are HTML tag names of the inputs that is explosed with InputContext,
 * *and* the special keyword "contenteditable" for contenteditable element.
 */
enum MozInputMethodInputContextTypes {
  "input", "textarea", "contenteditable",
  /**
   * <select> is managed by the API but it is handled by the System app only,
   * so this value is only accessible by System app from inputcontextfocus event.
   */
  "select"
};

/**
 * InputTypes of the input that InputContext is representing. The value
 * is inferred from the type attribute of element.
 *
 * See https://html.spec.whatwg.org/multipage/forms.html#states-of-the-type-attribute
 * for types of HTMLInputElement.
 *
 * They are divided into groups -- an layout/input capable of handling one type
 * in the group is considered as capable of handling all of the types in the
 * same group.
 * The layout/input that could handle type "text" is considered as the fallback
 * if none of layout/input installed can handle a specific type.
 *
 * Groups and fallbacks is enforced in Gaia System app currently.
 *
 * Noted that the actual virtual keyboard to show, for example in the case of
 * Gaia Keyboard app, will also depend on the inputMode of the input element.
 */
enum MozInputMethodInputContextInputTypes {
  /**
   * Group "text". Be reminded that contenteditable element is assigned with
   * an input type of "textarea".
   */
  "text", "search", "textarea",
  /**
   * Group "number"
   */
  "number", "tel",
  /**
   * Group "url"
   */
  "url",
  /**
   * Group "email"
   */
  "email",
  /**
   * Group "password".
   * An non-Latin alphabet layout/input should not be able to handle this type.
   */
  "password",
  /**
   * Group "option". These types are handled by System app itself currently, so
   * no input app will be set to active for these input types.
   * System app access these types from inputcontextfocus event.
   * ("select-one" and "select-multiple" are valid HTMLSelectElement#type.)
   */
  "datetime", "date", "month", "week", "time", "datetime-local", "color",
  "select-one", "select-multiple"
  /**
   * These types are ignored by the API even though they are valid
   * HTMLInputElement#type.
   */
  //"checkbox", "radio", "file", "submit", "image", "range", "reset", "button"
};

/**
 * An input app can host multiple inputs (a.k.a. layouts) and the capability of
 * the input is described by the input manifest.
 */
dictionary MozInputMethodInputManifest {
  required DOMString launch_path;
  required DOMString name;
  DOMString? description;
  sequence<MozInputMethodInputContextInputTypes> types;
};

/**
 * A MozInputMethodKeyboardEventDictBase contains the following properties,
 * indicating the properties of the keyboard event caused.
 *
 * This is the base dictionary type for us to create two child types that could
 * be used as argument type in two types of methods, as WebIDL parser required.
 *
 */
dictionary MozInputMethodKeyboardEventDictBase {
  /**
   * String/character to output, or a registered name of non-printable key.
   * (To be defined in the inheriting dictionary types.)
   */
  // DOMString key;
  /**
   * String/char indicating the virtual hardware key pressed. Optional.
   * Must be a value defined in
   * http://www.w3.org/TR/DOM-Level-3-Events-code/#keyboard-chording-virtual
   * If your keyboard app emulates physical keyboard layout, this value should
   * not be empty string. Otherwise, it should be empty string.
   */
  DOMString code = "";
  /**
   * keyCode of the keyboard event. Optional.
   * To be disregarded if |key| is an alphanumeric character.
   * If the key causes inputting a character and if your keyboard app emulates
   * a physical keyboard layout, this value should be same as the value used
   * by Firefox for desktop. If the key causes inputting an ASCII character
   * but if your keyboard app doesn't emulate any physical keyboard layouts,
   * the value should be proper value for the key value.
   */
  long? keyCode;
  /**
   * Indicates whether a key would be sent repeatedly. Optional.
   */
  boolean repeat = false;
  /**
   * Optional. True if |key| property is explicitly referring to a printable key.
   * When this is set, key will be printable even if the |key| value matches any
   * of the registered name of non-printable keys.
   */
  boolean printable = false;
};

/**
 * For methods like setComposition() and endComposition(), the optional
 * dictionary type argument is really optional when all of it's property
 * are optional.
 * This dictionary type is used to denote that argument.
 */
dictionary MozInputMethodKeyboardEventDict : MozInputMethodKeyboardEventDictBase {
  DOMString? key;
};

/**
 * For methods like keydown() and keyup(), the dictionary type argument is
 * considered required only if at least one of it's property is required.
 * This dictionary type is used to denote that argument.
 */
dictionary MozInputMethodRequiredKeyboardEventDict : MozInputMethodKeyboardEventDictBase {
  required DOMString key;
};