Bug 998188 part.4 nsIDOMWindowUtils.sendQueryContentEvent() and .sendSelectionSetEvent() should take additional flags with its argument for making callers selectable native line break mode or XP line break mode r=smaug, sr=jst

This commit is contained in:
Masayuki Nakano 2014-04-26 08:52:13 +09:00
Родитель 0b61f81cc1
Коммит 97396c150e
4 изменённых файлов: 278 добавлений и 15 удалений

Просмотреть файл

@ -2203,6 +2203,7 @@ NS_IMETHODIMP
nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
uint32_t aOffset, uint32_t aLength,
int32_t aX, int32_t aY,
uint32_t aAdditionalFlags,
nsIQueryContentEventResult **aResult)
{
*aResult = nullptr;
@ -2241,9 +2242,13 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
nsCOMPtr<nsIWidget> targetWidget = widget;
LayoutDeviceIntPoint pt(aX, aY);
bool useNativeLineBreak =
!(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
if (aType == QUERY_CHARACTER_AT_POINT) {
// Looking for the widget at the point.
WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
dummyEvent.mUseNativeLineBreak = useNativeLineBreak;
InitEvent(dummyEvent, &pt);
nsIFrame* popupFrame =
nsLayoutUtils::GetPopupFrameForEventCoordinates(presContext->GetRootPresContext(), &dummyEvent);
@ -2273,13 +2278,16 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
switch (aType) {
case NS_QUERY_TEXT_CONTENT:
queryEvent.InitForQueryTextContent(aOffset, aLength);
queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
break;
case NS_QUERY_CARET_RECT:
queryEvent.InitForQueryCaretRect(aOffset);
queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
break;
case NS_QUERY_TEXT_RECT:
queryEvent.InitForQueryTextRect(aOffset, aLength);
queryEvent.InitForQueryTextRect(aOffset, aLength, useNativeLineBreak);
break;
default:
queryEvent.mUseNativeLineBreak = useNativeLineBreak;
break;
}
@ -2297,7 +2305,7 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
NS_IMETHODIMP
nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
uint32_t aLength,
bool aReverse,
uint32_t aAdditionalFlags,
bool *aResult)
{
*aResult = false;
@ -2317,7 +2325,9 @@ nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
selectionEvent.mOffset = aOffset;
selectionEvent.mLength = aLength;
selectionEvent.mReversed = aReverse;
selectionEvent.mReversed = (aAdditionalFlags & SELECTION_SET_FLAG_REVERSE);
selectionEvent.mUseNativeLineBreak =
!(aAdditionalFlags & SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
nsEventStatus status;
nsresult rv = widget->DispatchEvent(&selectionEvent, status);

Просмотреть файл

@ -8,3 +8,4 @@ support-files =
[test_url.xul]
[test_console.xul]
[test_navigator_resolve_identity_xrays.xul]
[test_sendQueryContentAndSelectionSetEvent.html]

Просмотреть файл

@ -0,0 +1,224 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for nsIDOMWindowUtils.sendQueryContentEvent() and .sendSelectionSetEvent()</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<div id="editor" contenteditable>abc<br>def</div>
<pre id="test">
<script type="application/javascript">
var editor = document.getElementById("editor");
SimpleTest.waitForExplicitFinish();
const kIsWin = navigator.platform.indexOf("Win") == 0;
const kIsMac = navigator.platform.indexOf("Mac") == 0;
const kLineBreak = kIsWin ? "\r\n" : kIsMac ? "\r" : "\n";
var gUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
function escape(aStr)
{
var result = aStr.replace("\n", "\\n");
return result.replace("\r", "\\r");
}
function runTests()
{
editor.focus();
// NOTE: For compatibility, calling without flags should work as with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK.
// QueryTextContent
var expectedStr = escape(("abc" + kLineBreak + "def").substr(2, 4));
var result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_CONTENT, 2, 4, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
is(escape(result.text), expectedStr,
"sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) got unexpected string");
result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_CONTENT, 2, 4, 0, 0);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_TEXT_CONTENT) should succeed");
is(escape(result.text), expectedStr,
"sendQueryContentEvent(QUERY_TEXT_CONTENT) should return same string as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
expectedStr = escape(("abc\ndef").substr(2, 4));
result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_CONTENT, 2, 4, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed");
is(escape(result.text), expectedStr,
"sendQueryContentEvent(QUERY_TEXT_CONTENT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) got unexpected string");
// QueryCaretRect
window.getSelection().collapse(editor.firstChild, 0);
var caretNative = gUtils.sendQueryContentEvent(gUtils.QUERY_CARET_RECT, 6, 0, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK);
ok(caretNative.succeeded,
"sendQueryContentEvent(QUERY_CARET_RECT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
var caretXP = gUtils.sendQueryContentEvent(gUtils.QUERY_CARET_RECT, 6 - kLineBreak.length + 1, 0, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
ok(caretXP.succeeded,
"sendQueryContentEvent(QUERY_CARET_RECT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed");
is(caretXP.top, caretNative.top,
"The caret top should be same");
is(caretXP.left, caretNative.left,
"The caret left should be same");
result = gUtils.sendQueryContentEvent(gUtils.QUERY_CARET_RECT, 6, 0, 0, 0);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_CARET_RECT) should succeed");
is(result.top, caretNative.top,
"sendQueryContentEvent(QUERY_CARET_RECT) should return same top as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.left, caretNative.left,
"sendQueryContentEvent(QUERY_CARET_RECT) should return same left as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
// QueryTextRect
var textRectNative = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 6, 1, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK);
ok(textRectNative.succeeded,
"sendQueryContentEvent(QUERY_TEXT_RECT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
var textRectXP = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 6 - kLineBreak.length + 1, 1, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
ok(textRectXP.succeeded,
"sendQueryContentEvent(QUERY_TEXT_RECT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed");
is(textRectXP.top, textRectNative.top,
"The text top should be same");
is(textRectXP.left, textRectNative.left,
"The text left should be same");
is(textRectXP.height, textRectNative.height,
"The text height should be same");
is(textRectXP.width, textRectNative.width,
"The text width should be same");
result = gUtils.sendQueryContentEvent(gUtils.QUERY_TEXT_RECT, 6, 1, 0, 0);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_TEXT_RECT) should succeed");
is(result.top, textRectNative.top,
"sendQueryContentEvent(QUERY_TEXT_RECT) should return same top as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.left, textRectNative.left,
"sendQueryContentEvent(QUERY_TEXT_RECT) should return same left as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.height, textRectNative.height,
"sendQueryContentEvent(QUERY_TEXT_RECT) should return same height as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.width, textRectNative.width,
"sendQueryContentEvent(QUERY_TEXT_RECT) should return same width as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
// QueryCharacterAtOffset
result = gUtils.sendQueryContentEvent(gUtils.QUERY_CHARACTER_AT_POINT, 0, 0, textRectNative.left + 1, textRectNative.top + 1,
gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_CHARACTER_AT_POINT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
is(result.top, textRectNative.top,
"The character top is wrong");
is(result.left, textRectNative.left,
"The character left is wrong");
is(result.height, textRectNative.height,
"The character height is wrong");
is(result.width, textRectNative.width,
"The character width is wrong");
is(result.offset, 6,
"The character offset is wrong");
result = gUtils.sendQueryContentEvent(gUtils.QUERY_CHARACTER_AT_POINT, 0, 0, textRectNative.left + 1, textRectNative.top + 1);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_CHARACTER_AT_POINT) should succeed");
is(result.top, textRectNative.top,
"The character top should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.left, textRectNative.left,
"The character left should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.height, textRectNative.height,
"The character height should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.width, textRectNative.width,
"The character width should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
is(result.offset, 6,
"The character offset should be same as calling with QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK");
result = gUtils.sendQueryContentEvent(gUtils.QUERY_CHARACTER_AT_POINT, 0, 0, textRectXP.left + 1, textRectXP.top + 1,
gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_CHARACTER_AT_POINT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed");
is(result.top, textRectXP.top,
"The character top is wrong");
is(result.left, textRectXP.left,
"The character left is wrong");
is(result.height, textRectXP.height,
"The character height is wrong");
is(result.width, textRectXP.width,
"The character width is wrong");
is(result.offset, 6 - kLineBreak.length + 1,
"The character offset is wrong");
// SelectionSet and QuerySelectedText
var selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK);
ok(selectionSet,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
expectedStr = escape(("abc" + kLineBreak + "def").substr(0, 6));
result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
ok(!result.reversed,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK) should set non-reversed selection");
is(escape(result.text), expectedStr,
"sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) got unexpected string");
selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_XP_LINE_BREAK);
ok(selectionSet,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK) should succeed");
expectedStr = escape(("abc\ndef").substr(0, 6));
result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed");
ok(!result.reversed,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK) should set non-reversed selection");
is(escape(result.text), expectedStr,
"sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) got unexpected string");
var selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK | gUtils.SELECTION_SET_FLAG_REVERSE);
ok(selectionSet,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK) should succeed");
ok(result.reversed,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK | SELECTION_SET_FLAG_REVERSE) should set reversed selection");
selectionSet = gUtils.sendSelectionSetEvent(0, 6, gUtils.SELECTION_SET_FLAG_USE_XP_LINE_BREAK | gUtils.SELECTION_SET_FLAG_REVERSE);
ok(selectionSet,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK | SELECTION_SET_FLAG_REVERSE) should succeed");
result = gUtils.sendQueryContentEvent(gUtils.QUERY_SELECTED_TEXT, 0, 0, 0, 0,
gUtils.QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
ok(result.succeeded,
"sendQueryContentEvent(QUERY_SELECTED_TEXT, QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK) should succeed");
ok(result.reversed,
"sendSelectionSetEvent(0, 6, SELECTION_SET_FLAG_USE_XP_LINE_BREAK | SELECTION_SET_FLAG_REVERSE) should set reversed selection");
SimpleTest.finish();
}
SimpleTest.waitForFocus(runTests);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -43,7 +43,7 @@ interface nsIRunnable;
interface nsICompositionStringSynthesizer;
interface nsITranslationNodeList;
[scriptable, uuid(926c7450-ab88-11e3-a5e2-0800200c9a66)]
[scriptable, uuid(9376bafe-e7b1-48e7-87e2-1e64a7b5d54d)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -1020,18 +1020,32 @@ interface nsIDOMWindowUtils : nsISupports {
*/
nsICompositionStringSynthesizer createCompositionStringSynthesizer();
/**
* If sendQueryContentEvent()'s aAdditionalFlags argument is
* QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK, plain text generated from content
* is created with "\n".
* Otherwise, platform dependent. E.g., on Windows, "\r\n" is used.
* aOffset and aLength are offset and length in/of the plain text content.
* This flag also affects the result values such as offset, length and string.
*/
const unsigned long QUERY_CONTENT_FLAG_USE_NATIVE_LINE_BREAK = 0x0000;
const unsigned long QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK = 0x0001;
/**
* Synthesize a query content event. Note that the result value returned here
* is in LayoutDevice pixels rather than CSS pixels.
*
* @param aType One of the following const values. And see also each comment
* for the other parameters and the result.
* @param aAdditionalFlags See the description of QUERY_CONTENT_FLAG_*.
*/
nsIQueryContentEventResult sendQueryContentEvent(in unsigned long aType,
in unsigned long aOffset,
in unsigned long aLength,
in long aX,
in long aY);
nsIQueryContentEventResult sendQueryContentEvent(
in unsigned long aType,
in unsigned long aOffset,
in unsigned long aLength,
in long aX,
in long aY,
[optional] in unsigned long aAdditionalFlags);
// NOTE: following values are same as NS_QUERY_* in BasicEvents.h
@ -1143,6 +1157,22 @@ interface nsIDOMWindowUtils : nsISupports {
*/
void exitFullscreen();
/**
* If sendQueryContentEvent()'s aAdditionalFlags argument is
* SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK, aOffset and aLength are offset
* and length in/of plain text generated from content is created with "\n".
* Otherwise, platform dependent. E.g., on Windows, "\r\n" is used.
*/
const unsigned long SELECTION_SET_FLAG_USE_NATIVE_LINE_BREAK = 0x0000;
const unsigned long SELECTION_SET_FLAG_USE_XP_LINE_BREAK = 0x0001;
/**
* If SELECTION_SET_FLAG_REVERSE is set, the selection is set from
* |aOffset + aLength| to |aOffset|. Otherwise, it's set from |aOffset| to
* |aOffset + aLength|.
*/
const unsigned long SELECTION_SET_FLAG_REVERSE = 0x0002;
/**
* Synthesize a selection set event to the window.
*
@ -1151,14 +1181,12 @@ interface nsIDOMWindowUtils : nsISupports {
* @param aOffset The caret offset of the selection start.
* @param aLength The length of the selection. If this is too long, the
* extra length is ignored.
* @param aReverse If true, the selection set from |aOffset + aLength| to
* |aOffset|. Otherwise, set from |aOffset| to
* |aOffset + aLength|.
* @param aAdditionalFlags See the description of SELECTION_SET_FLAG_*.
* @return True, if succeeded. Otherwise, false.
*/
boolean sendSelectionSetEvent(in unsigned long aOffset,
in unsigned long aLength,
in boolean aReverse);
[optional] in unsigned long aAdditionalFlags);
/* Selection behaviors - mirror nsIFrame's nsSelectionAmount constants */
const unsigned long SELECT_CHARACTER = 0;