2015-01-28 06:27:32 +00:00
|
|
|
/* -*- 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;
|
2015-01-28 06:27:33 +00:00
|
|
|
interface nsITextInputProcessorCallback;
|
2015-01-28 06:27:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* An nsITextInputProcessor instance is associated with a top level widget which
|
|
|
|
* handles native IME. It's associated by calling init() or initForTests().
|
|
|
|
* 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 init() or initForTests() returns
|
|
|
|
* false (i.e., not throws an exception).
|
|
|
|
*
|
2015-01-28 06:27:33 +00:00
|
|
|
* NOTE: See nsITextInputProcessorCallback.idl for examples of |callback| in
|
|
|
|
* following examples,
|
|
|
|
*
|
2015-01-28 06:27:32 +00:00
|
|
|
* Example #1 JS-IME can start composition like this:
|
|
|
|
*
|
|
|
|
* var TIP = Components.classes["@mozilla.org/text-input-processor;1"].
|
|
|
|
* createInstance(Components.interfaces.nsITextInputProcessor);
|
2015-01-28 06:27:33 +00:00
|
|
|
* if (!TIP.init(window, callback)) {
|
2015-01-28 06:27:32 +00:00
|
|
|
* 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():
|
|
|
|
*
|
2015-01-28 06:27:33 +00:00
|
|
|
* if (!TIP.init(window, callback)) {
|
2015-01-28 06:27:32 +00:00
|
|
|
* return; // You failed to get the rights to make composition
|
|
|
|
* }
|
|
|
|
* TIP.commitComposition("Some words");
|
|
|
|
*
|
|
|
|
* Example #7 JS-IME can start composition explicitly:
|
|
|
|
*
|
2015-01-28 06:27:33 +00:00
|
|
|
* if (!TIP.init(window, callback)) {
|
2015-01-28 06:27:32 +00:00
|
|
|
* 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");
|
|
|
|
*/
|
|
|
|
|
2015-01-28 06:27:33 +00:00
|
|
|
[scriptable, builtinclass, uuid(8c20753c-8339-4e9c-86c5-ae30f1b456c3)]
|
2015-01-28 06:27:32 +00:00
|
|
|
interface nsITextInputProcessor : nsISupports
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* When you create an instance, you must call init() 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.
|
2015-01-28 06:27:33 +00:00
|
|
|
* @param aCallback Callback interface which handles requests to
|
|
|
|
* IME and notifications to IME. This must not be
|
|
|
|
* null.
|
2015-01-28 06:27:32 +00:00
|
|
|
* @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.
|
|
|
|
*/
|
2015-01-28 06:27:33 +00:00
|
|
|
boolean init(in nsIDOMWindow aWindow,
|
|
|
|
in nsITextInputProcessorCallback aCallback);
|
2015-01-28 06:27:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* When you create an instance for automated test, you must call
|
|
|
|
* initForTest(), first. See init() for more detail of this.
|
2015-01-28 06:27:33 +00:00
|
|
|
* Note that aCallback can be null. If it's null, nsITextInputProcessor
|
|
|
|
* implementation will handle them automatically.
|
2015-01-28 06:27:32 +00:00
|
|
|
*/
|
2015-01-28 06:27:33 +00:00
|
|
|
[optional_argc] boolean
|
|
|
|
initForTests(in nsIDOMWindow aWindow,
|
|
|
|
[optional] in nsITextInputProcessorCallback aCallback);
|
2015-01-28 06:27:32 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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"
|
|
|
|
%}
|