gecko-dev/dom/interfaces/base/nsITextInputProcessor.idl

278 lines
12 KiB
Plaintext
Raw Normal View History

/* -*- 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/. */
#include "nsISupports.idl"
interface nsIDOMWindow;
interface nsITextInputProcessorCallback;
/**
* An nsITextInputProcessor instance is associated with a top level widget which
* handles native IME. It's associated by calling beginInputTransaction() or
* beginInputTransactionForTests(). While an instance has composition, nobody
* can steal the rights to make composition on the top level widget. In other
* words, if another instance is composing on a top level widget, either
* beginInputTransaction() or beginInputTransactionForTests() returns false
* (i.e., not throws an exception).
*
* NOTE: See nsITextInputProcessorCallback.idl for examples of |callback| in
* following examples,
*
* Example #1 JS-IME can start composition like this:
*
* var TIP = Components.classes["@mozilla.org/text-input-processor;1"].
* createInstance(Components.interfaces.nsITextInputProcessor);
* if (!TIP.beginInputTransaction(window, callback)) {
* return; // You failed to get the rights to make composition
* }
* // Set new composition string first
* TIP.setPendingCompositionString("some-words-are-inputted");
* // Set clause information.
* TIP.appendClauseToPendingComposition(23, TIP.ATTR_RAW_CLAUSE);
* // Set caret position, this is optional.
* TIP.setCaretInPendingComposition(23);
* // Flush the pending composition
* if (!TIP.flushPendingComposition()) {
* // If it returns false, it fails to start composition.
* return;
* }
*
* Example #2 JS-IME can separate composition string to two or more clauses:
*
* // First, set composition string again
* TIP.setPendingCompositionString("some-words-are-inputted");
* // Then, if "are" is selected to convert, there are 3 clauses:
* TIP.appendClauseToPendingComposition(11, TIP.ATTR_CONVERTED_CLAUSE);
* TIP.appendClauseToPendingComposition(3, TIP.ATTR_SELECTED_CLAUSE);
* TIP.appendClauseToPendingComposition(9, TIP.ATTR_CONVERTED_CLAUSE);
* // Show caret at the beginning of the selected clause
* TIP.setCaretInPendingComposition(11);
* // Flush the pending composition. Note that if there is a composition,
* // flushPendingComposition() won't return false.
* TIP.flushPendingComposition();
*
* Example #3 JS-IME can commit composition with specific string with this:
*
* // First, there is a composition.
* TIP.setPendingCompositionString("some-words-directly-inputted");
* TIP.appendClauseToPendingComposition(28, TIP.ATTR_RAW_CLAUSE);
* TIP.flushPendingComposition();
* // This is useful when user selects a commit string from candidate list UI
* // which is provided by JS-IME.
* TIP.commitComposition("selected-words-from-candidate-list");
*
* Example #4 JS-IME can commit composition with the last composition string
* without specifying commit string:
*
* // First, there is a composition.
* TIP.setPendingCompositionString("some-words-will-be-commited");
* TIP.appendClauseToPendingComposition(27, TIP.ATTR_RAW_CLAUSE);
* TIP.flushPendingComposition();
* // This is useful when user just type Enter key.
* TIP.commitComposition();
*
* Example #5 JS-IME can cancel composition with this:
*
* // First, there is a composition.
* TIP.setPendingCompositionString("some-words-will-be-canceled");
* TIP.appendClauseToPendingComposition(27, TIP.ATTR_RAW_CLAUSE);
* TIP.flushPendingComposition();
* // This is useful when user doesn't want to commit the composition.
* // FYI: This is same as TIP.commitComposition("") for now.
* TIP.cancelComposition();
*
* Example #6 JS-IME can insert text only with commitComposition():
*
* if (!TIP.beginInputTransaction(window, callback)) {
* return; // You failed to get the rights to make composition
* }
* TIP.commitComposition("Some words");
*
* Example #7 JS-IME can start composition explicitly:
*
* if (!TIP.beginInputTransaction(window, callback)) {
* return; // You failed to get the rights to make composition
* }
* // If JS-IME don't want to show composing string in the focused editor,
* // JS-IME can dispatch only compositionstart event with this.
* if (!TIP.startComposition()) {
* // Failed to start composition.
* return;
* }
* // And when user selects a result from UI of JS-IME, commit with it.
* TIP.commitComposition("selected-words");
*/
[scriptable, builtinclass, uuid(512f1efe-9e0f-48a4-b423-3936ef948f34)]
interface nsITextInputProcessor : nsISupports
{
/**
* When you create an instance, you must call beginInputTransaction() first
* except when you created the instance for automated tests.
*
* @param aWindow A DOM window. The instance will look for a top
* level widget from this.
* @param aCallback Callback interface which handles requests to
* IME and notifications to IME. This must not be
* null.
* @return If somebody uses internal text input service for a
* composition, this returns false. Otherwise, returns
* true. I.e., only your TIP can create composition
* when this returns true. If this returns false,
* your TIP should wait next chance.
*/
boolean beginInputTransaction(in nsIDOMWindow aWindow,
in nsITextInputProcessorCallback aCallback);
/**
* When you create an instance for automated test, you must call
* beginInputTransaction(), first. See beginInputTransaction() for more
* detail of this.
* Note that aCallback can be null. If it's null, nsITextInputProcessor
* implementation will handle them automatically.
*/
[optional_argc] boolean
beginInputTransactionForTests(
in nsIDOMWindow aWindow,
[optional] in nsITextInputProcessorCallback aCallback);
/**
* startComposition() dispatches compositionstart event explicitly.
* IME does NOT need to call this typically since compositionstart event
* is automatically dispatched by sendPendingComposition() if
* compositionstart event hasn't been dispatched yet. If this is called
* when compositionstart has already been dispatched, this throws an
* exception.
*
* @return Returns true if composition starts normally.
* Otherwise, returns false because it might be
* canceled by the web application.
*/
boolean startComposition();
/**
* Set new composition string. Pending composition will be flushed by
* a call of flushPendingComposition(). However, if the new composition
* string isn't empty, you need to call appendClauseToPendingComposition() to
* fill all characters of aString with one or more clauses before flushing.
* Note that if you need to commit or cancel composition, use
* commitComposition() or cancelComposition().
*/
void setPendingCompositionString(in DOMString aString);
// ATTR_RAW_CLAUSE means that the clause hasn't been selected nor converted
// yet.
const unsigned long ATTR_RAW_CLAUSE = 0x02;
// ATTR_SELECTED_RAW_CLAUSE means that the clause hasn't been converted yet
// but is selected for converting to the other string.
const unsigned long ATTR_SELECTED_RAW_CLAUSE = 0x03;
// ATTR_CONVERTED_CLAUSE means that the clause has already been converted but
// is not selected. This does NOT mean that this clause isn't modifiable.
const unsigned long ATTR_CONVERTED_CLAUSE = 0x04;
// ATTR_SELECTED_CLAUSE means that the clause has already been converted and
// is selected. In other words, the clause is being converted.
const unsigned long ATTR_SELECTED_CLAUSE = 0x05;
/**
* Append a clause to the pending composition.
*
* If you need to fill the pending composition string with a clause, you
* should call this once. For example:
* appendClauseToPendingComposition(compositionString.length,
* ATTR_RAW_CLAUSE);
* is enough. If you need to separate the pending composition string to
* multiple clauses, you need to call this multiple times. For example,
* if your pending composition string has three clauses and the second clause
* is being converted:
* appendClauseToPendingComposition(firstClauseLength,
* ATTR_CONVERTED_CLAUSE);
* appendClauseToPendingComposition(secondClauseLength,
* ATTR_SELECTED_CLAUSE);
* appendClauseToPendingComposition(thirdClauseLength,
* ATTR_CONVERTED_CLAUSE);
* Note that if sum of aLength mismatches length of the pending composition
* string, flushPendingComposition() will throw an exception. I.e.,
* |firstClauseLength + secondClauseLength + thirdClauseLength| must be
* same as the length of pending composition string.
*
* TODO: Should be able to specify custom clause style.
*
* @param aLength Length of the clause.
* @param aAttribute One of ATTR_* constants.
*/
void appendClauseToPendingComposition(in unsigned long aLength,
in unsigned long aAttribute);
/**
* Set caret offset in the pending composition string. If you don't need to
* show a caret, you don't need to call this.
*
* @param aOffset Caret offset in the pending composition string.
* This must be between 0 and length of the pending
* composition string.
*/
void setCaretInPendingComposition(in unsigned long aOffset);
/**
* flushPendingComposition() must be called after
* setPendingCompositionString() and appendClauseToPendingComposition()
* (setCaretInPendingComposition() is optional) are called.
*
* Note that compositionstart will be automatically dispatched if this is
* called when there is no composition.
*
* Note that if sum of lengths of appended clauses are not same as composition
* string or caret offset is larger than the composition string length, this
* throws an exception.
*
* @return Returns true if there is a composition already or
* starting composition automatically.
* Otherwise, i.e., if it cannot start composition
* automatically, e.g., canceled by web apps, returns
* false.
*/
boolean flushPendingComposition();
/**
* commitComposition() will commit composition.
* If there is a composition which is started by the instance, this commits
* the composition. Otherwise, throws an exception.
*
* Note that if you tries to commit composition without specifying commit
* string when there is no composition, this throws an exception.
*
* @param aCommitString This is optional. If this is not specified,
* composition will be committed with the last
* composing string. Otherwise, committed with
* the specified string.
* @return Returns true if there is a composition already or
* starting composition automatically.
* Otherwise, i.e., if it cannot start composition
* automatically, e.g., canceled by web apps, returns
* false.
*/
[optional_argc]
boolean commitComposition([optional] in DOMString aCommitString);
/**
* cancelComposition() will cancel composition. This is for now the same as
* calling commitComposition(""). However, in the future, this might work
* better. If your IME needs to cancel composition, use this instead of
* commitComposition().
*
* Note that if you tries to cancel composition when there is no composition,
* this throws an exception.
*/
void cancelComposition();
};
%{C++
#define TEXT_INPUT_PROCESSOR_CID \
{ 0xcaaab47f, 0x1e31, 0x478e, \
{ 0x89, 0x19, 0x97, 0x09, 0x04, 0xe9, 0xcb, 0x72 } }
#define TEXT_INPUT_PROCESSOR_CONTRACTID \
"@mozilla.org/text-input-processor;1"
%}