mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1234459 - Expose full text in the input box to InputMethod API, r=masayuki, sr=smaug
This commit is contained in:
parent
830784d6b5
commit
f67c190aa1
@ -57,7 +57,7 @@ this.Keyboard = {
|
||||
'RemoveFocus',
|
||||
'SetSelectionRange', 'ReplaceSurroundingText', 'ShowInputMethodPicker',
|
||||
'SwitchToNextInputMethod', 'HideInputMethod',
|
||||
'GetText', 'SendKey', 'GetContext',
|
||||
'SendKey', 'GetContext',
|
||||
'SetComposition', 'EndComposition',
|
||||
'RegisterSync', 'Unregister'
|
||||
],
|
||||
@ -162,8 +162,6 @@ this.Keyboard = {
|
||||
mm.addMessageListener('Forms:Focus', this);
|
||||
mm.addMessageListener('Forms:Blur', this);
|
||||
mm.addMessageListener('Forms:SelectionChange', this);
|
||||
mm.addMessageListener('Forms:GetText:Result:OK', this);
|
||||
mm.addMessageListener('Forms:GetText:Result:Error', this);
|
||||
mm.addMessageListener('Forms:SetSelectionRange:Result:OK', this);
|
||||
mm.addMessageListener('Forms:SetSelectionRange:Result:Error', this);
|
||||
mm.addMessageListener('Forms:ReplaceSurroundingText:Result:OK', this);
|
||||
@ -226,8 +224,6 @@ this.Keyboard = {
|
||||
this.handleBlur(msg);
|
||||
break;
|
||||
case 'Forms:SelectionChange':
|
||||
case 'Forms:GetText:Result:OK':
|
||||
case 'Forms:GetText:Result:Error':
|
||||
case 'Forms:SetSelectionRange:Result:OK':
|
||||
case 'Forms:ReplaceSurroundingText:Result:OK':
|
||||
case 'Forms:SendKey:Result:OK':
|
||||
@ -288,9 +284,6 @@ this.Keyboard = {
|
||||
case 'Keyboard:ShowInputMethodPicker':
|
||||
this.showInputMethodPicker();
|
||||
break;
|
||||
case 'Keyboard:GetText':
|
||||
this.getText(msg);
|
||||
break;
|
||||
case 'Keyboard:SendKey':
|
||||
this.sendKey(msg);
|
||||
break;
|
||||
@ -423,10 +416,6 @@ this.Keyboard = {
|
||||
});
|
||||
},
|
||||
|
||||
getText: function keyboardGetText(msg) {
|
||||
this.sendToForm('Forms:GetText', msg.data);
|
||||
},
|
||||
|
||||
sendKey: function keyboardSendKey(msg) {
|
||||
this.sendToForm('Forms:Input:SendKey', msg.data);
|
||||
},
|
||||
|
@ -739,24 +739,67 @@ InputContextDOMRequestIpcHelper.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function MozInputContextSelectionChangeEventDetail(ctx, ownAction) {
|
||||
this._ctx = ctx;
|
||||
this.ownAction = ownAction;
|
||||
}
|
||||
|
||||
MozInputContextSelectionChangeEventDetail.prototype = {
|
||||
classID: Components.ID("ef35443e-a400-4ae3-9170-c2f4e05f7aed"),
|
||||
QueryInterface: XPCOMUtils.generateQI([]),
|
||||
|
||||
ownAction: false,
|
||||
|
||||
get selectionStart() {
|
||||
return this._ctx.selectionStart;
|
||||
},
|
||||
|
||||
get selectionEnd() {
|
||||
return this._ctx.selectionEnd;
|
||||
}
|
||||
};
|
||||
|
||||
function MozInputContextSurroundingTextChangeEventDetail(ctx, ownAction) {
|
||||
this._ctx = ctx;
|
||||
this.ownAction = ownAction;
|
||||
}
|
||||
|
||||
MozInputContextSurroundingTextChangeEventDetail.prototype = {
|
||||
classID: Components.ID("1c50fdaf-74af-4b2e-814f-792caf65a168"),
|
||||
QueryInterface: XPCOMUtils.generateQI([]),
|
||||
|
||||
ownAction: false,
|
||||
|
||||
get text() {
|
||||
return this._ctx.text;
|
||||
},
|
||||
|
||||
get textBeforeCursor() {
|
||||
return this._ctx.textBeforeCursor;
|
||||
},
|
||||
|
||||
get textAfterCursor() {
|
||||
return this._ctx.textAfterCursor;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* ==============================================
|
||||
* InputContext
|
||||
* ==============================================
|
||||
*/
|
||||
function MozInputContext(ctx) {
|
||||
function MozInputContext(data) {
|
||||
this._context = {
|
||||
type: ctx.type,
|
||||
inputType: ctx.inputType,
|
||||
inputMode: ctx.inputMode,
|
||||
lang: ctx.lang,
|
||||
selectionStart: ctx.selectionStart,
|
||||
selectionEnd: ctx.selectionEnd,
|
||||
textBeforeCursor: ctx.textBeforeCursor,
|
||||
textAfterCursor: ctx.textAfterCursor
|
||||
type: data.type,
|
||||
inputType: data.inputType,
|
||||
inputMode: data.inputMode,
|
||||
lang: data.lang,
|
||||
selectionStart: data.selectionStart,
|
||||
selectionEnd: data.selectionEnd,
|
||||
text: data.value
|
||||
};
|
||||
|
||||
this._contextId = ctx.contextId;
|
||||
this._contextId = data.contextId;
|
||||
}
|
||||
|
||||
MozInputContext.prototype = {
|
||||
@ -849,48 +892,45 @@ MozInputContext.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
updateSelectionContext: function ic_updateSelectionContext(ctx, ownAction) {
|
||||
updateSelectionContext: function ic_updateSelectionContext(data, ownAction) {
|
||||
if (!this._context) {
|
||||
return;
|
||||
}
|
||||
|
||||
let selectionDirty = this._context.selectionStart !== ctx.selectionStart ||
|
||||
this._context.selectionEnd !== ctx.selectionEnd;
|
||||
let surroundDirty = this._context.textBeforeCursor !== ctx.textBeforeCursor ||
|
||||
this._context.textAfterCursor !== ctx.textAfterCursor;
|
||||
let selectionDirty =
|
||||
this._context.selectionStart !== data.selectionStart ||
|
||||
this._context.selectionEnd !== data.selectionEnd;
|
||||
let surroundDirty = selectionDirty || data.text !== this._contextId.text;
|
||||
|
||||
this._context.selectionStart = ctx.selectionStart;
|
||||
this._context.selectionEnd = ctx.selectionEnd;
|
||||
this._context.textBeforeCursor = ctx.textBeforeCursor;
|
||||
this._context.textAfterCursor = ctx.textAfterCursor;
|
||||
this._context.text = data.text;
|
||||
this._context.selectionStart = data.selectionStart;
|
||||
this._context.selectionEnd = data.selectionEnd;
|
||||
|
||||
if (selectionDirty) {
|
||||
this._fireEvent("selectionchange", {
|
||||
selectionStart: ctx.selectionStart,
|
||||
selectionEnd: ctx.selectionEnd,
|
||||
ownAction: ownAction
|
||||
});
|
||||
let selectionChangeDetail =
|
||||
new MozInputContextSelectionChangeEventDetail(this, ownAction);
|
||||
let wrappedSelectionChangeDetail =
|
||||
this._window.MozInputContextSelectionChangeEventDetail
|
||||
._create(this._window, selectionChangeDetail);
|
||||
let selectionChangeEvent = new this._window.CustomEvent("selectionchange",
|
||||
{ cancelable: false, detail: wrappedSelectionChangeDetail });
|
||||
|
||||
this.__DOM_IMPL__.dispatchEvent(selectionChangeEvent);
|
||||
}
|
||||
|
||||
if (surroundDirty) {
|
||||
this._fireEvent("surroundingtextchange", {
|
||||
beforeString: ctx.textBeforeCursor,
|
||||
afterString: ctx.textAfterCursor,
|
||||
ownAction: ownAction
|
||||
});
|
||||
let surroundingTextChangeDetail =
|
||||
new MozInputContextSurroundingTextChangeEventDetail(this, ownAction);
|
||||
let wrappedSurroundingTextChangeDetail =
|
||||
this._window.MozInputContextSurroundingTextChangeEventDetail
|
||||
._create(this._window, surroundingTextChangeDetail);
|
||||
let selectionChangeEvent = new this._window.CustomEvent("surroundingtextchange",
|
||||
{ cancelable: false, detail: wrappedSurroundingTextChangeDetail });
|
||||
|
||||
this.__DOM_IMPL__.dispatchEvent(selectionChangeEvent);
|
||||
}
|
||||
},
|
||||
|
||||
_fireEvent: function ic_fireEvent(eventName, aDetail) {
|
||||
let detail = {
|
||||
detail: aDetail
|
||||
};
|
||||
|
||||
let event = new this._window.CustomEvent(eventName,
|
||||
Cu.cloneInto(detail, this._window));
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
},
|
||||
|
||||
// tag name of the input field
|
||||
get type() {
|
||||
return this._context.type;
|
||||
@ -910,15 +950,16 @@ MozInputContext.prototype = {
|
||||
},
|
||||
|
||||
getText: function ic_getText(offset, length) {
|
||||
let self = this;
|
||||
return this._sendPromise(function(resolverId) {
|
||||
cpmmSendAsyncMessageWithKbID(self, 'Keyboard:GetText', {
|
||||
contextId: self._contextId,
|
||||
requestId: resolverId,
|
||||
offset: offset,
|
||||
length: length
|
||||
});
|
||||
});
|
||||
let text;
|
||||
if (offset && length) {
|
||||
text = this._context.text.substr(offset, length);
|
||||
} else if (offset) {
|
||||
text = this._context.text.substr(offset);
|
||||
} else {
|
||||
text = this._context.text;
|
||||
}
|
||||
|
||||
return this._window.Promise.resolve(text);
|
||||
},
|
||||
|
||||
get selectionStart() {
|
||||
@ -929,12 +970,23 @@ MozInputContext.prototype = {
|
||||
return this._context.selectionEnd;
|
||||
},
|
||||
|
||||
get text() {
|
||||
return this._context.text;
|
||||
},
|
||||
|
||||
get textBeforeCursor() {
|
||||
return this._context.textBeforeCursor;
|
||||
let text = this._context.text;
|
||||
let start = this._context.selectionStart;
|
||||
return (start < 100) ?
|
||||
text.substr(0, start) :
|
||||
text.substr(start - 100, 100);
|
||||
},
|
||||
|
||||
get textAfterCursor() {
|
||||
return this._context.textAfterCursor;
|
||||
let text = this._context.text;
|
||||
let start = this._context.selectionStart;
|
||||
let end = this._context.selectionEnd;
|
||||
return text.substr(start, end - start + 100);
|
||||
},
|
||||
|
||||
setSelectionRange: function ic_setSelectionRange(start, length) {
|
||||
|
@ -423,7 +423,6 @@ var FormAssistant = {
|
||||
addMessageListener("Forms:Select:Blur", this);
|
||||
addMessageListener("Forms:SetSelectionRange", this);
|
||||
addMessageListener("Forms:ReplaceSurroundingText", this);
|
||||
addMessageListener("Forms:GetText", this);
|
||||
addMessageListener("Forms:Input:SendKey", this);
|
||||
addMessageListener("Forms:GetContext", this);
|
||||
addMessageListener("Forms:SetComposition", this);
|
||||
@ -438,8 +437,8 @@ var FormAssistant = {
|
||||
isHandlingFocus: false,
|
||||
selectionStart: -1,
|
||||
selectionEnd: -1,
|
||||
textBeforeCursor: "",
|
||||
textAfterCursor: "",
|
||||
text: "",
|
||||
|
||||
scrollIntoViewTimeout: null,
|
||||
_focusedElement: null,
|
||||
_focusCounter: 0, // up one for every time we focus a new element
|
||||
@ -524,8 +523,6 @@ var FormAssistant = {
|
||||
});
|
||||
if (del && element === self.focusedElement) {
|
||||
self.unhandleFocus();
|
||||
self.selectionStart = -1;
|
||||
self.selectionEnd = -1;
|
||||
}
|
||||
});
|
||||
|
||||
@ -626,8 +623,6 @@ var FormAssistant = {
|
||||
case "blur":
|
||||
if (this.focusedElement) {
|
||||
this.unhandleFocus();
|
||||
this.selectionStart = -1;
|
||||
this.selectionEnd = -1;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -696,14 +691,6 @@ var FormAssistant = {
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
switch (msg.name) {
|
||||
case "Forms:GetText":
|
||||
sendAsyncMessage("Forms:GetText:Result:Error", {
|
||||
requestId: json.requestId,
|
||||
error: "No focused element"
|
||||
});
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -935,24 +922,6 @@ var FormAssistant = {
|
||||
break;
|
||||
}
|
||||
|
||||
case "Forms:GetText": {
|
||||
let value = isContentEditable(target) ? getContentEditableText(target)
|
||||
: target.value;
|
||||
|
||||
if (json.offset && json.length) {
|
||||
value = value.substr(json.offset, json.length);
|
||||
}
|
||||
else if (json.offset) {
|
||||
value = value.substr(json.offset);
|
||||
}
|
||||
|
||||
sendAsyncMessage("Forms:GetText:Result:OK", {
|
||||
requestId: json.requestId,
|
||||
text: value
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case "Forms:GetContext": {
|
||||
let obj = getJSON(target, this._focusCounter);
|
||||
sendAsyncMessage("Forms:GetContext:Result:OK", obj);
|
||||
@ -997,6 +966,9 @@ var FormAssistant = {
|
||||
unhandleFocus: function fa_unhandleFocus() {
|
||||
this.setFocusedElement(null);
|
||||
this.isHandlingFocus = false;
|
||||
this.selectionStart = -1;
|
||||
this.selectionEnd = -1;
|
||||
this.text = "";
|
||||
sendAsyncMessage("Forms:Blur", {});
|
||||
},
|
||||
|
||||
@ -1036,23 +1008,18 @@ var FormAssistant = {
|
||||
let text = isContentEditable(element) ? getContentEditableText(element)
|
||||
: element.value;
|
||||
|
||||
let textAround = getTextAroundCursor(text, range);
|
||||
|
||||
let changed = this.selectionStart !== range[0] ||
|
||||
this.selectionEnd !== range[1] ||
|
||||
this.textBeforeCursor !== textAround.before ||
|
||||
this.textAfterCursor !== textAround.after;
|
||||
this.text !== text;
|
||||
|
||||
this.selectionStart = range[0];
|
||||
this.selectionEnd = range[1];
|
||||
this.textBeforeCursor = textAround.before;
|
||||
this.textAfterCursor = textAround.after;
|
||||
this.text = text;
|
||||
|
||||
return {
|
||||
selectionStart: range[0],
|
||||
selectionEnd: range[1],
|
||||
textBeforeCursor: textAround.before,
|
||||
textAfterCursor: textAround.after,
|
||||
text: text,
|
||||
changed: changed
|
||||
};
|
||||
},
|
||||
@ -1157,7 +1124,6 @@ function getJSON(element, focusCounter) {
|
||||
}
|
||||
|
||||
let range = getSelectionRange(element);
|
||||
let textAround = getTextAroundCursor(value, range);
|
||||
|
||||
return {
|
||||
"contextId": focusCounter,
|
||||
@ -1172,24 +1138,7 @@ function getJSON(element, focusCounter) {
|
||||
"selectionEnd": range[1],
|
||||
"max": max,
|
||||
"min": min,
|
||||
"lang": element.lang || "",
|
||||
"textBeforeCursor": textAround.before,
|
||||
"textAfterCursor": textAround.after
|
||||
};
|
||||
}
|
||||
|
||||
function getTextAroundCursor(value, range) {
|
||||
let textBeforeCursor = range[0] < 100 ?
|
||||
value.substr(0, range[0]) :
|
||||
value.substr(range[0] - 100, 100);
|
||||
|
||||
let textAfterCursor = range[1] + 100 > value.length ?
|
||||
value.substr(range[0], value.length) :
|
||||
value.substr(range[0], range[1] - range[0] + 100);
|
||||
|
||||
return {
|
||||
before: textBeforeCursor,
|
||||
after: textAfterCursor
|
||||
"lang": element.lang || ""
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ function runTest() {
|
||||
is(gContext.inputType, 'text', 'The inputType should match.');
|
||||
is(gContext.inputMode, 'verbatim', 'The inputMode should match.');
|
||||
is(gContext.lang, 'zh', 'The language should match.');
|
||||
is(gContext.text, 'Yuan', 'Should get the text.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Yuan',
|
||||
'Should get the text around the cursor.');
|
||||
|
||||
@ -65,6 +66,7 @@ function test_setSelectionRange() {
|
||||
test_sendKey();
|
||||
}, function(e) {
|
||||
ok(false, 'setSelectionRange failed:' + e.name);
|
||||
console.error(e);
|
||||
inputmethod_cleanup();
|
||||
});
|
||||
}
|
||||
@ -72,6 +74,8 @@ function test_setSelectionRange() {
|
||||
function test_sendKey() {
|
||||
// Add '-' to current cursor posistion and move the cursor position to 3.
|
||||
gContext.sendKey(0, '-'.charCodeAt(0), 0).then(function() {
|
||||
is(gContext.text, 'Yu-an',
|
||||
'sendKey should changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Yu-an',
|
||||
'sendKey should changed the input field correctly.');
|
||||
test_deleteSurroundingText();
|
||||
@ -86,6 +90,8 @@ function test_deleteSurroundingText() {
|
||||
// position back to 2.
|
||||
gContext.deleteSurroundingText(-1, 1).then(function() {
|
||||
ok(true, 'deleteSurroundingText finished');
|
||||
is(gContext.text, 'Yuan',
|
||||
'deleteSurroundingText should changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Yuan',
|
||||
'deleteSurroundingText should changed the input field correctly.');
|
||||
test_replaceSurroundingText();
|
||||
@ -99,6 +105,8 @@ function test_replaceSurroundingText() {
|
||||
// Replace 'Yuan' with 'Xulei'.
|
||||
gContext.replaceSurroundingText('Xulei', -2, 4).then(function() {
|
||||
ok(true, 'replaceSurroundingText finished');
|
||||
is(gContext.text, 'Xulei',
|
||||
'replaceSurroundingText changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Xulei',
|
||||
'replaceSurroundingText changed the input field correctly.');
|
||||
test_setComposition();
|
||||
@ -120,6 +128,8 @@ function test_setComposition() {
|
||||
|
||||
function test_endComposition() {
|
||||
gContext.endComposition('2013').then(function() {
|
||||
is(gContext.text, 'Xulei2013',
|
||||
'endComposition changed the input field correctly.');
|
||||
is(gContext.textBeforeCursor + gContext.textAfterCursor, 'Xulei2013',
|
||||
'endComposition changed the input field correctly.');
|
||||
test_onSelectionChange();
|
||||
@ -181,8 +191,9 @@ function test_onSurroundingTextChange() {
|
||||
|
||||
gContext.onsurroundingtextchange = function(evt) {
|
||||
ok(true, 'onsurroundingtextchange fired');
|
||||
is(evt.detail.beforeString, 'Xulei2013jj');
|
||||
is(evt.detail.afterString, '');
|
||||
is(evt.detail.text, 'Xulei2013jj');
|
||||
is(evt.detail.textBeforeCursor, 'Xulei2013jj');
|
||||
is(evt.detail.textAfterCursor, '');
|
||||
ok(evt.detail.ownAction);
|
||||
};
|
||||
|
||||
|
@ -245,7 +245,7 @@ interface MozInputContextFocusEventDetail {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Current value of the input/select element.
|
||||
* Current value of the input.
|
||||
*/
|
||||
readonly attribute DOMString? value;
|
||||
/**
|
||||
@ -270,7 +270,7 @@ dictionary MozInputContextChoicesInfo {
|
||||
};
|
||||
|
||||
/**
|
||||
* Content the header (<optgroup>) or an option (<option>).
|
||||
* Content of the option header (<optgroup>) or an option (<option>).
|
||||
*/
|
||||
dictionary MozInputMethodChoiceDict {
|
||||
boolean group;
|
||||
@ -357,8 +357,16 @@ interface MozInputContext: EventTarget {
|
||||
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;
|
||||
@ -380,9 +388,7 @@ interface MozInputContext: EventTarget {
|
||||
/* 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.
|
||||
*
|
||||
* A dict is provided in the detail property of the event containing the new values, and
|
||||
* an "ownAction" property to denote the event is the result of our own mutation to
|
||||
* the input field.
|
||||
* evt.detail is defined by MozInputContextSelectionChangeEventDetail.
|
||||
*/
|
||||
attribute EventHandler onselectionchange;
|
||||
|
||||
@ -411,9 +417,7 @@ interface MozInputContext: EventTarget {
|
||||
* editing or cursor movement. If the cursor has been moved, but the text around has not
|
||||
* changed, the IME won't get notification.
|
||||
*
|
||||
* A dict is provided in the detail property of the event containing the new values, and
|
||||
* an "ownAction" property to denote the event is the result of our own mutation to
|
||||
* the input field.
|
||||
* evt.detail is defined by MozInputContextSurroundingTextChangeEventDetail.
|
||||
*/
|
||||
attribute EventHandler onsurroundingtextchange;
|
||||
|
||||
@ -523,6 +527,62 @@ interface MozInputContext: EventTarget {
|
||||
optional MozInputMethodKeyboardEventDict dict);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detail of the selectionchange event.
|
||||
*/
|
||||
[JSImplementation="@mozilla.org/b2g-imm-selectionchange;1",
|
||||
Pref="dom.mozInputMethod.enabled",
|
||||
CheckAnyPermissions="input"]
|
||||
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",
|
||||
CheckAnyPermissions="input"]
|
||||
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",
|
||||
|
Loading…
Reference in New Issue
Block a user