tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsITextInputProcessor.idl (34591B)


      1 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "nsISupports.idl"
      7 
      8 interface mozIDOMWindow;
      9 interface nsITextInputProcessorCallback;
     10 
     11 webidl Event;
     12 
     13 /**
     14 * An nsITextInputProcessor instance is associated with a top level widget which
     15 * handles native IME.  It's associated by calling beginInputTransaction() or
     16 * beginInputTransactionForTests().  While an instance has composition, nobody
     17 * can steal the rights to make composition on the top level widget.  In other
     18 * words, if another instance is composing on a top level widget, either
     19 * beginInputTransaction() or beginInputTransactionForTests() returns false
     20 * (i.e., not throws an exception).
     21 *
     22 * NOTE: See nsITextInputProcessorCallback.idl for examples of |callback| in
     23 *       following examples,
     24 *
     25 * Example #1 JS-IME can start composition like this:
     26 *
     27 *   var TIP = Components.classes["@mozilla.org/text-input-processor;1"].
     28 *               createInstance(Components.interfaces.nsITextInputProcessor);
     29 *   if (!TIP.beginInputTransaction(window, callback)) {
     30 *     return; // You failed to get the rights to make composition
     31 *   }
     32 *   // Create a keyboard event if the following compositionc change is caused
     33 *   // by a key event.
     34 *   var keyEvent =
     35 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
     36 *   // Set new composition string first
     37 *   TIP.setPendingCompositionString("some-words-are-inputted");
     38 *   // Set clause information.
     39 *   TIP.appendClauseToPendingComposition(23, TIP.ATTR_RAW_CLAUSE);
     40 *   // Set caret position, this is optional.
     41 *   TIP.setCaretInPendingComposition(23);
     42 *   // Flush the pending composition
     43 *   if (!TIP.flushPendingComposition(keyEvent)) {
     44 *     // If it returns false, it fails to start composition.
     45 *     return;
     46 *   }
     47 *
     48 * Example #2 JS-IME can separate composition string to two or more clauses:
     49 *
     50 *   // Create a keyboard event if the following compositionc change is caused
     51 *   // by a key event.
     52 *   var keyEvent =
     53 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
     54 *   // First, set composition string again
     55 *   TIP.setPendingCompositionString("some-words-are-inputted");
     56 *   // Then, if "are" is selected to convert, there are 3 clauses:
     57 *   TIP.appendClauseToPendingComposition(11, TIP.ATTR_CONVERTED_CLAUSE);
     58 *   TIP.appendClauseToPendingComposition(3,  TIP.ATTR_SELECTED_CLAUSE);
     59 *   TIP.appendClauseToPendingComposition(9,  TIP.ATTR_CONVERTED_CLAUSE);
     60 *   // Show caret at the beginning of the selected clause
     61 *   TIP.setCaretInPendingComposition(11);
     62 *   // Flush the pending composition.  Note that if there is a composition,
     63 *   // flushPendingComposition() won't return false.
     64 *   TIP.flushPendingComposition(keyEvent);
     65 *
     66 * Example #3 JS-IME can commit composition with specific string with this:
     67 *
     68 *   // Create a keyboard event if the following compositionc change is caused
     69 *   // by a key event.
     70 *   var keyEvent1 =
     71 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
     72 *   // First, there is a composition.
     73 *   TIP.setPendingCompositionString("some-words-directly-inputted");
     74 *   TIP.appendClauseToPendingComposition(28, TIP.ATTR_RAW_CLAUSE);
     75 *   TIP.flushPendingComposition(keyEvent1);
     76 *   // Create a keyboard event if the following commit composition is caused
     77 *   // by a key event.
     78 *   var keyEvent2 =
     79 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
     80 *   // This is useful when user selects a commit string from candidate list UI
     81 *   // which is provided by JS-IME.
     82 *   TIP.commitCompositionWith("selected-words-from-candidate-list", keyEvent2);
     83 *
     84 * Example #4 JS-IME can commit composition with the last composition string
     85 *            without specifying commit string:
     86 *
     87 *   // Create a keyboard event if the following compositionc change is caused
     88 *   // by a key event.
     89 *   var keyEvent1 =
     90 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
     91 *   // First, there is a composition.
     92 *   TIP.setPendingCompositionString("some-words-will-be-commited");
     93 *   TIP.appendClauseToPendingComposition(27, TIP.ATTR_RAW_CLAUSE);
     94 *   TIP.flushPendingComposition(keyEvent1);
     95 *   // Create a keyboard event if the following commit is caused by a key
     96 *   // event.
     97 *   var keyEvent2 =
     98 *     new KeyboardEvent("", { key: "Enter", code: "Enter",
     99                               keyCode: KeyboardEvent.DOM_VK_RETURN });
    100 *   // This is useful when user just type Enter key.
    101 *   TIP.commitComposition(keyEvent2);
    102 *
    103 * Example #5 JS-IME can cancel composition with this:
    104 *
    105 *   // Create a keyboard event if the following composition change is caused
    106 *   // by a key event.
    107 *   var keyEvent1 =
    108 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
    109 *   // First, there is a composition.
    110 *   TIP.setPendingCompositionString("some-words-will-be-canceled");
    111 *   TIP.appendClauseToPendingComposition(27, TIP.ATTR_RAW_CLAUSE);
    112 *   TIP.flushPendingComposition(keyEvent1);
    113 *   // Create a keyboard event if the following canceling composition is
    114 *   // caused by a key event.
    115 *   var keyEvent2 =
    116 *     new KeyboardEvent("", { key: "Escape", code: "Escape",
    117                               keyCode: KeyboardEvent.DOM_VK_ESCAPE });
    118 *   // This is useful when user doesn't want to commit the composition.
    119 *   // FYI: This is same as TIP.commitCompositionWith("") for now.
    120 *   TIP.cancelComposition(keyEvent2);
    121 *
    122 * Example #6 JS-IME can insert text only with commitCompositionWith():
    123 *
    124 *   // Create a keyboard event if the following inserting text is caused by a
    125 *   // key event.
    126 *   var keyEvent1 =
    127 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
    128 *   if (!TIP.beginInputTransaction(window, callback)) {
    129 *     return; // You failed to get the rights to make composition
    130 *   }
    131 *   TIP.commitCompositionWith("Some words", keyEvent1);
    132 *
    133 * Example #7 JS-IME can start composition explicitly:
    134 *
    135 *   if (!TIP.beginInputTransaction(window, callback)) {
    136 *     return; // You failed to get the rights to make composition
    137 *   }
    138 *   // Create a keyboard event if the following starting composition is caused
    139 *   // by a key event.
    140 *   var keyEvent1 =
    141 *     new KeyboardEvent("", { key: "foo", code: "bar", keyCode: buzz });
    142 *   // If JS-IME don't want to show composing string in the focused editor,
    143 *   // JS-IME can dispatch only compositionstart event with this.
    144 *   if (!TIP.startComposition(keyEvent1)) {
    145 *     // Failed to start composition.
    146 *     return;
    147 *   }
    148 *   // And when user selects a result from UI of JS-IME, commit with it.
    149 *   // Then, the key event should be null.
    150 *   TIP.commitCompositionWith("selected-words");
    151 *
    152 * Example #8 JS-IME or JS-Keyboard should dispatch key events even during
    153 *            composition (non-printable key case):
    154 *
    155 *   if (!TIP.beginInputTransaction(window, callback)) {
    156 *     return; // You failed to get the rights to dispatch key events
    157 *   }
    158 *
    159 *   // You don't need to specify .keyCode value if it's non-printable key
    160 *   // because it can be computed from .key value.
    161 *   // If you specify non-zero value to .keyCode, it'll be used.
    162 *   var keyEvent = new KeyboardEvent("", { code: "Enter", key: "Enter" });
    163 *   if (TIP.keydown(keyEvent)) {
    164 *     // Handle its default action
    165 *   }
    166 *
    167 *   // Even if keydown event was consumed, keyup event should be dispatched.
    168 *   if (TIP.keyup(keyEvent)) {
    169 *     // Handle its default action
    170 *   }
    171 *
    172 * Example #9 JS-IME or JS-Keyboard should dispatch key events even during
    173 *            composition (printable key case):
    174 *
    175 *   if (!TIP.beginInputTransaction(window, callback)) {
    176 *     return; // You failed to get the rights to dispatch key events
    177 *   }
    178 *
    179 *   // You need to specify .keyCode value if it's printable key.
    180 *   // The rules of .keyCode value is documented in MDN:
    181 *   //   https://developer.mozilla.org/docs/Web/API/KeyboardEvent.keyCode
    182 *   //
    183 *   //   #1 If the key location is DOM_KEY_LOCATION_NUMPAD and NumLock is
    184 *   //      active, you should specify DOM_VK_NUMPAD[0-9], DOM_VK_MULTIPLY,
    185 *   //      DOM_VK_ADD, DOM_VK_SEPARATOR, DOM_VK_SUBTRACT, DOM_VK_DECIMAL or
    186 *   //      DOM_VK_DIVIDE.
    187 *   //   #2 If the key is Spacebar, use DOM_VK_SPACE.
    188 *   //
    189 *   //   Following rules are printable keys in DOM_KEY_LOCATION_STANDARD.
    190 *   //   .keyCode value for a key shouldn't be changed by modifier states:
    191 *   //     #1 If the key can input [0-9] with any modifier state (except
    192 *   //        NumLock state), the value should be DOM_VK_[0-9].
    193 *   //     #2 Otherwise, and if the key inputs an ASCII alphabet with no
    194 *   //        active modifiers, use DOM_VK_[A-Z].
    195 *   //     #3 Otherwise, and if the key inputs an ASCII alphabet with no
    196 *   //        active modifiers except Shift key state, use DOM_VK_[A-Z] for
    197 *   //        the shifted character.  E.g., if a key causes non-alphabet
    198 *   //        character such as "@" or a Unicode character without Shift key
    199 *   //        but "a" is inputted when Shift key is pressed, the proper
    200 *   //        keyCode is DOM_VK_A.
    201 *   //     #4 Otherwise, and if the key inputs another ASCII character with
    202 *   //        no modifier states, use a proper value for the character.  E.g.,
    203 *   //        if the key inputs "*" without Shift key state, it should be
    204 *   //        DOM_VK_ASTERISK.
    205 *   //     #5 Otherwise, and if the key inputs another ASCII character with
    206 *   //        Shift key state, use a proper value for the character.  E.g.,
    207 *   //        if a key causes a Unicode character without Shift key but "&"
    208 *   //        is inputted when Shift key is pressed, the proper keyCode is
    209 *   //        DOM_VK_AMPERSAND.
    210 *   //     See above document for the other cases.
    211 *   //
    212 *   // NOTE: If the software keyboard is 10-key like simple phone,
    213 *   //       We don't have common rules to decide its .keyCode value.
    214 *   //       Above rules should be used when the JS-Keyboard emulates PC
    215 *   //       keyboard.
    216 *   // .key value should be inputting character by the key with current
    217 *   // modifier state.
    218 *   // .code value should be empty string if the JS-Keyboard isn't emulating
    219 *   // physical keyboard.  Otherwise, use same value with physical keyboard's
    220 *   // same key.
    221 *   var keyEvent = new KeyboardEvent("", { code: "KeyA", key: "a",
    222 *                                          keyCode: KeyboardEvent.DOM_VK_A });
    223 *   if (TIP.keydown(keyEvent)) {
    224 *     // Handle its default action
    225 *   }
    226 *
    227 *   // Even if keydown event was consumed, keyup event should be dispatched.
    228 *   if (TIP.keyup(keyEvent)) {
    229 *     // Handle its default action
    230 *   }
    231 *
    232 * Example #10 JS-Keyboard doesn't need to initialize modifier states at
    233 *             calling either keydown() or keyup().
    234 *
    235 *   // Neither beginInputTransaction() nor beginInputTransactionForTests()
    236 *   // resets modifier state.
    237 *   if (!TIP.beginInputTransaction(window, callback)) {
    238 *     return; // You failed to get the rights to dispatch key events
    239 *   }
    240 *
    241 *   var leftShift = new KeyboardEvent("", { code: "ShiftLeft", key: "Shift" });
    242 *
    243 *   // This causes following key events will be shifted automatically.
    244 *   TIP.keydown(leftShift);
    245 *
    246 *   var rightShift =
    247 *     new KeyboardEvent("", { code: "ShiftRight", key: "Shift" });
    248 *
    249 *   TIP.keydown(rightShift);
    250 *
    251 *   // keyup of one of shift key doesn't cause inactivating "Shift" state.
    252 *   TIP.keyup(rightShift);
    253 *
    254 *   // This causes inactivating "Shift" state completely.
    255 *   TIP.keyup(leftShift);
    256 */
    257 
    258 [scriptable, builtinclass, uuid(47ae2181-2e98-4d58-84a2-b8db6764ce9a)]
    259 interface nsITextInputProcessor : nsISupports
    260 {
    261  /**
    262   * Returns true if this instance was dispatched compositionstart but hasn't
    263   * dispatched compositionend yet.
    264   */
    265  readonly attribute boolean hasComposition;
    266 
    267  /**
    268   * When you create an instance, you must call beginInputTransaction() first
    269   * except when you created the instance for automated tests.
    270   *
    271   * @param aWindow         A DOM window.  The instance will look for a top
    272   *                        level widget from this.
    273   * @param aCallback       Callback interface which handles requests to
    274   *                        IME and notifications to IME.  This must not be
    275   *                        null.
    276   * @return                If somebody uses internal text input service for a
    277   *                        composition, this returns false.  Otherwise, returns
    278   *                        true.  I.e., only your TIP can create composition
    279   *                        when this returns true.  If this returns false,
    280   *                        your TIP should wait next chance.
    281   */
    282  boolean beginInputTransaction(in mozIDOMWindow aWindow,
    283                                in nsITextInputProcessorCallback aCallback);
    284 
    285  /**
    286   * When you create an instance for automated test, you must call
    287   * beginInputTransaction(), first.  See beginInputTransaction() for more
    288   * detail of this.
    289   * Note that aCallback can be null.  If it's null, nsITextInputProcessor
    290   * implementation will handle them automatically.
    291   */
    292  [optional_argc] boolean
    293    beginInputTransactionForTests(
    294      in mozIDOMWindow aWindow,
    295      [optional] in nsITextInputProcessorCallback aCallback);
    296 
    297  /**
    298   * startComposition() dispatches compositionstart event explicitly.
    299   * IME does NOT need to call this typically since compositionstart event
    300   * is automatically dispatched by sendPendingComposition() if
    301   * compositionstart event hasn't been dispatched yet.  If this is called
    302   * when compositionstart has already been dispatched, this throws an
    303   * exception.
    304   *
    305   * @param aKeyboardEvent  Key event which causes starting composition.
    306   *                        If its type value is "keydown", this method
    307   *                        dispatches only keydown event first.  Otherwise,
    308   *                        dispatches keydown first and keyup at last.
    309   *                        key value and keyCode values of keydown event
    310   *                        are set to "Process" and DOM_VK_PROCESSKEY
    311   *                        automatically.  You can prevent this behavior
    312   *                        with KEY_DONT_MARK_KEYDOWN_AS_PROCESSED.
    313   * @param aKeyFlags       See KEY_* constants.
    314   * @return                Returns true if composition starts normally.
    315   *                        Otherwise, returns false because it might be
    316   *                        canceled by the web application.
    317   */
    318  [can_run_script, optional_argc]
    319    boolean startComposition([optional] in Event aKeyboardEvent,
    320                             [optional] in unsigned long aKeyFlags);
    321 
    322  /**
    323   * Set new composition string.  Pending composition will be flushed by
    324   * a call of flushPendingComposition().  However, if the new composition
    325   * string isn't empty, you need to call appendClauseToPendingComposition() to
    326   * fill all characters of aString with one or more clauses before flushing.
    327   * Note that if you need to commit or cancel composition, use
    328   * commitComposition(), commitCompositionWith() or cancelComposition().
    329   */
    330  void setPendingCompositionString(in AString aString);
    331 
    332  // ATTR_RAW_CLAUSE means that the clause hasn't been selected nor converted
    333  // yet.
    334  const unsigned long ATTR_RAW_CLAUSE           = 0x02;
    335  // ATTR_SELECTED_RAW_CLAUSE means that the clause hasn't been converted yet
    336  // but is selected for converting to the other string.
    337  const unsigned long ATTR_SELECTED_RAW_CLAUSE  = 0x03;
    338  // ATTR_CONVERTED_CLAUSE means that the clause has already been converted but
    339  // is not selected.  This does NOT mean that this clause isn't modifiable.
    340  const unsigned long ATTR_CONVERTED_CLAUSE     = 0x04;
    341  // ATTR_SELECTED_CLAUSE means that the clause has already been converted and
    342  // is selected.  In other words, the clause is being converted.
    343  const unsigned long ATTR_SELECTED_CLAUSE      = 0x05;
    344 
    345  /**
    346   * Append a clause to the pending composition.
    347   *
    348   * If you need to fill the pending composition string with a clause, you
    349   * should call this once.  For example:
    350   *   appendClauseToPendingComposition(compositionString.length,
    351   *                                    ATTR_RAW_CLAUSE);
    352   * is enough.  If you need to separate the pending composition string to
    353   * multiple clauses, you need to call this multiple times. For example,
    354   * if your pending composition string has three clauses and the second clause
    355   * is being converted:
    356   *  appendClauseToPendingComposition(firstClauseLength,
    357   *                                   ATTR_CONVERTED_CLAUSE);
    358   *  appendClauseToPendingComposition(secondClauseLength,
    359   *                                   ATTR_SELECTED_CLAUSE);
    360   *  appendClauseToPendingComposition(thirdClauseLength,
    361   *                                   ATTR_CONVERTED_CLAUSE);
    362   * Note that if sum of aLength mismatches length of the pending composition
    363   * string, flushPendingComposition() will throw an exception.  I.e.,
    364   * |firstClauseLength + secondClauseLength + thirdClauseLength| must be
    365   * same as the length of pending composition string.
    366   *
    367   * TODO: Should be able to specify custom clause style.
    368   *
    369   * @param aLength         Length of the clause.
    370   * @param aAttribute      One of ATTR_* constants.
    371   */
    372  void appendClauseToPendingComposition(in unsigned long aLength,
    373                                        in unsigned long aAttribute);
    374 
    375  /**
    376   * Set caret offset in the pending composition string.  If you don't need to
    377   * show a caret, you don't need to call this.
    378   *
    379   * @param aOffset         Caret offset in the pending composition string.
    380   *                        This must be between 0 and length of the pending
    381   *                        composition string.
    382   */
    383  void setCaretInPendingComposition(in unsigned long aOffset);
    384 
    385  /**
    386   * flushPendingComposition() must be called after
    387   * setPendingCompositionString() and appendClauseToPendingComposition()
    388   * (setCaretInPendingComposition() is optional) are called.
    389   *
    390   * Note that compositionstart will be automatically dispatched if this is
    391   * called when there is no composition.
    392   *
    393   * Note that if sum of lengths of appended clauses are not same as composition
    394   * string or caret offset is larger than the composition string length, this
    395   * throws an exception.
    396   *
    397   * @param aKeyboardEvent  Key event which causes the composition string.
    398   *                        If its type value is "keydown", this method
    399   *                        dispatches only keydown event first.  Otherwise,
    400   *                        dispatches keydown first and keyup at last.
    401   *                        key value and keyCode values of keydown event
    402   *                        are set to "Process" and DOM_VK_PROCESSKEY
    403   *                        automatically.  You can prevent this behavior
    404   *                        with KEY_DONT_MARK_KEYDOWN_AS_PROCESSED.
    405   * @param aKeyFlags       See KEY_* constants.
    406   * @return                Returns true if there is a composition already or
    407   *                        starting composition automatically.
    408   *                        Otherwise, i.e., if it cannot start composition
    409   *                        automatically, e.g., canceled by web apps, returns
    410   *                        false.
    411   */
    412  [can_run_script, optional_argc]
    413    boolean flushPendingComposition(
    414      [optional] in Event aKeyboardEvent,
    415      [optional] in unsigned long aKeyFlags);
    416 
    417  /**
    418   * commitComposition() will commit composition with the last composition
    419   * string.  If there is no composition, this will throw an exception.
    420   *
    421   * @param aKeyboardEvent  Key event which causes the commit composition.
    422   *                        If its type value is "keydown", this method
    423   *                        dispatches only keydown event first.  Otherwise,
    424   *                        dispatches keydown first and keyup at last.
    425   *                        key value and keyCode values of keydown event
    426   *                        are set to "Process" and DOM_VK_PROCESSKEY
    427   *                        automatically.  You can prevent this behavior
    428   *                        with KEY_DONT_MARK_KEYDOWN_AS_PROCESSED.
    429   * @param aKeyFlags       See KEY_* constants.
    430   */
    431  [can_run_script, optional_argc]
    432    void commitComposition([optional] in Event aKeyboardEvent,
    433                           [optional] in unsigned long aKeyFlags);
    434 
    435  /**
    436   * commitCompositionWith() will commit composition with the specific string.
    437   * If there is no composition, this will start composition and commit it
    438   * with the specified string.
    439   *
    440   * @param aCommitString   The string to be committed.
    441   * @param aKeyboardEvent  Key event which causes the commit composition.
    442   *                        If its type value is "keydown", this method
    443   *                        dispatches only keydown event first.  Otherwise,
    444   *                        dispatches keydown first and keyup at last.
    445   *                        key value and keyCode values of keydown event
    446   *                        are set to "Process" and DOM_VK_PROCESSKEY
    447   *                        automatically.  You can prevent this behavior
    448   *                        with KEY_DONT_MARK_KEYDOWN_AS_PROCESSED.
    449   * @param aKeyFlags       See KEY_* constants.
    450   * @return                Returns true if there is a composition already or
    451   *                        starting composition automatically.
    452   *                        Otherwise, i.e., if it cannot start composition
    453   *                        automatically, e.g., canceled by web apps, returns
    454   *                        false.
    455   */
    456  [can_run_script, optional_argc]
    457    boolean commitCompositionWith(in AString aCommitString,
    458                                  [optional] in Event aKeyboardEvent,
    459                                  [optional] in unsigned long aKeyFlags);
    460 
    461  /**
    462   * cancelComposition() will cancel composition.  This is for now the same as
    463   * calling commitComposition("").  However, in the future, this might work
    464   * better.  If your IME needs to cancel composition, use this instead of
    465   * commitComposition().
    466   *
    467   * Note that if you tries to cancel composition when there is no composition,
    468   * this throws an exception.
    469   *
    470   * @param aKeyboardEvent  Key event which causes the canceling composition.
    471   *                        If its type value is "keydown", this method
    472   *                        dispatches only keydown event first.  Otherwise,
    473   *                        dispatches keydown first and keyup at last.
    474   *                        key value and keyCode values of keydown event
    475   *                        are set to "Process" and DOM_VK_PROCESSKEY
    476   *                        automatically.  You can prevent this behavior
    477   *                        with KEY_DONT_MARK_KEYDOWN_AS_PROCESSED.
    478   * @param aKeyFlags       See KEY_* constants.
    479   */
    480  [can_run_script, optional_argc]
    481    void cancelComposition([optional] in Event aKeyboardEvent,
    482                           [optional] in unsigned long aKeyFlags);
    483 
    484  // Specifying KEY_DEFAULT_PREVENTED can dispatch key events whose
    485  // defaultPrevented are true.  Note that if this is specified, keypress event
    486  // won't be fired.
    487  const unsigned long KEY_DEFAULT_PREVENTED                        = 0x00000001;
    488  // If KEY_NON_PRINTABLE_KEY is specified and the .key value isn't valid
    489  // key name, the methods will throws an exception.  In other words, this
    490  // flag prevents to dispatch key events with wrong key values and to cause
    491  // such key events input the key values as text.
    492  const unsigned long KEY_NON_PRINTABLE_KEY                        = 0x00000002;
    493  // If KEY_FORCE_PRINTABLE_KEY is specified and even if the .key value is a
    494  // registered key name, it's treated as inputting text value.
    495  const unsigned long KEY_FORCE_PRINTABLE_KEY                      = 0x00000004;
    496  // If KEY_KEEP_KEY_LOCATION_STANDARD is specified when its .location is not
    497  // initialized or initialized with 0, the value isn't computed with .code
    498  // value.  Note that if .location is initialized with non-zero value,
    499  // this flag causes throwing an exception.
    500  // NOTE: This is not recommended to use except for tests.
    501  const unsigned long KEY_KEEP_KEY_LOCATION_STANDARD               = 0x00000008;
    502  // If KEY_KEEP_KEYCODE_ZERO is specified when its .keyCode is not initialized
    503  // or initialized with 0, the value isn't computed with .key value when it
    504  // represents non-printable key.  Note that if .keyCode is initialized with
    505  // non-zero value, this flag causes throwing an exception.
    506  const unsigned long KEY_KEEP_KEYCODE_ZERO                        = 0x00000010;
    507  // If KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT is specified when the key event is
    508  // a modifier key's, keydown() and keyup() only modifies its modifier state
    509  // without dispatching key events.  This is useful for testing odd behavior
    510  // or emulating legacy API behavior.
    511  const unsigned long KEY_DONT_DISPATCH_MODIFIER_KEY_EVENT         = 0x00000020;
    512  // If KEY_DONT_MARK_KEYDOWN_AS_PROCESSED is specified, key value and keyCode
    513  // value of keydown event are not changed to "Process" and DOM_VK_PROCESSKEY.
    514  const unsigned long KEY_DONT_MARK_KEYDOWN_AS_PROCESSED           = 0x00000040;
    515  // If KEY_MARK_KEYUP_AS_PROCESSED is specified, key value and keyCode value
    516  // of keyup event are changed to "Process" and DOM_VK_PROCESSKEY.
    517  const unsigned long KEY_MARK_KEYUP_AS_PROCESSED                  = 0x00000080;
    518 
    519  // These values can be used to do bitwise operation with the return value of
    520  // the keydown() method.
    521  const unsigned long KEYEVENT_NOT_CONSUMED                        = 0x00000000;
    522  const unsigned long KEYDOWN_IS_CONSUMED                          = 0x00000001;
    523  const unsigned long KEYPRESS_IS_CONSUMED                         = 0x00000002;
    524 
    525  /**
    526   * keydown() may dispatch a keydown event and some keypress events if
    527   * preceding keydown event isn't consumed and they are necessary.
    528   * Note that even if this is called during composition, key events may not
    529   * be dispatched.  In this case, this returns false.
    530   *
    531   * You should initialize at least .key value and .code value of the event.
    532   * Additionally, if you try to emulate a printable key, .keyCode value should
    533   * be specified if there is proper key value.  See the comment of above
    534   * example how to decide .keyCode value of a printable key.  On the other
    535   * hand, .keyCode value is automatically computed when you try to emulate
    536   * non-printable key.  However, if you try to emulate physical keyboard of
    537   * desktop platform, you need to specify proper value explicitly because
    538   * the mapping table of this API isn't enough to emulate the behavior of
    539   * Gecko for desktop platforms.
    540   *
    541   * NOTE: Even if this has composition, JS-Keyboard should call keydown() and
    542   *       keyup().  Although, with the default preferences and normal
    543   *       conditions, DOM key events won't be fired during composition.
    544   *       However, they MAY be dispatched for some reasons, e.g., the web
    545   *       content listens only key events, or if the standard DOM event spec
    546   *       will be changed in the future.
    547   *
    548   * @param aKeyboardEvent  Must be a keyboard event which should be dispatched
    549   *                        as a keydown event and keypress events.
    550   *                        #1 Note that you don't need to set charCode value
    551   *                        because it's computed from its key value.
    552   *                        #2 If code value is set properly and location value
    553   *                        isn't specified (i.e., 0), the location value will
    554   *                        be guessed from the code value.
    555   *                        #3 Non-defined code names are not allowed. If your
    556   *                        key isn't registered, file a bug. If your key isn't
    557   *                        defined by any standards, use "" (empty string).
    558   *                        #4 .keyCode is guessed from .key value if the key
    559   *                        name is registered and .keyCode isn't initialized.
    560   *                        #5 modifier key states, e.g., .shiftKey, are
    561   *                        ignored.  Instead, modifier states are managed by
    562   *                        each instance and set automatically.
    563   * @param aKeyFlags       Special flags.  The values can be some of KEY_*
    564   *                        constants.
    565   * @return                KEYEVENT_NOT_CONSUMED, if the keydown event nor
    566   *                        the following keypress event(s) are consumed.
    567   *                        KEYDOWN_IS_CONSUMED, if the keydown event is
    568   *                        consumed. No keypress event will be dispatched in
    569   *                        this case.
    570   *                        KEYPRESS_IS_CONSUMED, if the keypress event(s) is
    571   *                        consumed when dispatched.
    572   *                        Note that keypress event is always consumed by
    573   *                        native code for the printable keys (indicating the
    574   *                        default action has been taken).
    575   */
    576  [can_run_script, optional_argc]
    577    unsigned long keydown(in Event aKeyboardEvent,
    578                          [optional] in unsigned long aKeyFlags);
    579 
    580  /**
    581   * Similar to keydown(), but this dispatches only a keyup event.
    582   */
    583  [optional_argc]
    584    boolean keyup(in Event aKeyboardEvent,
    585                  [optional] in unsigned long aKeyFlags);
    586 
    587  /**
    588   * insertTextWithKeyPress() is designed for automated tests.  This dispatches
    589   * isolated eKeyPress events to insert aString if selection is in an editable
    590   * element.
    591   *
    592   * @aString           The string which will be inserted.
    593   * @aKeyboardEvent    [optional]  This is nullable.   If specified as
    594   *                    non-nullptr, the insertion is emulated as caused by the
    595   *                    key event.
    596   * @param aKeyFlags   Special flags.  The values can be some of KEY_*
    597   *                    constants.
    598   * @return            false if one of the dispatched eKeyPress event is
    599   *                    consumed.
    600   */
    601  [can_run_script, optional_argc]
    602    boolean insertTextWithKeyPress(in AString aString,
    603                                   [optional] in Event aKeyboardEvent,
    604                                   [optional] in unsigned long aKeyFlags);
    605 
    606  /**
    607   * getModifierState() returns modifier state managed by this instance.
    608   *
    609   * @param aModifier       One of modifier key names.  This doesn't support
    610   *                        virtual modifiers like "Accel".
    611   * @return                true if the modifier key is active.  Otherwise,
    612   *                        false.
    613   */
    614  boolean getModifierState(in AString aModifierKey);
    615 
    616  /**
    617   * shareModifierStateOf() makes the instance shares modifier state of
    618   * another instance.  When this is called, the instance refers the modifier
    619   * state of another instance.  After that, changes to either this and the
    620   * other instance's modifier state is synchronized.
    621   *
    622   * @param aOther          Another instance which will be referred by the
    623   *                        instance.  If this is null, the instance restarts
    624   *                        to manage modifier state independently.
    625   */
    626  void shareModifierStateOf(in nsITextInputProcessor aOther);
    627 
    628  /**
    629   * Helper method to get usual |.code| value of non-printable keys.
    630   *
    631   * @param aKeyValue       A predefined key value such as "Enter".
    632   *                        If this is not a proper non-printable key value
    633   *                        or a proper key value but not in usual keyboard of
    634   *                        the platform, this returns empty string.
    635   * @param aLocation       The |.location| value.  This is important if
    636   *                        the key may be in different location.
    637   *                        E.g., Left vs. Right or Standard vs. Numpad.
    638   *                        If this is undefined or null, it'll be treated
    639   *                        as Standard or Left.
    640   * @return                One of a code value of well-known key on usual
    641   *                        keyboard on the platform, or empty string.
    642   */
    643  [optional_argc]
    644    AString computeCodeValueOfNonPrintableKey(
    645              in AString aKeyValue,
    646              [optional] in jsval aLocation);
    647 
    648  /**
    649   * Helper method to guess |.code| value of a printable key which is in usual
    650   * keyboard of the platform and when active keyboard layout is US-English.
    651   * Note that this is not aware of option key mapping on macOS.
    652   *
    653   * @param aKeyValue          The key value. Must be a character which can
    654   *                           be inputted with US-English keyboard layout.
    655   * @param aLocation          The location of the key.  This is important
    656   *                           to distinguish whether the key is in Standard
    657   *                           or Numpad. If this is undefined or null, will
    658   *                           be treated as Standard.
    659   * @return                   Returns empty string if there is no proper key.
    660   */
    661  [optional_argc]
    662    AString guessCodeValueOfPrintableKeyInUSEnglishKeyboardLayout(
    663              in AString aKeyValue,
    664              [optional] in jsval aLocation);
    665 
    666  /**
    667   * Helper method to guess |.keyCode| value of a printable key which is in
    668   * usual keyboard of the platform and when active keyboard layout is
    669   * US-English.
    670   * Note that this is not aware of option key mapping on macOS.
    671   *
    672   * @param aKeyValue          The key value.  Must be a character which can
    673   *                           be inputted with US-English keyboard layout.
    674   * @param aLocation          The location of the key.  This is important
    675   *                           to distinguish whether the key is in Standard
    676   *                           our Numpad.  If this is undefined or null,
    677   *                           will be treated as Standard.
    678   * @return                   Returns 0 if there is no proper key to input
    679   *                           aKeyValue with US-English keyboard layout.
    680   */
    681  [optional_argc]
    682    unsigned long guessKeyCodeValueOfPrintableKeyInUSEnglishKeyboardLayout(
    683                    in AString aKeyValue,
    684                    [optional] in jsval aLocation);
    685 };