Bug 1336426 - Query selected text before calling word breaker. r=masayuki,m_kato

When triggering dictionary lookup in native macOS apps, the currently selected text is used if the cursor falls within the selection range. Since Bug 1275486 and Bug 425915 are yet to be implemented, this patch could at least give the user ability to manually mark their query first.

Differential Revision: https://phabricator.services.mozilla.com/D57096

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Poren Chiang 2020-03-10 21:24:13 +00:00
parent 6c6fc9f3dc
commit 0ab9bb5418

View File

@ -957,42 +957,57 @@ nsLookUpDictionaryCommand::DoCommandParams(const char* aCommandName,
return NS_ERROR_FAILURE;
}
WidgetQueryContentEvent textContent(true, eQueryTextContent, widget);
// OSX 10.7 queries 50 characters before/after current point. So we fetch
// same length.
WidgetQueryContentEvent selection(true, eQuerySelectedText, widget);
handler.OnQuerySelectedText(&selection);
bool useSelection = false;
uint32_t offset = charAt.mReply.mOffset;
if (offset > 50) {
offset -= 50;
} else {
offset = 0;
}
textContent.InitForQueryTextContent(offset, 100);
handler.OnQueryTextContent(&textContent);
if (NS_WARN_IF(!textContent.mSucceeded ||
textContent.mReply.mString.IsEmpty())) {
return NS_ERROR_FAILURE;
uint32_t begin, length;
// macOS prioritizes user selected text if the current point falls within the
// selection range. So we check the selection first.
if (selection.mSucceeded) {
begin = selection.mReply.mOffset;
length = selection.mReply.mString.Length();
useSelection = (offset >= begin && offset < (begin + length));
}
// XXX nsIWordBreaker doesn't use contextual breaker.
// If OS provides it, widget should use it if contextual breaker is needed.
RefPtr<mozilla::intl::WordBreaker> wordBreaker =
nsContentUtils::WordBreaker();
if (NS_WARN_IF(!wordBreaker)) {
return NS_ERROR_FAILURE;
}
if (!useSelection) {
WidgetQueryContentEvent textContent(true, eQueryTextContent, widget);
// OSX 10.7 queries 50 characters before/after current point. So we fetch
// same length.
if (offset > 50) {
offset -= 50;
} else {
offset = 0;
}
textContent.InitForQueryTextContent(offset, 100);
handler.OnQueryTextContent(&textContent);
if (NS_WARN_IF(!textContent.mSucceeded ||
textContent.mReply.mString.IsEmpty())) {
return NS_ERROR_FAILURE;
}
mozilla::intl::WordRange range = wordBreaker->FindWord(
textContent.mReply.mString.get(), textContent.mReply.mString.Length(),
charAt.mReply.mOffset - offset);
if (range.mEnd == range.mBegin) {
return NS_ERROR_FAILURE;
// XXX nsIWordBreaker doesn't use contextual breaker.
// If OS provides it, widget should use it if contextual breaker is needed.
RefPtr<mozilla::intl::WordBreaker> wordBreaker =
nsContentUtils::WordBreaker();
if (NS_WARN_IF(!wordBreaker)) {
return NS_ERROR_FAILURE;
}
mozilla::intl::WordRange range = wordBreaker->FindWord(
textContent.mReply.mString.get(), textContent.mReply.mString.Length(),
charAt.mReply.mOffset - offset);
if (range.mEnd == range.mBegin) {
return NS_ERROR_FAILURE;
}
begin = range.mBegin + offset;
length = range.mEnd - range.mBegin;
}
range.mBegin += offset;
range.mEnd += offset;
WidgetQueryContentEvent lookUpContent(true, eQueryTextContent, widget);
lookUpContent.InitForQueryTextContent(range.mBegin,
range.mEnd - range.mBegin);
lookUpContent.InitForQueryTextContent(begin, length);
lookUpContent.RequestFontRanges();
handler.OnQueryTextContent(&lookUpContent);
if (NS_WARN_IF(!lookUpContent.mSucceeded ||
@ -1001,7 +1016,7 @@ nsLookUpDictionaryCommand::DoCommandParams(const char* aCommandName,
}
WidgetQueryContentEvent charRect(true, eQueryTextRect, widget);
charRect.InitForQueryTextRect(range.mBegin, range.mEnd - range.mBegin);
charRect.InitForQueryTextRect(begin, length);
handler.OnQueryTextRect(&charRect);
if (NS_WARN_IF(!charRect.mSucceeded)) {
return NS_ERROR_FAILURE;