import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 895274 part.145 Rename NS_SELECTION_SET to eSetSelection r=smaug (5a576f3fc7)
- Bug 895274 part.146 Rename NS_MOUSE_SCROLL_START to eLegacyMouseScrollEventFirst r=smaug (a03038ca81)
- Bug 895274 part.147 Rename NS_MOUSE_SCROLL to eLegacyMouseLineOrPageScroll r=smaug (a16fa072ad)
- Bug 895274 part.148 Rename NS_MOUSE_PIXEL_SCROLL to eLegacyMousePixelScroll r=smaug (85810aa54b)
- Bug 895274 part.150 Rename NS_QUERY_CONTENT_EVENT_START to eQueryContentEventFirst r=smaug (36b4be4c20)
- Bug 895274 part.151 Rename NS_QUERY_SELECTION_AS_TRANSFERABLE to eQuerySelectionAsTransferable r=smaug (7b50da594a)
- Bug 895274 part.152 Rename NS_QUERY_SELECTED_TEXT to eQuerySelectedText r=smaug (3dbd79293f)
- Bug 1199224 TSFTextStore should clear mLockedContent unless it needs to wait the content to be modified asynchronously r=emk (70aed5d4c5)
- Bug 895274 part.153 Rename NS_QUERY_TEXT_CONTENT to eQueryTextContent r=smaug (9d3a8acf96)
- Bug 299603 part.1 IMContextWrapper should have a method to initialize a TextRange r=m_kato (cf04d9b788)
- Bug 299603 part.2 IMContextWrapper::SetTextRange() should initialize the range offsets and fail if the range is collapsed r=m_kato (4c64f3f7e7)
- Bug 299603 part.3 IMContextWrapper::SetTextRange() shold set the style of the range which is specified by the IME r=m_kato (02b09d3df4)
- Bug 1057921 - Don't propagate text decorations through outer <svg> elements. r=dholbert (e1e489eb2b)
- Bug 1186721 - Suppress line break due to soft hyphen inside ruby. r=jfkthame (15bdd20955)
- Bug 1175789 Draw underline as overline when it's in vertical writing mode and the language is Japanese or Korean r=dbaron (ffdb9f3e5b)
- Bug 834830 - Add nsISelectionController.SELECTION_URLSTRIKEOUT to enable striking out parts of the URL in the URL bar r=roc (73d2871c77)
- Bug 1155261 - Fix computation of glyph extents and text-frame visual overflow for vertical text frames. r=smontagu (5e94c117c3)
- Bug 1140486 patch 1 - Pass block frame instead of block reflow state to nsTextFrame::RecomputeOverflow. r=jfkthame (2ecd788bd1)
- Bug 1140486 patch 2 - Make nsTextFrame::UpdateOverflow include the visual overflow from the text metrics by calling existing RecomputeOverflow. r=jfkthame (3452b7edfd)
- Bug 299603 part.4 Some global methods in nsTextFrame.cpp should be members of nsTextFrame class r=roc (9ca79dab6f)
- Bug 299603 part.5 nsTextFrame should use system foreground or background color when painting IME selections if whose style defines only one of foreground color or background color r=roc (c4843a6c98)
- Bug 299603 part.6 Guess the meaning of each clause in the composition string with caret position r=m_kato (364dfcc3b2)
- Bug 299603 part.7 IMContextWrapper::CreateTextRange() should convert the caret offset from offset in characters to offset in UTF-16 r=m_kato (d67b116232)
- Bug 895274 part.154 Rename NS_QUERY_CARET_RECT to eQueryCaretRect r=smaug (da09b897d9)
- Bug 1153634 - Weaken the assertion condition to make it match the condition before. r=roc (02ce185f35)
- Bug 299603 part.8 Rename aLastDispatchedData with aCompositionString in IMContextWrapper::CreateTextRangeArray() r=m_kato (998af878dc)
This commit is contained in:
2022-05-03 11:34:54 +08:00
parent 3b6bacfa0e
commit f96be1a4d9
50 changed files with 1127 additions and 458 deletions
+6 -6
View File
@@ -1934,13 +1934,13 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
EventMessage message;
switch (aType) {
case QUERY_SELECTED_TEXT:
message = NS_QUERY_SELECTED_TEXT;
message = eQuerySelectedText;
break;
case QUERY_TEXT_CONTENT:
message = NS_QUERY_TEXT_CONTENT;
message = eQueryTextContent;
break;
case QUERY_CARET_RECT:
message = NS_QUERY_CARET_RECT;
message = eQueryCaretRect;
break;
case QUERY_TEXT_RECT:
message = NS_QUERY_TEXT_RECT;
@@ -1992,10 +1992,10 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
InitEvent(queryEvent, &pt);
switch (message) {
case NS_QUERY_TEXT_CONTENT:
case eQueryTextContent:
queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
break;
case NS_QUERY_CARET_RECT:
case eQueryCaretRect:
queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
break;
case NS_QUERY_TEXT_RECT:
@@ -2033,7 +2033,7 @@ nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
return NS_ERROR_FAILURE;
}
WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
WidgetSelectionEvent selectionEvent(true, eSetSelection, widget);
InitEvent(selectionEvent);
selectionEvent.mOffset = aOffset;
+3 -2
View File
@@ -16,7 +16,7 @@ interface nsIDOMNode;
interface nsISelection;
interface nsISelectionDisplay;
[scriptable, uuid(82c3a9df-9bd6-4da2-b561-d85a9eec5caa)]
[scriptable, uuid(e5238312-2f50-4ec1-8e23-6337f3a67727)]
interface nsISelectionController : nsISelectionDisplay
{
const short SELECTION_NONE=0;
@@ -29,7 +29,8 @@ interface nsISelectionController : nsISelectionDisplay
const short SELECTION_ACCESSIBILITY=64; // For accessibility API usage
const short SELECTION_FIND=128;
const short SELECTION_URLSECONDARY=256;
const short NUM_SELECTIONTYPES=10;
const short SELECTION_URLSTRIKEOUT=512;
const short NUM_SELECTIONTYPES=11;
const short SELECTION_ANCHOR_REGION = 0;
const short SELECTION_FOCUS_REGION = 1;
+21 -21
View File
@@ -19,8 +19,9 @@ NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsQueryContentEventResult)
NS_IMPL_RELEASE(nsQueryContentEventResult)
nsQueryContentEventResult::nsQueryContentEventResult() :
mEventID(0), mSucceeded(false)
nsQueryContentEventResult::nsQueryContentEventResult()
: mEventMessage(eVoidEvent)
, mSucceeded(false)
{
}
@@ -54,20 +55,19 @@ nsQueryContentEventResult::GetTentativeCaretOffset(uint32_t* aOffset)
return NS_OK;
}
static bool IsRectEnabled(uint32_t aEventID)
static bool IsRectEnabled(EventMessage aEventMessage)
{
return aEventID == NS_QUERY_CARET_RECT ||
aEventID == NS_QUERY_TEXT_RECT ||
aEventID == NS_QUERY_EDITOR_RECT ||
aEventID == NS_QUERY_CHARACTER_AT_POINT;
return aEventMessage == eQueryCaretRect ||
aEventMessage == NS_QUERY_TEXT_RECT ||
aEventMessage == NS_QUERY_EDITOR_RECT ||
aEventMessage == NS_QUERY_CHARACTER_AT_POINT;
}
NS_IMETHODIMP
nsQueryContentEventResult::GetReversed(bool *aReversed)
{
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(mEventID == NS_QUERY_SELECTED_TEXT,
NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText, NS_ERROR_NOT_AVAILABLE);
*aReversed = mReversed;
return NS_OK;
}
@@ -76,7 +76,7 @@ NS_IMETHODIMP
nsQueryContentEventResult::GetLeft(int32_t *aLeft)
{
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
NS_ERROR_NOT_AVAILABLE);
*aLeft = mRect.x;
return NS_OK;
@@ -86,7 +86,7 @@ NS_IMETHODIMP
nsQueryContentEventResult::GetWidth(int32_t *aWidth)
{
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
NS_ERROR_NOT_AVAILABLE);
*aWidth = mRect.width;
return NS_OK;
@@ -96,7 +96,7 @@ NS_IMETHODIMP
nsQueryContentEventResult::GetTop(int32_t *aTop)
{
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
NS_ERROR_NOT_AVAILABLE);
*aTop = mRect.y;
return NS_OK;
@@ -106,7 +106,7 @@ NS_IMETHODIMP
nsQueryContentEventResult::GetHeight(int32_t *aHeight)
{
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
NS_ERROR_NOT_AVAILABLE);
*aHeight = mRect.height;
return NS_OK;
@@ -116,8 +116,8 @@ NS_IMETHODIMP
nsQueryContentEventResult::GetText(nsAString &aText)
{
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(mEventID == NS_QUERY_SELECTED_TEXT ||
mEventID == NS_QUERY_TEXT_CONTENT,
NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText ||
mEventMessage == eQueryTextContent,
NS_ERROR_NOT_AVAILABLE);
aText = mString;
return NS_OK;
@@ -126,7 +126,7 @@ nsQueryContentEventResult::GetText(nsAString &aText)
NS_IMETHODIMP
nsQueryContentEventResult::GetSucceeded(bool *aSucceeded)
{
NS_ENSURE_TRUE(mEventID != 0, NS_ERROR_NOT_INITIALIZED);
NS_ENSURE_TRUE(mEventMessage != eVoidEvent, NS_ERROR_NOT_INITIALIZED);
*aSucceeded = mSucceeded;
return NS_OK;
}
@@ -135,8 +135,8 @@ NS_IMETHODIMP
nsQueryContentEventResult::GetNotFound(bool *aNotFound)
{
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(mEventID == NS_QUERY_SELECTED_TEXT ||
mEventID == NS_QUERY_CHARACTER_AT_POINT,
NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText ||
mEventMessage == NS_QUERY_CHARACTER_AT_POINT,
NS_ERROR_NOT_AVAILABLE);
*aNotFound = (mOffset == WidgetQueryContentEvent::NOT_FOUND);
return NS_OK;
@@ -148,7 +148,7 @@ nsQueryContentEventResult::GetTentativeCaretOffsetNotFound(bool* aNotFound)
if (NS_WARN_IF(!mSucceeded)) {
return NS_ERROR_NOT_AVAILABLE;
}
if (NS_WARN_IF(mEventID != NS_QUERY_CHARACTER_AT_POINT)) {
if (NS_WARN_IF(mEventMessage != NS_QUERY_CHARACTER_AT_POINT)) {
return NS_ERROR_NOT_AVAILABLE;
}
*aNotFound = (mTentativeCaretOffset == WidgetQueryContentEvent::NOT_FOUND);
@@ -159,7 +159,7 @@ void
nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
const WidgetQueryContentEvent &aEvent)
{
mEventID = aEvent.mMessage;
mEventMessage = aEvent.mMessage;
mSucceeded = aEvent.mSucceeded;
mReversed = aEvent.mReply.mReversed;
mRect = aEvent.mReply.mRect;
@@ -167,7 +167,7 @@ nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
mTentativeCaretOffset = aEvent.mReply.mTentativeCaretOffset;
mString = aEvent.mReply.mString;
if (!IsRectEnabled(mEventID) || !aWidget || !mSucceeded) {
if (!IsRectEnabled(mEventMessage) || !aWidget || !mSucceeded) {
return;
}
+1 -1
View File
@@ -29,7 +29,7 @@ public:
protected:
~nsQueryContentEventResult();
uint32_t mEventID;
mozilla::EventMessage mEventMessage;
uint32_t mOffset;
uint32_t mTentativeCaretOffset;
+4 -4
View File
@@ -796,11 +796,11 @@ nsresult
ContentEventHandler::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
{
switch (aEvent->mMessage) {
case NS_QUERY_SELECTED_TEXT:
case eQuerySelectedText:
return OnQuerySelectedText(aEvent);
case NS_QUERY_TEXT_CONTENT:
case eQueryTextContent:
return OnQueryTextContent(aEvent);
case NS_QUERY_CARET_RECT:
case eQueryCaretRect:
return OnQueryCaretRect(aEvent);
case NS_QUERY_TEXT_RECT:
return OnQueryTextRect(aEvent);
@@ -808,7 +808,7 @@ ContentEventHandler::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
return OnQueryEditorRect(aEvent);
case NS_QUERY_CONTENT_STATE:
return OnQueryContentState(aEvent);
case NS_QUERY_SELECTION_AS_TRANSFERABLE:
case eQuerySelectionAsTransferable:
return OnQuerySelectionAsTransferable(aEvent);
case NS_QUERY_CHARACTER_AT_POINT:
return OnQueryCharacterAtPoint(aEvent);
+4 -4
View File
@@ -42,11 +42,11 @@ public:
// Handle aEvent in the current process.
nsresult HandleQueryContentEvent(WidgetQueryContentEvent* aEvent);
// NS_QUERY_SELECTED_TEXT event handler
// eQuerySelectedText event handler
nsresult OnQuerySelectedText(WidgetQueryContentEvent* aEvent);
// NS_QUERY_TEXT_CONTENT event handler
// eQueryTextContent event handler
nsresult OnQueryTextContent(WidgetQueryContentEvent* aEvent);
// NS_QUERY_CARET_RECT event handler
// eQueryCaretRect event handler
nsresult OnQueryCaretRect(WidgetQueryContentEvent* aEvent);
// NS_QUERY_TEXT_RECT event handler
nsresult OnQueryTextRect(WidgetQueryContentEvent* aEvent);
@@ -54,7 +54,7 @@ public:
nsresult OnQueryEditorRect(WidgetQueryContentEvent* aEvent);
// NS_QUERY_CONTENT_STATE event handler
nsresult OnQueryContentState(WidgetQueryContentEvent* aEvent);
// NS_QUERY_SELECTION_AS_TRANSFERABLE event handler
// eQuerySelectionAsTransferable event handler
nsresult OnQuerySelectionAsTransferable(WidgetQueryContentEvent* aEvent);
// NS_QUERY_CHARACTER_AT_POINT event handler
nsresult OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent);
+2 -2
View File
@@ -649,11 +649,11 @@ NON_IDL_EVENT(DOMFocusOut,
eUIEventClass)
NON_IDL_EVENT(DOMMouseScroll,
NS_MOUSE_SCROLL,
eLegacyMouseLineOrPageScroll,
EventNameType_HTMLXUL,
eMouseScrollEventClass)
NON_IDL_EVENT(MozMousePixelScroll,
NS_MOUSE_PIXEL_SCROLL,
eLegacyMousePixelScroll,
EventNameType_HTMLXUL,
eMouseScrollEventClass)
+14 -14
View File
@@ -759,7 +759,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
InitLineOrPageDelta(aTargetFrame, this, wheelEvent);
}
break;
case NS_SELECTION_SET:
case eSetSelection:
IMEStateManager::HandleSelectionEvent(aPresContext, GetFocusedContent(),
aEvent->AsSelectionEvent());
break;
@@ -784,7 +784,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
// If the event is trusted event, set the selected text to data of
// composition event.
WidgetCompositionEvent* compositionEvent = aEvent->AsCompositionEvent();
WidgetQueryContentEvent selectedText(true, NS_QUERY_SELECTED_TEXT,
WidgetQueryContentEvent selectedText(true, eQuerySelectedText,
compositionEvent->widget);
HandleQueryContentEvent(&selectedText);
NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text");
@@ -801,9 +801,9 @@ void
EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
{
switch (aEvent->mMessage) {
case NS_QUERY_SELECTED_TEXT:
case NS_QUERY_TEXT_CONTENT:
case NS_QUERY_CARET_RECT:
case eQuerySelectedText:
case eQueryTextContent:
case eQueryCaretRect:
case NS_QUERY_TEXT_RECT:
case NS_QUERY_EDITOR_RECT:
if (!IsTargetCrossProcess(aEvent)) {
@@ -814,7 +814,7 @@ EventStateManager::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
return;
// Following events have not been supported in e10s mode yet.
case NS_QUERY_CONTENT_STATE:
case NS_QUERY_SELECTION_AS_TRANSFERABLE:
case eQuerySelectionAsTransferable:
case NS_QUERY_CHARACTER_AT_POINT:
case NS_QUERY_DOM_WIDGET_HITTEST:
break;
@@ -2209,8 +2209,8 @@ EventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame,
targetContent = targetContent->GetParent();
}
WidgetMouseScrollEvent event(aEvent->mFlags.mIsTrusted, NS_MOUSE_SCROLL,
aEvent->widget);
WidgetMouseScrollEvent event(aEvent->mFlags.mIsTrusted,
eLegacyMouseLineOrPageScroll, aEvent->widget);
event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
event.refPoint = aEvent->refPoint;
@@ -2249,8 +2249,8 @@ EventStateManager::SendPixelScrollEvent(nsIFrame* aTargetFrame,
targetContent = targetContent->GetParent();
}
WidgetMouseScrollEvent event(aEvent->mFlags.mIsTrusted, NS_MOUSE_PIXEL_SCROLL,
aEvent->widget);
WidgetMouseScrollEvent event(aEvent->mFlags.mIsTrusted,
eLegacyMousePixelScroll, aEvent->widget);
event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
event.refPoint = aEvent->refPoint;
@@ -3101,8 +3101,8 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
break;
}
case WheelPrefs::ACTION_HISTORY: {
// If this event doesn't cause NS_MOUSE_SCROLL event or the direction
// is oblique, don't perform history back/forward.
// If this event doesn't cause eLegacyMouseLineOrPageScroll event or
// the direction is oblique, don't perform history back/forward.
int32_t intDelta = wheelEvent->GetPreferredIntDelta();
if (!intDelta) {
break;
@@ -3111,8 +3111,8 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
break;
}
case WheelPrefs::ACTION_ZOOM: {
// If this event doesn't cause NS_MOUSE_SCROLL event or the direction
// is oblique, don't perform zoom in/out.
// If this event doesn't cause eLegacyMouseLineOrPageScroll event or
// the direction is oblique, don't perform zoom in/out.
int32_t intDelta = wheelEvent->GetPreferredIntDelta();
if (!intDelta) {
break;
+2 -2
View File
@@ -109,8 +109,8 @@ public:
nsEventStatus* aStatus);
/**
* DispatchLegacyMouseScrollEvents() dispatches NS_MOUSE_SCROLL event and
* NS_MOUSE_PIXEL_SCROLL event for compatiblity with old Gecko.
* DispatchLegacyMouseScrollEvents() dispatches eLegacyMouseLineOrPageScroll
* event and eLegacyMousePixelScroll event for compatibility with old Gecko.
*/
void DispatchLegacyMouseScrollEvents(nsIFrame* aTargetFrame,
WidgetWheelEvent* aEvent,
+10 -11
View File
@@ -51,20 +51,20 @@ static const char*
ToChar(EventMessage aEventMessage)
{
switch (aEventMessage) {
case NS_QUERY_SELECTED_TEXT:
return "NS_QUERY_SELECTED_TEXT";
case NS_QUERY_TEXT_CONTENT:
return "NS_QUERY_TEXT_CONTENT";
case NS_QUERY_CARET_RECT:
return "NS_QUERY_CARET_RECT";
case eQuerySelectedText:
return "eQuerySelectedText";
case eQueryTextContent:
return "eQueryTextContent";
case eQueryCaretRect:
return "eQueryCaretRect";
case NS_QUERY_TEXT_RECT:
return "NS_QUERY_TEXT_RECT";
case NS_QUERY_EDITOR_RECT:
return "NS_QUERY_EDITOR_RECT";
case NS_QUERY_CONTENT_STATE:
return "NS_QUERY_CONTENT_STATE";
case NS_QUERY_SELECTION_AS_TRANSFERABLE:
return "NS_QUERY_SELECTION_AS_TRANSFERABLE";
case eQuerySelectionAsTransferable:
return "eQuerySelectionAsTransferable";
case NS_QUERY_CHARACTER_AT_POINT:
return "NS_QUERY_CHARACTER_AT_POINT";
case NS_QUERY_DOM_WIDGET_HITTEST:
@@ -569,8 +569,7 @@ IMEContentObserver::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
// If the instance has cache, it should use the cached selection which was
// sent to the widget.
if (aEvent->mMessage == NS_QUERY_SELECTED_TEXT &&
aEvent->mUseNativeLineBreak &&
if (aEvent->mMessage == eQuerySelectedText && aEvent->mUseNativeLineBreak &&
mSelectionData.IsValid()) {
aEvent->mReply.mContentsRoot = mRootContent;
aEvent->mReply.mHasSelection = !mSelectionData.IsCollapsed();
@@ -1109,7 +1108,7 @@ IMEContentObserver::UpdateSelectionCache()
// XXX Cannot we cache some information for reducing the cost to compute
// selection offset and writing mode?
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, mWidget);
WidgetQueryContentEvent selection(true, eQuerySelectedText, mWidget);
ContentEventHandler handler(GetPresContext());
handler.OnQuerySelectedText(&selection);
if (NS_WARN_IF(!selection.mSucceeded)) {
+2 -2
View File
@@ -149,8 +149,8 @@ GetEventMessageName(EventMessage aMessage)
return "NS_COMPOSITION_COMMIT_AS_IS";
case NS_COMPOSITION_COMMIT:
return "NS_COMPOSITION_COMMIT";
case NS_SELECTION_SET:
return "NS_SELECTION_SET";
case eSetSelection:
return "eSetSelection";
default:
return "unacceptable event message";
}
+2 -5
View File
@@ -415,9 +415,7 @@ TextComposition::NotityUpdateComposition(
if (aCompositionEvent->mMessage == NS_COMPOSITION_START) {
nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
// Update composition start offset
WidgetQueryContentEvent selectedTextEvent(true,
NS_QUERY_SELECTED_TEXT,
widget);
WidgetQueryContentEvent selectedTextEvent(true, eQuerySelectedText, widget);
widget->DispatchEvent(&selectedTextEvent, status);
if (selectedTextEvent.mSucceeded) {
mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
@@ -615,8 +613,7 @@ TextComposition::CompositionEventDispatcher::Run()
switch (mEventMessage) {
case NS_COMPOSITION_START: {
WidgetCompositionEvent compStart(true, NS_COMPOSITION_START, widget);
WidgetQueryContentEvent selectedText(true, NS_QUERY_SELECTED_TEXT,
widget);
WidgetQueryContentEvent selectedText(true, eQuerySelectedText, widget);
ContentEventHandler handler(presContext);
handler.OnQuerySelectedText(&selectedText);
NS_ASSERTION(selectedText.mSucceeded, "Failed to get selected text");
+2 -2
View File
@@ -2458,8 +2458,8 @@ nsGenericHTMLFormElement::IsElementDisabledForEvents(EventMessage aMessage,
case ePointerEnter:
case ePointerLeave:
case NS_WHEEL_WHEEL:
case NS_MOUSE_SCROLL:
case NS_MOUSE_PIXEL_SCROLL:
case eLegacyMouseLineOrPageScroll:
case eLegacyMousePixelScroll:
return false;
default:
break;
+1 -1
View File
@@ -2334,7 +2334,7 @@ TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
}
switch (aEvent.mMessage) {
case NS_QUERY_TEXT_RECT:
case NS_QUERY_CARET_RECT:
case eQueryCaretRect:
case NS_QUERY_EDITOR_RECT:
aEvent.mReply.mRect -= GetChildProcessOffset();
break;
+5 -5
View File
@@ -1812,7 +1812,7 @@ CocoaEventTypeForEvent(const WidgetGUIEvent& anEvent, nsIFrame* aObjectFrame)
case eFocus:
case eBlur:
return NPCocoaEventFocusChanged;
case NS_MOUSE_SCROLL:
case eLegacyMouseLineOrPageScroll:
return NPCocoaEventScrollWheel;
default:
return (NPCocoaEventType)0;
@@ -1829,7 +1829,7 @@ TranslateToNPCocoaEvent(WidgetGUIEvent* anEvent, nsIFrame* aObjectFrame)
if (anEvent->mMessage == eMouseMove ||
anEvent->mMessage == eMouseDown ||
anEvent->mMessage == eMouseUp ||
anEvent->mMessage == NS_MOUSE_SCROLL ||
anEvent->mMessage == eLegacyMouseLineOrPageScroll ||
anEvent->mMessage == eMouseOver ||
anEvent->mMessage == eMouseOut)
{
@@ -1871,14 +1871,14 @@ TranslateToNPCocoaEvent(WidgetGUIEvent* anEvent, nsIFrame* aObjectFrame)
}
break;
}
case NS_MOUSE_SCROLL:
{
case eLegacyMouseLineOrPageScroll: {
WidgetWheelEvent* wheelEvent = anEvent->AsWheelEvent();
if (wheelEvent) {
cocoaEvent.data.mouse.deltaX = wheelEvent->lineOrPageDeltaX;
cocoaEvent.data.mouse.deltaY = wheelEvent->lineOrPageDeltaY;
} else {
NS_WARNING("NS_MOUSE_SCROLL is not a WidgetWheelEvent? (could be, haven't checked)");
NS_WARNING("eLegacyMouseLineOrPageScroll is not a WidgetWheelEvent? "
"(could be, haven't checked)");
}
break;
}
+12 -6
View File
@@ -2081,8 +2081,8 @@ gfxFont::IsSpaceGlyphInvisible(gfxContext *aRefContext, gfxTextRun *aTextRun)
GetOrCreateGlyphExtents(aTextRun->GetAppUnitsPerDevUnit());
gfxRect glyphExtents;
mFontEntry->mSpaceGlyphIsInvisible =
extents->GetTightGlyphExtentsAppUnits(this, eHorizontal,
aRefContext, GetSpaceGlyph(), &glyphExtents) &&
extents->GetTightGlyphExtentsAppUnits(this, aRefContext,
GetSpaceGlyph(), &glyphExtents) &&
glyphExtents.IsEmpty();
mFontEntry->mSpaceGlyphIsInvisibleInitialized = true;
}
@@ -2189,11 +2189,14 @@ gfxFont::Measure(gfxTextRun *aTextRun,
} else {
gfxRect glyphRect;
if (!extents->GetTightGlyphExtentsAppUnits(this,
orientation,
aRefContext, glyphIndex, &glyphRect)) {
glyphRect = gfxRect(0, metrics.mBoundingBox.Y(),
advance, metrics.mBoundingBox.Height());
}
if (orientation == eVertical) {
Swap(glyphRect.x, glyphRect.y);
Swap(glyphRect.width, glyphRect.height);
}
if (isRTL) {
glyphRect -= gfxPoint(advance, 0);
}
@@ -2218,13 +2221,16 @@ gfxFont::Measure(gfxTextRun *aTextRun,
gfxRect glyphRect;
if (glyphData->IsMissing() || !extents ||
!extents->GetTightGlyphExtentsAppUnits(this,
orientation,
aRefContext, glyphIndex, &glyphRect)) {
// We might have failed to get glyph extents due to
// OOM or something
glyphRect = gfxRect(0, -metrics.mAscent,
advance, metrics.mAscent + metrics.mDescent);
}
if (orientation == eVertical) {
Swap(glyphRect.x, glyphRect.y);
Swap(glyphRect.width, glyphRect.height);
}
if (isRTL) {
glyphRect -= gfxPoint(advance, 0);
}
@@ -3108,7 +3114,7 @@ gfxFont::GetOrCreateGlyphExtents(int32_t aAppUnitsPerDevUnit) {
}
void
gfxFont::SetupGlyphExtents(gfxContext *aContext, Orientation aOrientation,
gfxFont::SetupGlyphExtents(gfxContext *aContext,
uint32_t aGlyphID, bool aNeedTight,
gfxGlyphExtents *aExtents)
{
@@ -3134,7 +3140,7 @@ gfxFont::SetupGlyphExtents(gfxContext *aContext, Orientation aOrientation,
cairo_text_extents_t extents;
cairo_glyph_extents(aContext->GetCairo(), &glyph, 1, &extents);
const Metrics& fontMetrics = GetMetrics(aOrientation);
const Metrics& fontMetrics = GetMetrics(eHorizontal);
int32_t appUnitsPerDevUnit = aExtents->GetAppUnitsPerDevUnit();
if (!aNeedTight && extents.x_bearing >= 0 &&
extents.y_bearing >= -fontMetrics.maxAscent &&
+1 -2
View File
@@ -1614,8 +1614,7 @@ public:
gfxGlyphExtents *GetOrCreateGlyphExtents(int32_t aAppUnitsPerDevUnit);
// You need to call SetupCairoFont on the aCR just before calling this
virtual void SetupGlyphExtents(gfxContext *aContext,
Orientation aOrientation, uint32_t aGlyphID,
virtual void SetupGlyphExtents(gfxContext *aContext, uint32_t aGlyphID,
bool aNeedTight, gfxGlyphExtents *aExtents);
// This is called by the default Draw() implementation above.
+1 -3
View File
@@ -36,7 +36,6 @@ gfxGlyphExtents::~gfxGlyphExtents()
bool
gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont *aFont,
gfxFont::Orientation aOrientation,
gfxContext *aContext, uint32_t aGlyphID, gfxRect *aExtents)
{
HashEntry *entry = mTightGlyphExtents.GetEntry(aGlyphID);
@@ -50,8 +49,7 @@ gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont *aFont,
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
++gGlyphExtentsSetupLazyTight;
#endif
aFont->SetupGlyphExtents(aContext, aOrientation, aGlyphID, true,
this);
aFont->SetupGlyphExtents(aContext, aGlyphID, true, this);
entry = mTightGlyphExtents.GetEntry(aGlyphID);
}
if (!entry) {
-1
View File
@@ -63,7 +63,6 @@ public:
// Returns true on success. Can fail on OOM or when aContext is null
// and extents were not (successfully) prefetched.
bool GetTightGlyphExtentsAppUnits(gfxFont *aFont,
gfxFont::Orientation aOrientation,
gfxContext *aContext, uint32_t aGlyphID, gfxRect *aExtents);
void SetContainedGlyphWidthAppUnits(uint32_t aGlyphID, uint16_t aWidth) {
+2 -4
View File
@@ -1374,8 +1374,6 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
for (j = start; j < end; ++j) {
const gfxTextRun::CompressedGlyph *glyphData = &charGlyphs[j];
gfxFont::Orientation orientation =
IsVertical() ? gfxFont::eVertical : gfxFont::eHorizontal;
if (glyphData->IsSimpleGlyph()) {
// If we're in speed mode, don't set up glyph extents here; we'll
// just return "optimistic" glyph bounds later
@@ -1392,7 +1390,7 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
++gGlyphExtentsSetupEagerSimple;
#endif
font->SetupGlyphExtents(aRefContext, orientation,
font->SetupGlyphExtents(aRefContext,
glyphIndex, false, extents);
}
}
@@ -1418,7 +1416,7 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
++gGlyphExtentsSetupEagerTight;
#endif
font->SetupGlyphExtents(aRefContext, orientation,
font->SetupGlyphExtents(aRefContext,
glyphIndex, true, extents);
}
}
+1 -1
View File
@@ -7164,7 +7164,7 @@ PresShell::HandleEvent(nsIFrame* aFrame,
if (presShell != this) {
nsIFrame* frame = presShell->GetRootFrame();
if (!frame) {
if (aEvent->mMessage == NS_QUERY_TEXT_CONTENT ||
if (aEvent->mMessage == eQueryTextContent ||
aEvent->IsContentCommandEvent()) {
return NS_OK;
}
+1
View File
@@ -3019,6 +3019,7 @@ nsFrame::HandlePress(nsPresContext* aPresContext,
if (curDetail->mType != nsISelectionController::SELECTION_SPELLCHECK &&
curDetail->mType != nsISelectionController::SELECTION_FIND &&
curDetail->mType != nsISelectionController::SELECTION_URLSECONDARY &&
curDetail->mType != nsISelectionController::SELECTION_URLSTRIKEOUT &&
curDetail->mStart <= offsets.StartOffset() &&
offsets.EndOffset() <= curDetail->mEnd)
{
+1 -1
View File
@@ -3285,7 +3285,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsOverflowAreas& aOverflo
if (pfd->mRecomputeOverflow ||
frame->StyleContext()->HasTextDecorationLines()) {
nsTextFrame* f = static_cast<nsTextFrame*>(frame);
r = f->RecomputeOverflow(*mBlockReflowState);
r = f->RecomputeOverflow(mBlockReflowState->frame);
}
frame->FinishAndStoreOverflow(r, frame->GetSize());
}
+2
View File
@@ -275,6 +275,7 @@ GetIndexFromSelectionType(SelectionType aType)
case nsISelectionController::SELECTION_ACCESSIBILITY: return 6; break;
case nsISelectionController::SELECTION_FIND: return 7; break;
case nsISelectionController::SELECTION_URLSECONDARY: return 8; break;
case nsISelectionController::SELECTION_URLSTRIKEOUT: return 9; break;
default:
return -1; break;
}
@@ -296,6 +297,7 @@ GetSelectionTypeFromIndex(int8_t aIndex)
case 6: return nsISelectionController::SELECTION_ACCESSIBILITY; break;
case 7: return nsISelectionController::SELECTION_FIND; break;
case 8: return nsISelectionController::SELECTION_URLSECONDARY; break;
case 9: return nsISelectionController::SELECTION_URLSTRIKEOUT; break;
default:
return nsISelectionController::SELECTION_NORMAL; break;
}
+236 -153
View File
@@ -354,6 +354,9 @@ public:
}
}
nscolor GetSystemFieldForegroundColor();
nscolor GetSystemFieldBackgroundColor();
protected:
nsTextFrame* mFrame;
nsPresContext* mPresContext;
@@ -373,6 +376,8 @@ protected:
int32_t mSufficientContrast;
nscolor mFrameBackgroundColor;
nscolor mSystemFieldForegroundColor;
nscolor mSystemFieldBackgroundColor;
// selection colors and underline info, the colors are resolved colors if
// mResolveColors is true (which is the default), i.e., the foreground color
@@ -3637,6 +3642,11 @@ nsTextPaintStyle::InitCommonColors()
nscolor defaultBgColor = mPresContext->DefaultBackgroundColor();
mFrameBackgroundColor = NS_ComposeColors(defaultBgColor, bgColor);
mSystemFieldForegroundColor =
LookAndFeel::GetColor(LookAndFeel::eColorID__moz_fieldtext);
mSystemFieldBackgroundColor =
LookAndFeel::GetColor(LookAndFeel::eColorID__moz_field);
if (bgFrame->IsThemed()) {
// Assume a native widget has sufficient contrast always
mSufficientContrast = 0;
@@ -3664,6 +3674,20 @@ nsTextPaintStyle::InitCommonColors()
mInitCommonColors = true;
}
nscolor
nsTextPaintStyle::GetSystemFieldForegroundColor()
{
InitCommonColors();
return mSystemFieldForegroundColor;
}
nscolor
nsTextPaintStyle::GetSystemFieldBackgroundColor()
{
InitCommonColors();
return mSystemFieldBackgroundColor;
}
static Element*
FindElementAncestorForMozSelection(nsIContent* aContent)
{
@@ -4830,6 +4854,18 @@ LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame)
}
}
static bool IsUnderlineRight(nsIFrame* aFrame)
{
nsIAtom* langAtom = aFrame->StyleFont()->mLanguage;
if (!langAtom) {
return false;
}
nsAtomString langStr(langAtom);
return (StringBeginsWith(langStr, NS_LITERAL_STRING("ja")) ||
StringBeginsWith(langStr, NS_LITERAL_STRING("ko"))) &&
(langStr.Length() == 2 || langStr[2] == '-');
}
void
nsTextFrame::GetTextDecorations(
nsPresContext* aPresContext,
@@ -4928,11 +4964,19 @@ nsTextFrame::GetTextDecorations(
color = nsLayoutUtils::GetColor(f, eCSSProperty_text_decoration_color);
}
if (textDecorations & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE) {
bool swapUnderlineAndOverline = vertical && IsUnderlineRight(f);
const uint8_t kUnderline =
swapUnderlineAndOverline ? NS_STYLE_TEXT_DECORATION_LINE_OVERLINE :
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
const uint8_t kOverline =
swapUnderlineAndOverline ? NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE :
NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
if (textDecorations & kUnderline) {
aDecorations.mUnderlines.AppendElement(
nsTextFrame::LineDecoration(f, baselineOffset, color, style));
}
if (textDecorations & NS_STYLE_TEXT_DECORATION_LINE_OVERLINE) {
if (textDecorations & kOverline) {
aDecorations.mOverlines.AppendElement(
nsTextFrame::LineDecoration(f, baselineOffset, color, style));
}
@@ -4965,6 +5009,12 @@ nsTextFrame::GetTextDecorations(
if (f->IsFloating() || f->IsAbsolutelyPositioned()) {
break;
}
// If we're an outer <svg> element, which is classified as an atomic
// inline-level element, we're done.
if (f->GetType() == nsGkAtoms::svgOuterSVGFrame) {
break;
}
}
}
@@ -5175,16 +5225,16 @@ nsTextFrame::UnionAdditionalOverflow(nsPresContext* aPresContext,
AddStateBits(TEXT_SELECTION_UNDERLINE_OVERFLOWED);
}
static gfxFloat
ComputeDescentLimitForSelectionUnderline(nsPresContext* aPresContext,
nsTextFrame* aFrame,
const gfxFont::Metrics& aFontMetrics)
gfxFloat
nsTextFrame::ComputeDescentLimitForSelectionUnderline(
nsPresContext* aPresContext,
const gfxFont::Metrics& aFontMetrics)
{
gfxFloat app = aPresContext->AppUnitsPerDevPixel();
nscoord lineHeightApp =
nsHTMLReflowState::CalcLineHeight(aFrame->GetContent(),
aFrame->StyleContext(), NS_AUTOHEIGHT,
aFrame->GetFontSizeInflation());
nsHTMLReflowState::CalcLineHeight(GetContent(),
StyleContext(), NS_AUTOHEIGHT,
GetFontSizeInflation());
gfxFloat lineHeight = gfxFloat(lineHeightApp) / app;
if (lineHeight <= aFontMetrics.maxHeight) {
return aFontMetrics.maxDescent;
@@ -5196,15 +5246,18 @@ ComputeDescentLimitForSelectionUnderline(nsPresContext* aPresContext,
// Make sure this stays in sync with DrawSelectionDecorations below
static const SelectionType SelectionTypesWithDecorations =
nsISelectionController::SELECTION_SPELLCHECK |
nsISelectionController::SELECTION_URLSTRIKEOUT |
nsISelectionController::SELECTION_IME_RAWINPUT |
nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT |
nsISelectionController::SELECTION_IME_CONVERTEDTEXT |
nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT;
static gfxFloat
ComputeSelectionUnderlineHeight(nsPresContext* aPresContext,
const gfxFont::Metrics& aFontMetrics,
SelectionType aSelectionType)
/* static */
gfxFloat
nsTextFrame::ComputeSelectionUnderlineHeight(
nsPresContext* aPresContext,
const gfxFont::Metrics& aFontMetrics,
SelectionType aSelectionType)
{
switch (aSelectionType) {
case nsISelectionController::SELECTION_IME_RAWINPUT:
@@ -5232,28 +5285,22 @@ ComputeSelectionUnderlineHeight(nsPresContext* aPresContext,
}
}
enum DecorationType {
eNormalDecoration,
eSelectionDecoration
};
static void
PaintDecorationLine(nsIFrame* aFrame,
gfxContext* const aCtx,
const gfxRect& aDirtyRect,
nscolor aColor,
const nscolor* aOverrideColor,
const gfxPoint& aPt,
gfxFloat aICoordInFrame,
const gfxSize& aLineSize,
gfxFloat aAscent,
gfxFloat aOffset,
uint8_t aDecoration,
uint8_t aStyle,
DecorationType aDecorationType,
nsTextFrame::DrawPathCallbacks* aCallbacks,
bool aVertical,
gfxFloat aDescentLimit = -1.0)
void
nsTextFrame::PaintDecorationLine(gfxContext* const aCtx,
const gfxRect& aDirtyRect,
nscolor aColor,
const nscolor* aOverrideColor,
const gfxPoint& aPt,
gfxFloat aICoordInFrame,
const gfxSize& aLineSize,
gfxFloat aAscent,
gfxFloat aOffset,
uint8_t aDecoration,
uint8_t aStyle,
DecorationType aDecorationType,
DrawPathCallbacks* aCallbacks,
bool aVertical,
gfxFloat aDescentLimit /* = -1.0 */)
{
nscolor lineColor = aOverrideColor ? *aOverrideColor : aColor;
if (aCallbacks) {
@@ -5262,7 +5309,7 @@ PaintDecorationLine(nsIFrame* aFrame,
} else {
aCallbacks->NotifyBeforeSelectionDecorationLine(lineColor);
}
nsCSSRendering::DecorationLineToPath(aFrame, aCtx, aDirtyRect, lineColor,
nsCSSRendering::DecorationLineToPath(this, aCtx, aDirtyRect, lineColor,
aPt, aICoordInFrame, aLineSize, aAscent, aOffset, aDecoration, aStyle,
aVertical, aDescentLimit);
if (aDecorationType == eNormalDecoration) {
@@ -5271,7 +5318,7 @@ PaintDecorationLine(nsIFrame* aFrame,
aCallbacks->NotifySelectionDecorationLinePathEmitted();
}
} else {
nsCSSRendering::PaintDecorationLine(aFrame, *aCtx->GetDrawTarget(),
nsCSSRendering::PaintDecorationLine(this, *aCtx->GetDrawTarget(),
ToRect(aDirtyRect), lineColor,
aPt, Float(aICoordInFrame), aLineSize, aAscent, aOffset, aDecoration, aStyle,
aVertical, aDescentLimit);
@@ -5282,16 +5329,20 @@ PaintDecorationLine(nsIFrame* aFrame,
* This, plus SelectionTypesWithDecorations, encapsulates all knowledge about
* drawing text decoration for selections.
*/
static void DrawSelectionDecorations(gfxContext* aContext,
const gfxRect& aDirtyRect,
SelectionType aType,
nsTextFrame* aFrame,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
const gfxPoint& aPt, gfxFloat aICoordInFrame, gfxFloat aWidth,
gfxFloat aAscent, const gfxFont::Metrics& aFontMetrics,
nsTextFrame::DrawPathCallbacks* aCallbacks,
bool aVertical)
void
nsTextFrame::DrawSelectionDecorations(gfxContext* aContext,
const gfxRect& aDirtyRect,
SelectionType aType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
const gfxPoint& aPt,
gfxFloat aICoordInFrame,
gfxFloat aWidth,
gfxFloat aAscent,
const gfxFont::Metrics& aFontMetrics,
DrawPathCallbacks* aCallbacks,
bool aVertical,
uint8_t aDecoration)
{
gfxPoint pt(aPt);
gfxSize size(aWidth,
@@ -5299,7 +5350,7 @@ static void DrawSelectionDecorations(gfxContext* aContext,
aFontMetrics, aType));
gfxFloat descentLimit =
ComputeDescentLimitForSelectionUnderline(aTextPaintStyle.PresContext(),
aFrame, aFontMetrics);
aFontMetrics);
float relativeSize;
uint8_t style;
@@ -5310,6 +5361,9 @@ static void DrawSelectionDecorations(gfxContext* aContext,
aTextPaintStyle.GetSelectionUnderlineForPaint(index, &color,
&relativeSize, &style);
gfxFloat offset = aDecoration == NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE ?
aFontMetrics.underlineOffset : aFontMetrics.maxAscent;
switch (aType) {
case nsISelectionController::SELECTION_IME_RAWINPUT:
case nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT:
@@ -5342,13 +5396,25 @@ static void DrawSelectionDecorations(gfxContext* aContext,
// There is no underline style definition.
return;
}
if (aRangeStyle.IsUnderlineColorDefined()) {
// If underline color is defined and that doesn't depend on the
// foreground color, we should use the color directly.
if (aRangeStyle.IsUnderlineColorDefined() &&
aRangeStyle.IsForegroundColorDefined() &&
aRangeStyle.mUnderlineColor != aRangeStyle.mForegroundColor) {
color = aRangeStyle.mUnderlineColor;
} else if (aRangeStyle.IsForegroundColorDefined()) {
color = aRangeStyle.mForegroundColor;
} else {
NS_ASSERTION(!aRangeStyle.IsBackgroundColorDefined(),
"Only the background color is defined");
}
// If foreground color or background color is defined, the both colors
// are computed by GetSelectionTextColors(). Then, we should use its
// foreground color always. The color should have sufficient contrast
// with the background color.
else if (aRangeStyle.IsForegroundColorDefined() ||
aRangeStyle.IsBackgroundColorDefined()) {
nscolor bg;
GetSelectionTextColors(aType, aTextPaintStyle, aRangeStyle,
&color, &bg);
}
// Otherwise, use the foreground color of the frame.
else {
color = aTextPaintStyle.GetTextColor();
}
} else if (!weDefineSelectionUnderline) {
@@ -5362,30 +5428,37 @@ static void DrawSelectionDecorations(gfxContext* aContext,
if (!weDefineSelectionUnderline)
return;
break;
case nsISelectionController::SELECTION_URLSTRIKEOUT: {
nscoord inflationMinFontSize =
nsLayoutUtils::InflationMinFontSizeFor(this);
float inflation =
GetInflationForTextDecorations(this, inflationMinFontSize);
const gfxFont::Metrics metrics =
GetFirstFontMetrics(GetFontGroupForFrame(this, inflation), aVertical);
relativeSize = 2.0f;
offset = metrics.strikeoutOffset + 0.5;
aDecoration = NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH;
break;
}
default:
NS_WARNING("Requested selection decorations when there aren't any");
return;
}
size.height *= relativeSize;
PaintDecorationLine(aFrame, aContext, aDirtyRect, color, nullptr, pt,
PaintDecorationLine(aContext, aDirtyRect, color, nullptr, pt,
(aVertical ? (pt.y - aPt.y) : (pt.x - aPt.x)) + aICoordInFrame,
size, aAscent, aFontMetrics.underlineOffset,
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, style, eSelectionDecoration,
size, aAscent, offset, aDecoration, style, eSelectionDecoration,
aCallbacks, aVertical, descentLimit);
}
/**
* This function encapsulates all knowledge of how selections affect foreground
* and background colors.
* @return true if the selection affects colors, false otherwise
* @param aForeground the foreground color to use
* @param aBackground the background color to use, or RGBA(0,0,0,0) if no
* background should be painted
*/
static bool GetSelectionTextColors(SelectionType aType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
nscolor* aForeground, nscolor* aBackground)
/* static */
bool
nsTextFrame::GetSelectionTextColors(SelectionType aType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
nscolor* aForeground,
nscolor* aBackground)
{
switch (aType) {
case nsISelectionController::SELECTION_NORMAL:
@@ -5402,17 +5475,28 @@ static bool GetSelectionTextColors(SelectionType aType,
case nsISelectionController::SELECTION_IME_CONVERTEDTEXT:
case nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT:
if (aRangeStyle.IsDefined()) {
*aForeground = aTextPaintStyle.GetTextColor();
*aBackground = NS_RGBA(0,0,0,0);
if (!aRangeStyle.IsForegroundColorDefined() &&
!aRangeStyle.IsBackgroundColorDefined()) {
*aForeground = aTextPaintStyle.GetTextColor();
*aBackground = NS_RGBA(0,0,0,0);
return false;
}
if (aRangeStyle.IsForegroundColorDefined()) {
*aForeground = aRangeStyle.mForegroundColor;
}
if (aRangeStyle.IsBackgroundColorDefined()) {
if (aRangeStyle.IsBackgroundColorDefined()) {
*aBackground = aRangeStyle.mBackgroundColor;
} else {
// If foreground color is defined but background color isn't
// defined, we can guess that IME must expect that the background
// color is system's default field background color.
*aBackground = aTextPaintStyle.GetSystemFieldBackgroundColor();
}
} else { // aRangeStyle.IsBackgroundColorDefined() is true
*aBackground = aRangeStyle.mBackgroundColor;
// If background color is defined but foreground color isn't defined,
// we can assume that IME must expect that the foreground color is
// same as system's field text color.
*aForeground = aTextPaintStyle.GetSystemFieldForegroundColor();
}
return true;
}
@@ -5568,6 +5652,9 @@ AddHyphenToMetrics(nsTextFrame* aTextFrame, gfxTextRun* aBaseTextRun,
gfxTextRun::Metrics hyphenMetrics =
hyphenTextRun->MeasureText(0, hyphenTextRun->GetLength(),
aBoundingBoxType, aContext, nullptr);
if (aTextFrame->GetWritingMode().IsLineInverted()) {
hyphenMetrics.mBoundingBox.y = -hyphenMetrics.mBoundingBox.YMost();
}
aMetrics->CombineWith(hyphenMetrics, aBaseTextRun->IsRightToLeft());
}
@@ -5832,6 +5919,10 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
gfxFont* firstFont = aProvider.GetFontGroup()->GetFirstValidFont();
bool verticalRun = mTextRun->IsVertical();
bool rightUnderline = verticalRun && IsUnderlineRight(this);
const uint8_t kDecoration =
rightUnderline ? NS_STYLE_TEXT_DECORATION_LINE_OVERLINE :
NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE;
bool useVerticalMetrics = verticalRun && mTextRun->UseCenterBaseline();
gfxFont::Metrics
decorationMetrics(firstFont->GetMetrics(useVerticalMetrics ?
@@ -5875,10 +5966,10 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
}
gfxFloat width = Abs(advance) / app;
gfxFloat xInFrame = pt.x - (aFramePt.x / app);
DrawSelectionDecorations(aCtx, dirtyRect, aSelectionType, this,
DrawSelectionDecorations(aCtx, dirtyRect, aSelectionType,
aTextPaintStyle, selectedStyle, pt, xInFrame,
width, mAscent / app, decorationMetrics,
aCallbacks, verticalRun);
aCallbacks, verticalRun, kDecoration);
}
iterator.UpdateWithAdvance(advance);
}
@@ -6388,7 +6479,7 @@ nsTextFrame::DrawTextRunAndDecorations(
decSize.height = metrics.underlineSize;
bCoord = (frameBStart - dec.mBaselineOffset) / app;
PaintDecorationLine(this, aCtx, dirtyRect, dec.mColor,
PaintDecorationLine(aCtx, dirtyRect, dec.mColor,
aDecorationOverrideColor, decPt, 0.0, decSize, ascent,
metrics.underlineOffset, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
dec.mStyle, eNormalDecoration, aCallbacks, verticalRun);
@@ -6409,7 +6500,7 @@ nsTextFrame::DrawTextRunAndDecorations(
decSize.height = metrics.underlineSize;
bCoord = (frameBStart - dec.mBaselineOffset) / app;
PaintDecorationLine(this, aCtx, dirtyRect, dec.mColor,
PaintDecorationLine(aCtx, dirtyRect, dec.mColor,
aDecorationOverrideColor, decPt, 0.0, decSize, ascent,
metrics.maxAscent, NS_STYLE_TEXT_DECORATION_LINE_OVERLINE, dec.mStyle,
eNormalDecoration, aCallbacks, verticalRun);
@@ -6436,7 +6527,7 @@ nsTextFrame::DrawTextRunAndDecorations(
decSize.height = metrics.strikeoutSize;
bCoord = (frameBStart - dec.mBaselineOffset) / app;
PaintDecorationLine(this, aCtx, dirtyRect, dec.mColor,
PaintDecorationLine(aCtx, dirtyRect, dec.mColor,
aDecorationOverrideColor, decPt, 0.0, decSize, ascent,
metrics.strikeoutOffset, NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH,
dec.mStyle, eNormalDecoration, aCallbacks, verticalRun);
@@ -6647,7 +6738,7 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
gfxFloat underlineOffset = fontGroup->GetUnderlineOffset();
gfxFloat ascent = aPresContext->AppUnitsToGfxUnits(mAscent);
gfxFloat descentLimit =
ComputeDescentLimitForSelectionUnderline(aPresContext, this, metrics);
ComputeDescentLimitForSelectionUnderline(aPresContext, metrics);
SelectionDetails *details = GetSelectionDetails();
for (SelectionDetails *sd = details; sd; sd = sd->mNext) {
@@ -7654,8 +7745,9 @@ nsTextFrame::AddInlinePrefISizeForFlow(nsRenderingContext *aRenderingContext,
// XXXldb Shouldn't we be including the newline as part of the
// segment that it ends rather than part of the segment that it
// starts?
NS_ASSERTION(preformatNewlines,
"We can't be here unless newlines are hard breaks");
NS_ASSERTION(preformatNewlines || preformatTabs,
"We can't be here unless newlines are "
"hard breaks or there are tabs");
preformattedNewline = preformatNewlines && textRun->CharIsNewline(i);
preformattedTab = preformatTabs && textRun->CharIsTab(i);
if (!preformattedNewline && !preformattedTab) {
@@ -7799,12 +7891,12 @@ nsTextFrame::ComputeTightBounds(gfxContext* aContext) const
ComputeTransformedLength(provider),
gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS,
aContext, &provider);
if (GetWritingMode().IsLineInverted()) {
metrics.mBoundingBox.y = -metrics.mBoundingBox.YMost();
}
// mAscent should be the same as metrics.mAscent, but it's what we use to
// paint so that's the one we'll use.
nsRect boundingBox = RoundOut(metrics.mBoundingBox);
if (GetWritingMode().IsLineInverted()) {
boundingBox.y = -boundingBox.YMost();
}
boundingBox += nsPoint(0, mAscent);
if (mTextRun->IsVertical()) {
// Swap line-relative textMetrics dimensions to physical coordinates.
@@ -8375,7 +8467,8 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
(GetStateBits() & TEXT_IS_IN_TOKEN_MATHML);
gfxBreakPriority breakPriority = aLineLayout.LastOptionalBreakPriority();
gfxTextRun::SuppressBreak suppressBreak = gfxTextRun::eNoSuppressBreak;
if (ShouldSuppressLineBreak()) {
bool shouldSuppressLineBreak = ShouldSuppressLineBreak();
if (shouldSuppressLineBreak) {
suppressBreak = gfxTextRun::eSuppressAllBreaks;
} else if (!aLineLayout.LineIsBreakable()) {
suppressBreak = gfxTextRun::eSuppressInitialBreak;
@@ -8398,6 +8491,10 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
textMetrics.mDescent = gfxFloat(fm->MaxDescent());
}
}
if (GetWritingMode().IsLineInverted()) {
Swap(textMetrics.mAscent, textMetrics.mDescent);
textMetrics.mBoundingBox.y = -textMetrics.mBoundingBox.YMost();
}
// The "end" iterator points to the first character after the string mapped
// by this frame. Basically, its original-string offset is offset+charsFit
// after we've computed charsFit.
@@ -8503,31 +8600,21 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
finalSize.BSize(wm) = 0;
} else if (boundingBoxType != gfxFont::LOOSE_INK_EXTENTS) {
// Use actual text metrics for floating first letter frame.
if (wm.IsLineInverted()) {
aMetrics.SetBlockStartAscent(NSToCoordCeil(textMetrics.mDescent));
finalSize.BSize(wm) = aMetrics.BlockStartAscent() +
NSToCoordCeil(textMetrics.mAscent);
} else {
aMetrics.SetBlockStartAscent(NSToCoordCeil(textMetrics.mAscent));
finalSize.BSize(wm) = aMetrics.BlockStartAscent() +
NSToCoordCeil(textMetrics.mDescent);
}
aMetrics.SetBlockStartAscent(NSToCoordCeil(textMetrics.mAscent));
finalSize.BSize(wm) = aMetrics.BlockStartAscent() +
NSToCoordCeil(textMetrics.mDescent);
} else {
// Otherwise, ascent should contain the overline drawable area.
// And also descent should contain the underline drawable area.
// nsFontMetrics::GetMaxAscent/GetMaxDescent contains them.
nsFontMetrics* fm = provider.GetFontMetrics();
nscoord fontAscent = fm->MaxAscent();
nscoord fontDescent = fm->MaxDescent();
if (wm.IsLineInverted()) {
aMetrics.SetBlockStartAscent(std::max(NSToCoordCeil(textMetrics.mDescent), fontDescent));
nscoord descent = std::max(NSToCoordCeil(textMetrics.mAscent), fontAscent);
finalSize.BSize(wm) = aMetrics.BlockStartAscent() + descent;
} else {
aMetrics.SetBlockStartAscent(std::max(NSToCoordCeil(textMetrics.mAscent), fontAscent));
nscoord descent = std::max(NSToCoordCeil(textMetrics.mDescent), fontDescent);
finalSize.BSize(wm) = aMetrics.BlockStartAscent() + descent;
}
nscoord fontAscent =
wm.IsLineInverted() ? fm->MaxDescent() : fm->MaxAscent();
nscoord fontDescent =
wm.IsLineInverted() ? fm->MaxAscent() : fm->MaxDescent();
aMetrics.SetBlockStartAscent(std::max(NSToCoordCeil(textMetrics.mAscent), fontAscent));
nscoord descent = std::max(NSToCoordCeil(textMetrics.mDescent), fontDescent);
finalSize.BSize(wm) = aMetrics.BlockStartAscent() + descent;
}
aMetrics.SetSize(wm, finalSize);
@@ -8541,14 +8628,18 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
// Handle text that runs outside its normal bounds.
nsRect boundingBox = RoundOut(textMetrics.mBoundingBox);
if (wm.IsLineInverted()) {
boundingBox.y = -boundingBox.YMost();
}
boundingBox += nsPoint(0, mAscent);
if (mTextRun->IsVertical()) {
// Swap line-relative textMetrics dimensions to physical coordinates.
Swap(boundingBox.x, boundingBox.y);
Swap(boundingBox.width, boundingBox.height);
if (GetWritingMode().IsVerticalRL()) {
boundingBox.x = -boundingBox.XMost();
boundingBox.x += aMetrics.Width() - mAscent;
} else {
boundingBox.x += mAscent;
}
} else {
boundingBox.y += mAscent;
}
aMetrics.SetOverflowAreasToDesiredBounds();
aMetrics.VisualOverflow().UnionRect(aMetrics.VisualOverflow(), boundingBox);
@@ -8572,36 +8663,38 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
aLineLayout.SetTrimmableISize(NSToCoordFloor(trimmableWidth));
AddStateBits(TEXT_HAS_NONCOLLAPSED_CHARACTERS);
}
if (charsFit > 0 && charsFit == length &&
textStyle->mHyphens != NS_STYLE_HYPHENS_NONE &&
HasSoftHyphenBefore(frag, mTextRun, offset, end)) {
bool fits =
textMetrics.mAdvanceWidth + provider.GetHyphenWidth() <= availWidth;
// Record a potential break after final soft hyphen
aLineLayout.NotifyOptionalBreakPosition(this, length, fits,
gfxBreakPriority::eNormalBreak);
}
bool breakAfter = forceBreakAfter;
// length == 0 means either the text is empty or it's all collapsed away
bool emptyTextAtStartOfLine = atStartOfLine && length == 0;
if (!breakAfter && charsFit == length && !emptyTextAtStartOfLine &&
transformedOffset + transformedLength == mTextRun->GetLength() &&
!ShouldSuppressLineBreak() &&
(mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK)) {
// We placed all the text in the textrun and we have a break opportunity at
// the end of the textrun. We need to record it because the following
// content may not care about nsLineBreaker.
// Note that because we didn't break, we can be sure that (thanks to the
// code up above) textMetrics.mAdvanceWidth includes the width of any
// trailing whitespace. So we need to subtract trimmableWidth here
// because if we did break at this point, that much width would be trimmed.
if (textMetrics.mAdvanceWidth - trimmableWidth > availWidth) {
breakAfter = true;
} else {
aLineLayout.NotifyOptionalBreakPosition(this, length, true,
if (!shouldSuppressLineBreak) {
if (charsFit > 0 && charsFit == length &&
textStyle->mHyphens != NS_STYLE_HYPHENS_NONE &&
HasSoftHyphenBefore(frag, mTextRun, offset, end)) {
bool fits =
textMetrics.mAdvanceWidth + provider.GetHyphenWidth() <= availWidth;
// Record a potential break after final soft hyphen
aLineLayout.NotifyOptionalBreakPosition(this, length, fits,
gfxBreakPriority::eNormalBreak);
}
// length == 0 means either the text is empty or it's all collapsed away
bool emptyTextAtStartOfLine = atStartOfLine && length == 0;
if (!breakAfter && charsFit == length && !emptyTextAtStartOfLine &&
transformedOffset + transformedLength == mTextRun->GetLength() &&
(mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK)) {
// We placed all the text in the textrun and we have a break opportunity
// at the end of the textrun. We need to record it because the following
// content may not care about nsLineBreaker.
// Note that because we didn't break, we can be sure that (thanks to the
// code up above) textMetrics.mAdvanceWidth includes the width of any
// trailing whitespace. So we need to subtract trimmableWidth here
// because if we did break at this point, that much width would be
// trimmed.
if (textMetrics.mAdvanceWidth - trimmableWidth > availWidth) {
breakAfter = true;
} else {
aLineLayout.NotifyOptionalBreakPosition(this, length, true,
gfxBreakPriority::eNormalBreak);
}
}
}
// Compute reflow status
@@ -8650,7 +8743,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
if (!textStyle->WhiteSpaceIsSignificant() &&
(lineContainer->StyleText()->mTextAlign == NS_STYLE_TEXT_ALIGN_JUSTIFY ||
lineContainer->StyleText()->mTextAlignLast == NS_STYLE_TEXT_ALIGN_JUSTIFY ||
ShouldSuppressLineBreak()) &&
shouldSuppressLineBreak) &&
!lineContainer->IsSVGText()) {
AddStateBits(TEXT_JUSTIFICATION_ENABLED);
provider.ComputeJustification(offset, charsFit);
@@ -8754,7 +8847,7 @@ nsTextFrame::TrimTrailingWhiteSpace(nsRenderingContext* aRC)
}
nsOverflowAreas
nsTextFrame::RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState)
nsTextFrame::RecomputeOverflow(nsIFrame* aBlockFrame)
{
nsRect bounds(nsPoint(0, 0), GetSize());
nsOverflowAreas result(bounds, bounds);
@@ -8772,10 +8865,10 @@ nsTextFrame::RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState)
ComputeTransformedLength(provider),
gfxFont::LOOSE_INK_EXTENTS, nullptr,
&provider);
nsRect boundingBox = RoundOut(textMetrics.mBoundingBox);
if (GetWritingMode().IsLineInverted()) {
boundingBox.y = -boundingBox.YMost();
textMetrics.mBoundingBox.y = -textMetrics.mBoundingBox.YMost();
}
nsRect boundingBox = RoundOut(textMetrics.mBoundingBox);
boundingBox += nsPoint(0, mAscent);
if (mTextRun->IsVertical()) {
// Swap line-relative textMetrics dimensions to physical coordinates.
@@ -8784,8 +8877,7 @@ nsTextFrame::RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState)
}
nsRect &vis = result.VisualOverflow();
vis.UnionRect(vis, boundingBox);
UnionAdditionalOverflow(PresContext(), aBlockReflowState.frame, provider,
&vis, true);
UnionAdditionalOverflow(PresContext(), aBlockFrame, provider, &vis, true);
return result;
}
@@ -9159,18 +9251,9 @@ nsTextFrame::HasAnyNoncollapsedCharacters()
bool
nsTextFrame::UpdateOverflow()
{
const nsRect rect(nsPoint(0, 0), GetSize());
nsOverflowAreas overflowAreas(rect, rect);
if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
return false;
}
gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
if (!mTextRun) {
return false;
}
PropertyProvider provider(this, iter, nsTextFrame::eInflated);
provider.InitializeForDisplay(true);
nsIFrame* decorationsBlock;
if (IsFloatingFirstLetterChild()) {
@@ -9192,8 +9275,8 @@ nsTextFrame::UpdateOverflow()
}
}
UnionAdditionalOverflow(PresContext(), decorationsBlock, provider,
&overflowAreas.VisualOverflow(), true);
nsOverflowAreas overflowAreas = RecomputeOverflow(decorationsBlock);
return FinishAndStoreOverflow(overflowAreas, GetSize());
}
+71 -2
View File
@@ -7,6 +7,7 @@
#define nsTextFrame_h__
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/gfx/2D.h"
#include "nsFrame.h"
#include "nsGenericDOMDataNode.h"
@@ -40,6 +41,7 @@ public:
};
class nsTextFrame : public nsTextFrameBase {
typedef mozilla::TextRangeStyle TextRangeStyle;
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Rect Rect;
@@ -281,8 +283,7 @@ public:
TextOffsetType aOffsetType =
TextOffsetType::OFFSETS_IN_CONTENT_TEXT) override;
nsOverflowAreas
RecomputeOverflow(const nsHTMLReflowState& aBlockReflowState);
nsOverflowAreas RecomputeOverflow(nsIFrame* aBlockFrame);
enum TextRunType {
// Anything in reflow (but not intrinsic width calculation) or
@@ -745,6 +746,74 @@ protected:
bool CombineSelectionUnderlineRect(nsPresContext* aPresContext,
nsRect& aRect);
/**
* Utility methods to paint selection.
*/
void DrawSelectionDecorations(gfxContext* aContext,
const gfxRect& aDirtyRect,
SelectionType aType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
const gfxPoint& aPt,
gfxFloat aICoordInFrame,
gfxFloat aWidth,
gfxFloat aAscent,
const gfxFont::Metrics& aFontMetrics,
DrawPathCallbacks* aCallbacks,
bool aVertical,
uint8_t aDecoration);
enum DecorationType
{
eNormalDecoration,
eSelectionDecoration
};
void PaintDecorationLine(gfxContext* const aCtx,
const gfxRect& aDirtyRect,
nscolor aColor,
const nscolor* aOverrideColor,
const gfxPoint& aPt,
gfxFloat aICoordInFrame,
const gfxSize& aLineSize,
gfxFloat aAscent,
gfxFloat aOffset,
uint8_t aDecoration,
uint8_t aStyle,
DecorationType aDecorationType,
DrawPathCallbacks* aCallbacks,
bool aVertical,
gfxFloat aDescentLimit = -1.0);
/**
* ComputeDescentLimitForSelectionUnderline() computes the most far position
* where we can put selection underline.
*
* @return The maximum underline offset from the baseline (positive value
* means that the underline can put below the baseline).
*/
gfxFloat ComputeDescentLimitForSelectionUnderline(
nsPresContext* aPresContext,
const gfxFont::Metrics& aFontMetrics);
/**
* This function encapsulates all knowledge of how selections affect
* foreground and background colors.
* @param aForeground the foreground color to use
* @param aBackground the background color to use, or RGBA(0,0,0,0) if no
* background should be painted
* @return true if the selection affects colors, false otherwise
*/
static bool GetSelectionTextColors(SelectionType aType,
nsTextPaintStyle& aTextPaintStyle,
const TextRangeStyle &aRangeStyle,
nscolor* aForeground,
nscolor* aBackground);
/**
* ComputeSelectionUnderlineHeight() computes selection underline height of
* the specified selection type from the font metrics.
*/
static gfxFloat ComputeSelectionUnderlineHeight(
nsPresContext* aPresContext,
const gfxFont::Metrics& aFontMetrics,
SelectionType aSelectionType);
ContentOffsets GetCharacterOffsetAtFramePointInternal(nsPoint aPoint,
bool aForInsertionPoint);
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bug 1186720 - Line break suppression with soft hyphen</title>
</head>
<body style="width: 1px">
x<ruby>a</ruby>
</body>
</html>
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bug 1186720 - Line break suppression with soft hyphen</title>
</head>
<body style="width: 1px">
x<ruby>a&shy;</ruby>
</body>
</html>
+1
View File
@@ -30,6 +30,7 @@ test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLin
== line-break-suppression-2.html line-break-suppression-2-ref.html
== line-break-suppression-3.html line-break-suppression-3-ref.html
== line-break-suppression-4.html line-break-suppression-4-ref.html
== line-break-suppression-5.html line-break-suppression-5-ref.html
== line-height-1.html line-height-1-ref.html
== line-height-2.html line-height-2-ref.html
== line-height-3.html line-height-3-ref.html
@@ -1 +1,2 @@
pref(layout.css.ruby.enabled,true) == ruby-text-decoration-01.html ruby-text-decoration-01-ref.html
== text-decoration-propagation-01.html text-decoration-propagation-01-ref.html
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Test Reference</title>
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
<span>
<svg width="400" height="100">
<text x="10" y="30">This text must not be underlined.</text>
</svg>
</span>
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Test: text-decoration shouldn't propagate through 'svg' element</title>
<link rel="author" title="Cameron McCormack" href="mailto:cam@mcc.id.au">
<link rel="help" href="http://www.w3.org/TR/css-text-decor-3/#line-decoration">
<link rel="match" href="text-decoration-propagation-01-ref.html">
<meta name="assert" content="An outer 'svg' element is an atomic inline-axis element, so text decorations must not propagate through it.">
<style>
span { text-decoration: underline; }
</style>
<span>
<svg width="400" height="100">
<text x="10" y="30">This text must not be underlined.</text>
</svg>
</span>
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1175789 - underline and overline in various language</title>
<style type="text/css">
body {
font-family: "Arial", "Helvetica", "sans-serif";
}
div {
padding: .5em 1em;
line-height: 2em;
}
.underline {
text-decoration: underline;
}
.overline {
text-decoration: overline;
}
</style>
</head>
<body>
<dl>
<dt>lang="en-US"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ja"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="ko"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="ja-JP"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="ko-KR"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="overline">underline</span><br>
<span class="underline">overline</span>
</div>
</dd>
<dt>lang="zh"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
</dl>
</body>
</html>
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
<head>
<title>Bug 1175789 - underline and overline in various language</title>
<style type="text/css">
body {
font-family: "Arial", "Helvetica", "sans-serif";
}
div {
padding: .5em 1em;
line-height: 2em;
}
.underline {
text-decoration: underline;
}
.overline {
text-decoration: overline;
}
</style>
</head>
<body>
<dl>
<dt>lang="en-US"</dt>
<dd lang="en-US">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ja"</dt>
<dd lang="ja">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ko"</dt>
<dd lang="ko">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ja-JP"</dt>
<dd lang="ja-JP">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="ko-KR"</dt>
<dd lang="ko-KR">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
<dt>lang="zh"</dt>
<dd lang="zh">
<div style="writing-mode: vertical-rl;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
<div style="writing-mode: vertical-lr;">
<span class="underline">underline</span><br>
<span class="overline">overline</span>
</div>
</dd>
</dl>
</body>
</html>
@@ -149,6 +149,7 @@ test-pref(dom.meta-viewport.enabled,true) test-pref(font.size.inflation.emPerLin
== 1172774-percent-padding-3.html 1172774-percent-vertical-ref.html
== 1172774-percent-padding-4.html 1172774-percent-vertical-ref.html
== 1174450-intrinsic-sizing.html 1174450-intrinsic-sizing-ref.html
== 1175789-underline-overline-1.html 1175789-underline-overline-1-ref.html
# Suite of tests from Gérard Talbot in bug 1079151
include abspos/reftest.list
+11 -11
View File
@@ -39,8 +39,8 @@ GetEventMessageName(EventMessage aMessage)
return "NS_COMPOSITION_COMMIT_AS_IS";
case NS_COMPOSITION_COMMIT:
return "NS_COMPOSITION_COMMIT";
case NS_SELECTION_SET:
return "NS_SELECTION_SET";
case eSetSelection:
return "eSetSelection";
default:
return "unacceptable event message";
}
@@ -177,7 +177,7 @@ ContentCacheInChild::CacheSelection(nsIWidget* aWidget,
mSelection.Clear();
nsEventStatus status = nsEventStatus_eIgnore;
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, aWidget);
WidgetQueryContentEvent selection(true, eQuerySelectedText, aWidget);
aWidget->DispatchEvent(&selection, status);
if (NS_WARN_IF(!selection.mSucceeded)) {
MOZ_LOG(sContentCacheLog, LogLevel::Error,
@@ -219,7 +219,7 @@ ContentCacheInChild::CacheCaret(nsIWidget* aWidget,
mCaret.mOffset = mSelection.StartOffset();
nsEventStatus status = nsEventStatus_eIgnore;
WidgetQueryContentEvent caretRect(true, NS_QUERY_CARET_RECT, aWidget);
WidgetQueryContentEvent caretRect(true, eQueryCaretRect, aWidget);
caretRect.InitForQueryCaretRect(mCaret.mOffset);
aWidget->DispatchEvent(&caretRect, status);
if (NS_WARN_IF(!caretRect.mSucceeded)) {
@@ -276,7 +276,7 @@ ContentCacheInChild::CacheText(nsIWidget* aWidget,
this, aWidget, GetNotificationName(aNotification)));
nsEventStatus status = nsEventStatus_eIgnore;
WidgetQueryContentEvent queryText(true, NS_QUERY_TEXT_CONTENT, aWidget);
WidgetQueryContentEvent queryText(true, eQueryTextContent, aWidget);
queryText.InitForQueryTextContent(0, UINT32_MAX);
aWidget->DispatchEvent(&queryText, status);
if (NS_WARN_IF(!queryText.mSucceeded)) {
@@ -516,10 +516,10 @@ ContentCacheInParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent,
aEvent.mReply.mFocusedWidget = aWidget;
switch (aEvent.mMessage) {
case NS_QUERY_SELECTED_TEXT:
case eQuerySelectedText:
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("ContentCacheInParent: 0x%p HandleQueryContentEvent("
"aEvent={ mMessage=NS_QUERY_SELECTED_TEXT }, aWidget=0x%p)",
"aEvent={ mMessage=eQuerySelectedText }, aWidget=0x%p)",
this, aWidget));
if (NS_WARN_IF(!IsSelectionValid())) {
// If content cache hasn't been initialized properly, make the query
@@ -557,10 +557,10 @@ ContentCacheInParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent,
GetBoolName(aEvent.mReply.mHasSelection),
GetWritingModeName(aEvent.mReply.mWritingMode).get()));
break;
case NS_QUERY_TEXT_CONTENT: {
case eQueryTextContent: {
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("ContentCacheInParent: 0x%p HandleQueryContentEvent("
"aEvent={ mMessage=NS_QUERY_TEXT_CONTENT, mInput={ mOffset=%u, "
"aEvent={ mMessage=eQueryTextContent, mInput={ mOffset=%u, "
"mLength=%u } }, aWidget=0x%p), mText.Length()=%u",
this, aEvent.mInput.mOffset,
aEvent.mInput.mLength, aWidget, mText.Length()));
@@ -638,10 +638,10 @@ ContentCacheInParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent,
GetWritingModeName(aEvent.mReply.mWritingMode).get(),
GetRectText(aEvent.mReply.mRect).get()));
break;
case NS_QUERY_CARET_RECT:
case eQueryCaretRect:
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("ContentCacheInParent: 0x%p HandleQueryContentEvent("
"aEvent={ mMessage=NS_QUERY_CARET_RECT, mInput={ mOffset=%u } }, "
"aEvent={ mMessage=eQueryCaretRect, mInput={ mOffset=%u } }, "
"aWidget=0x%p), mText.Length()=%u",
this, aEvent.mInput.mOffset, aWidget, mText.Length()));
if (NS_WARN_IF(!IsSelectionValid())) {
+4 -4
View File
@@ -282,13 +282,13 @@ public:
/**
* HandleQueryContentEvent() sets content data to aEvent.mReply.
*
* For NS_QUERY_SELECTED_TEXT, fail if the cache doesn't contain the whole
* For eQuerySelectedText, fail if the cache doesn't contain the whole
* selected range. (This shouldn't happen because PuppetWidget should have
* already sent the whole selection.)
*
* For NS_QUERY_TEXT_CONTENT, fail only if the cache doesn't overlap with
* For eQueryTextContent, fail only if the cache doesn't overlap with
* the queried range. Note the difference from above. We use
* this behavior because a normal NS_QUERY_TEXT_CONTENT event is allowed to
* this behavior because a normal eQueryTextContent event is allowed to
* have out-of-bounds offsets, so that widget can request content without
* knowing the exact length of text. It's up to widget to handle cases when
* the returned offset/length are different from the queried offset/length.
@@ -296,7 +296,7 @@ public:
* For NS_QUERY_TEXT_RECT, fail if cached offset/length aren't equals to input.
* Cocoa widget always queries selected offset, so it works on it.
*
* For NS_QUERY_CARET_RECT, fail if cached offset isn't equals to input
* For eQueryCaretRect, fail if cached offset isn't equals to input
*
* For NS_QUERY_EDITOR_RECT, always success
*/
+15 -15
View File
@@ -123,10 +123,10 @@ NS_EVENT_MESSAGE(eXULPopupHidden, eXULEventFirst + 3)
NS_EVENT_MESSAGE(eXULBroadcast, eXULEventFirst + 5)
NS_EVENT_MESSAGE(eXULCommandUpdate, eXULEventFirst + 6)
// Scroll events
NS_EVENT_MESSAGE(NS_MOUSE_SCROLL_START, 1600)
NS_EVENT_MESSAGE(NS_MOUSE_SCROLL, NS_MOUSE_SCROLL_START)
NS_EVENT_MESSAGE(NS_MOUSE_PIXEL_SCROLL, NS_MOUSE_SCROLL_START + 1)
// Legacy mouse scroll (wheel) events
NS_EVENT_MESSAGE(eLegacyMouseScrollEventFirst, 1600)
NS_EVENT_MESSAGE(eLegacyMouseLineOrPageScroll, eLegacyMouseScrollEventFirst)
NS_EVENT_MESSAGE(eLegacyMousePixelScroll, eLegacyMouseScrollEventFirst + 1)
NS_EVENT_MESSAGE(NS_SCROLLPORT_START, 1700)
NS_EVENT_MESSAGE(NS_SCROLLPORT_UNDERFLOW, NS_SCROLLPORT_START)
@@ -212,36 +212,36 @@ NS_EVENT_MESSAGE(eCut, eClipboardEventFirst + 1)
NS_EVENT_MESSAGE(ePaste, eClipboardEventFirst + 2)
// Query the content information
NS_EVENT_MESSAGE(NS_QUERY_CONTENT_EVENT_START, 3200)
NS_EVENT_MESSAGE(eQueryContentEventFirst, 3200)
// Query for the selected text information, it return the selection offset,
// selection length and selected text.
NS_EVENT_MESSAGE(NS_QUERY_SELECTED_TEXT, NS_QUERY_CONTENT_EVENT_START)
NS_EVENT_MESSAGE(eQuerySelectedText, eQueryContentEventFirst)
// Query for the text content of specified range, it returns actual lengh (if
// the specified range is too long) and the text of the specified range.
// Returns the entire text if requested length > actual length.
NS_EVENT_MESSAGE(NS_QUERY_TEXT_CONTENT, NS_QUERY_CONTENT_EVENT_START + 1)
NS_EVENT_MESSAGE(eQueryTextContent, eQueryContentEventFirst + 1)
// Query for the caret rect of nth insertion point. The offset of the result is
// relative position from the top level widget.
NS_EVENT_MESSAGE(NS_QUERY_CARET_RECT, NS_QUERY_CONTENT_EVENT_START + 3)
NS_EVENT_MESSAGE(eQueryCaretRect, eQueryContentEventFirst + 3)
// Query for the bounding rect of a range of characters. This works on any
// valid character range given offset and length. Result is relative to top
// level widget coordinates
NS_EVENT_MESSAGE(NS_QUERY_TEXT_RECT, NS_QUERY_CONTENT_EVENT_START + 4)
NS_EVENT_MESSAGE(NS_QUERY_TEXT_RECT, eQueryContentEventFirst + 4)
// Query for the bounding rect of the current focused frame. Result is relative
// to top level widget coordinates
NS_EVENT_MESSAGE(NS_QUERY_EDITOR_RECT, NS_QUERY_CONTENT_EVENT_START + 5)
NS_EVENT_MESSAGE(NS_QUERY_EDITOR_RECT, eQueryContentEventFirst + 5)
// Query for the current state of the content. The particular members of
// mReply that are set for each query content event will be valid on success.
NS_EVENT_MESSAGE(NS_QUERY_CONTENT_STATE, NS_QUERY_CONTENT_EVENT_START + 6)
NS_EVENT_MESSAGE(NS_QUERY_CONTENT_STATE, eQueryContentEventFirst + 6)
// Query for the selection in the form of a nsITransferable.
NS_EVENT_MESSAGE(NS_QUERY_SELECTION_AS_TRANSFERABLE, NS_QUERY_CONTENT_EVENT_START + 7)
NS_EVENT_MESSAGE(eQuerySelectionAsTransferable, eQueryContentEventFirst + 7)
// Query for character at a point. This returns the character offset, its
// rect and also tentative caret point if the point is clicked. The point is
// specified by Event::refPoint.
NS_EVENT_MESSAGE(NS_QUERY_CHARACTER_AT_POINT, NS_QUERY_CONTENT_EVENT_START + 8)
NS_EVENT_MESSAGE(NS_QUERY_CHARACTER_AT_POINT, eQueryContentEventFirst + 8)
// Query if the DOM element under Event::refPoint belongs to our widget
// or not.
NS_EVENT_MESSAGE(NS_QUERY_DOM_WIDGET_HITTEST, NS_QUERY_CONTENT_EVENT_START + 9)
NS_EVENT_MESSAGE(NS_QUERY_DOM_WIDGET_HITTEST, eQueryContentEventFirst + 9)
// Video events
NS_EVENT_MESSAGE(eMediaEventFirst, 3300)
@@ -295,7 +295,7 @@ NS_EVENT_MESSAGE(ePluginInputEvent, ePluginEventFirst)
// Events to manipulate selection (WidgetSelectionEvent)
NS_EVENT_MESSAGE(eSelectionEventFirst, 3700)
// Clear any previous selection and set the given range as the selection
NS_EVENT_MESSAGE(NS_SELECTION_SET, eSelectionEventFirst)
NS_EVENT_MESSAGE(eSetSelection, eSelectionEventFirst)
// Events of commands for the contents
NS_EVENT_MESSAGE(NS_CONTENT_COMMAND_EVENT_START, 3800)
+10 -9
View File
@@ -399,11 +399,11 @@ public:
}
// The delta value of mouse scroll event.
// If the event message is NS_MOUSE_SCROLL, the value indicates scroll amount
// in lines. However, if the value is nsIDOMUIEvent::SCROLL_PAGE_UP or
// nsIDOMUIEvent::SCROLL_PAGE_DOWN, the value inducates one page scroll.
// If the event message is NS_MOUSE_PIXEL_SCROLL, the value indicates scroll
// amount in pixels.
// If the event message is eLegacyMouseLineOrPageScroll, the value indicates
// scroll amount in lines. However, if the value is
// nsIDOMUIEvent::SCROLL_PAGE_UP or nsIDOMUIEvent::SCROLL_PAGE_DOWN, the
// value inducates one page scroll. If the event message is
// eLegacyMousePixelScroll, the value indicates scroll amount in pixels.
int32_t delta;
// If this is true, it may cause to scroll horizontally.
@@ -499,13 +499,14 @@ public:
// If device event handlers don't know when they should set lineOrPageDeltaX
// and lineOrPageDeltaY, this is true. Otherwise, false.
// If mIsNoLineOrPageDelta is true, ESM will generate NS_MOUSE_SCROLL events
// when accumulated delta values reach a line height.
// If mIsNoLineOrPageDelta is true, ESM will generate
// eLegacyMouseLineOrPageScroll events when accumulated delta values reach
// a line height.
bool mIsNoLineOrPageDelta;
// If widget sets lineOrPageDelta, EventStateManager will dispatch
// NS_MOUSE_SCROLL event for compatibility. Note that the delta value means
// pages if the deltaMode is DOM_DELTA_PAGE, otherwise, lines.
// eLegacyMouseLineOrPageScroll event for compatibility. Note that the delta
// value means pages if the deltaMode is DOM_DELTA_PAGE, otherwise, lines.
int32_t lineOrPageDeltaX;
int32_t lineOrPageDeltaY;
+9 -9
View File
@@ -495,7 +495,7 @@ public:
void InitForQueryTextContent(uint32_t aOffset, uint32_t aLength,
bool aUseNativeLineBreak = true)
{
NS_ASSERTION(mMessage == NS_QUERY_TEXT_CONTENT,
NS_ASSERTION(mMessage == eQueryTextContent,
"wrong initializer is called");
mInput.mOffset = aOffset;
mInput.mLength = aLength;
@@ -505,7 +505,7 @@ public:
void InitForQueryCaretRect(uint32_t aOffset,
bool aUseNativeLineBreak = true)
{
NS_ASSERTION(mMessage == NS_QUERY_CARET_RECT,
NS_ASSERTION(mMessage == eQueryCaretRect,
"wrong initializer is called");
mInput.mOffset = aOffset;
mUseNativeLineBreak = aUseNativeLineBreak;
@@ -530,29 +530,29 @@ public:
void RequestFontRanges()
{
NS_ASSERTION(mMessage == NS_QUERY_TEXT_CONTENT,
NS_ASSERTION(mMessage == eQueryTextContent,
"not querying text content");
mWithFontRanges = true;
}
uint32_t GetSelectionStart(void) const
{
NS_ASSERTION(mMessage == NS_QUERY_SELECTED_TEXT,
NS_ASSERTION(mMessage == eQuerySelectedText,
"not querying selection");
return mReply.mOffset + (mReply.mReversed ? mReply.mString.Length() : 0);
}
uint32_t GetSelectionEnd(void) const
{
NS_ASSERTION(mMessage == NS_QUERY_SELECTED_TEXT,
NS_ASSERTION(mMessage == eQuerySelectedText,
"not querying selection");
return mReply.mOffset + (mReply.mReversed ? 0 : mReply.mString.Length());
}
mozilla::WritingMode GetWritingMode(void) const
{
NS_ASSERTION(mMessage == NS_QUERY_SELECTED_TEXT ||
mMessage == NS_QUERY_CARET_RECT ||
NS_ASSERTION(mMessage == eQuerySelectedText ||
mMessage == eQueryCaretRect ||
mMessage == NS_QUERY_TEXT_RECT,
"not querying selection or text rect");
return mReply.mWritingMode;
@@ -593,9 +593,9 @@ public:
bool mWidgetIsHit;
// mozilla::WritingMode value at the end (focus) of the selection
mozilla::WritingMode mWritingMode;
// used by NS_QUERY_SELECTION_AS_TRANSFERABLE
// Used by eQuerySelectionAsTransferable
nsCOMPtr<nsITransferable> mTransferable;
// used by NS_QUERY_TEXT_CONTENT with font ranges requested
// Used by eQueryTextContent with font ranges requested
nsAutoTArray<mozilla::FontRange, 1> mFontRanges;
} mReply;
+1 -1
View File
@@ -356,7 +356,7 @@ public:
bool DispatchEvent(WidgetGUIEvent& aEvent);
/**
* SetSelection() dispatches NS_SELECTION_SET event for the aRange.
* SetSelection() dispatches eSetSelection event for the aRange.
*
* @param aRange The range which will be selected.
* @return TRUE if setting selection is succeeded and
+5 -5
View File
@@ -2969,7 +2969,7 @@ IMEInputHandler::ConversationIdentifier()
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
// NOTE: The size of NSInteger is same as pointer size.
WidgetQueryContentEvent textContent(true, NS_QUERY_TEXT_CONTENT, mWidget);
WidgetQueryContentEvent textContent(true, eQueryTextContent, mWidget);
textContent.InitForQueryTextContent(0, 0);
DispatchEvent(textContent);
if (!textContent.mSucceeded) {
@@ -3005,7 +3005,7 @@ IMEInputHandler::GetAttributedSubstringFromRange(NSRange& aRange,
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
nsAutoString str;
WidgetQueryContentEvent textContent(true, NS_QUERY_TEXT_CONTENT, mWidget);
WidgetQueryContentEvent textContent(true, eQueryTextContent, mWidget);
textContent.InitForQueryTextContent(aRange.location, aRange.length);
textContent.RequestFontRanges();
DispatchEvent(textContent);
@@ -3098,7 +3098,7 @@ IMEInputHandler::SelectedRange()
nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, mWidget);
WidgetQueryContentEvent selection(true, eQuerySelectedText, mWidget);
DispatchEvent(selection);
MOZ_LOG(gLog, LogLevel::Info,
@@ -3202,7 +3202,7 @@ IMEInputHandler::FirstRectForCharacterRange(NSRange& aRange,
}
if (useCaretRect) {
WidgetQueryContentEvent caretRect(true, NS_QUERY_CARET_RECT, mWidget);
WidgetQueryContentEvent caretRect(true, eQueryCaretRect, mWidget);
caretRect.InitForQueryCaretRect(aRange.location);
DispatchEvent(caretRect);
if (!caretRect.mSucceeded) {
@@ -3978,7 +3978,7 @@ TextInputHandlerBase::SetSelection(NSRange& aRange)
MOZ_ASSERT(!Destroyed());
nsRefPtr<TextInputHandlerBase> kungFuDeathGrip(this);
WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, mWidget);
WidgetSelectionEvent selectionEvent(true, eSetSelection, mWidget);
selectionEvent.mOffset = aRange.location;
selectionEvent.mLength = aRange.length;
selectionEvent.mReversed = false;
+3 -4
View File
@@ -1829,7 +1829,7 @@ nsChildView::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
// the physical direction of the arrow.
if (aEvent.keyCode >= nsIDOMKeyEvent::DOM_VK_LEFT &&
aEvent.keyCode <= nsIDOMKeyEvent::DOM_VK_DOWN) {
WidgetQueryContentEvent query(true, NS_QUERY_SELECTED_TEXT, this);
WidgetQueryContentEvent query(true, eQuerySelectedText, this);
DispatchWindowEvent(query);
if (query.mSucceeded && query.mReply.mWritingMode.IsVertical()) {
@@ -1915,7 +1915,7 @@ NSView<mozView>* nsChildView::GetEditorView()
// We need to get editor's view. E.g., when the focus is in the bookmark
// dialog, the view is <panel> element of the dialog. At this time, the key
// events are processed the parent window's view that has native focus.
WidgetQueryContentEvent textContent(true, NS_QUERY_TEXT_CONTENT, this);
WidgetQueryContentEvent textContent(true, eQueryTextContent, this);
textContent.InitForQueryTextContent(0, 0);
DispatchWindowEvent(textContent);
if (textContent.mSucceeded && textContent.mReply.mFocusedWidget) {
@@ -6080,8 +6080,7 @@ PanGestureTypeForEvent(NSEvent* aEvent)
return NO;
// Obtain the current selection.
WidgetQueryContentEvent event(true,
NS_QUERY_SELECTION_AS_TRANSFERABLE,
WidgetQueryContentEvent event(true, eQuerySelectionAsTransferable,
mGeckoChild);
mGeckoChild->DispatchWindowEvent(event);
if (!event.mSucceeded || !event.mReply.mTransferable)
+329 -92
View File
@@ -94,6 +94,80 @@ public:
virtual ~GetWritingModeName() {}
};
class GetTextRangeStyleText final : public nsAutoCString
{
public:
explicit GetTextRangeStyleText(const TextRangeStyle& aStyle)
{
if (!aStyle.IsDefined()) {
AssignLiteral("{ IsDefined()=false }");
return;
}
if (aStyle.IsLineStyleDefined()) {
AppendLiteral("{ mLineStyle=");
AppendLineStyle(aStyle.mLineStyle);
if (aStyle.IsUnderlineColorDefined()) {
AppendLiteral(", mUnderlineColor=");
AppendColor(aStyle.mUnderlineColor);
} else {
AppendLiteral(", IsUnderlineColorDefined=false");
}
} else {
AppendLiteral("{ IsLineStyleDefined()=false");
}
if (aStyle.IsForegroundColorDefined()) {
AppendLiteral(", mForegroundColor=");
AppendColor(aStyle.mForegroundColor);
} else {
AppendLiteral(", IsForegroundColorDefined()=false");
}
if (aStyle.IsBackgroundColorDefined()) {
AppendLiteral(", mBackgroundColor=");
AppendColor(aStyle.mBackgroundColor);
} else {
AppendLiteral(", IsBackgroundColorDefined()=false");
}
AppendLiteral(" }");
}
void AppendLineStyle(uint8_t aLineStyle)
{
switch (aLineStyle) {
case TextRangeStyle::LINESTYLE_NONE:
AppendLiteral("LINESTYLE_NONE");
break;
case TextRangeStyle::LINESTYLE_SOLID:
AppendLiteral("LINESTYLE_SOLID");
break;
case TextRangeStyle::LINESTYLE_DOTTED:
AppendLiteral("LINESTYLE_DOTTED");
break;
case TextRangeStyle::LINESTYLE_DASHED:
AppendLiteral("LINESTYLE_DASHED");
break;
case TextRangeStyle::LINESTYLE_DOUBLE:
AppendLiteral("LINESTYLE_DOUBLE");
break;
case TextRangeStyle::LINESTYLE_WAVY:
AppendLiteral("LINESTYLE_WAVY");
break;
default:
AppendPrintf("Invalid(0x%02X)", aLineStyle);
break;
}
}
void AppendColor(nscolor aColor)
{
AppendPrintf("{ R=0x%02X, G=0x%02X, B=0x%02X, A=0x%02X }",
NS_GET_R(aColor), NS_GET_G(aColor), NS_GET_B(aColor),
NS_GET_A(aColor));
}
virtual ~GetTextRangeStyleText() {};
};
const static bool kUseSimpleContextDefault = MOZ_WIDGET_GTK == 2;
/******************************************************************************
@@ -1397,21 +1471,21 @@ IMContextWrapper::DispatchCompositionCommitEvent(
already_AddRefed<TextRangeArray>
IMContextWrapper::CreateTextRangeArray(GtkIMContext* aContext,
const nsAString& aLastDispatchedData)
const nsAString& aCompositionString)
{
MOZ_LOG(gGtkIMLog, LogLevel::Info,
("GTKIM: %p CreateTextRangeArray(aContext=%p, "
"aLastDispatchedData=\"%s\" (Length()=%u))",
this, aContext, NS_ConvertUTF16toUTF8(aLastDispatchedData).get(),
aLastDispatchedData.Length()));
"aCompositionString=\"%s\" (Length()=%u))",
this, aContext, NS_ConvertUTF16toUTF8(aCompositionString).get(),
aCompositionString.Length()));
nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray();
gchar *preedit_string;
gint cursor_pos;
gint cursor_pos_in_chars;
PangoAttrList *feedback_list;
gtk_im_context_get_preedit_string(aContext, &preedit_string,
&feedback_list, &cursor_pos);
&feedback_list, &cursor_pos_in_chars);
if (!preedit_string || !*preedit_string) {
MOZ_LOG(gGtkIMLog, LogLevel::Error,
("GTKIM: %p CreateTextRangeArray(), FAILED, due to "
@@ -1422,6 +1496,53 @@ IMContextWrapper::CreateTextRangeArray(GtkIMContext* aContext,
return textRangeArray.forget();
}
// Convert caret offset from offset in characters to offset in UTF-16
// string. If we couldn't proper offset in UTF-16 string, we should
// assume that the caret is at the end of the composition string.
uint32_t caretOffsetInUTF16 = aCompositionString.Length();
if (NS_WARN_IF(cursor_pos_in_chars < 0)) {
// Note that this case is undocumented. We should assume that the
// caret is at the end of the composition string.
} else if (cursor_pos_in_chars == 0) {
caretOffsetInUTF16 = 0;
} else {
gchar* charAfterCaret =
g_utf8_offset_to_pointer(preedit_string, cursor_pos_in_chars);
if (NS_WARN_IF(!charAfterCaret)) {
MOZ_LOG(gGtkIMLog, LogLevel::Warning,
("GTKIM: %p CreateTextRangeArray(), failed to get UTF-8 "
"string before the caret (cursor_pos_in_chars=%d)",
this, cursor_pos_in_chars));
} else {
glong caretOffset = 0;
gunichar2* utf16StrBeforeCaret =
g_utf8_to_utf16(preedit_string, charAfterCaret - preedit_string,
nullptr, &caretOffset, nullptr);
if (NS_WARN_IF(!utf16StrBeforeCaret) ||
NS_WARN_IF(caretOffset < 0)) {
MOZ_LOG(gGtkIMLog, LogLevel::Warning,
("GTKIM: %p CreateTextRangeArray(), WARNING, failed to "
"convert to UTF-16 string before the caret "
"(cursor_pos_in_chars=%d, caretOffset=%d)",
this, cursor_pos_in_chars, caretOffset));
} else {
caretOffsetInUTF16 = static_cast<uint32_t>(caretOffset);
uint32_t compositionStringLength = aCompositionString.Length();
if (NS_WARN_IF(caretOffsetInUTF16 > compositionStringLength)) {
MOZ_LOG(gGtkIMLog, LogLevel::Warning,
("GTKIM: %p CreateTextRangeArray(), WARNING, "
"caretOffsetInUTF16=%u is larger than "
"compositionStringLength=%u",
this, caretOffsetInUTF16, compositionStringLength));
caretOffsetInUTF16 = compositionStringLength;
}
}
if (utf16StrBeforeCaret) {
g_free(utf16StrBeforeCaret);
}
}
}
PangoAttrIterator* iter;
iter = pango_attr_list_get_iterator(feedback_list);
if (!iter) {
@@ -1434,93 +1555,21 @@ IMContextWrapper::CreateTextRangeArray(GtkIMContext* aContext,
return textRangeArray.forget();
}
/*
* Depend on gtk2's implementation on XIM support.
* In aFeedback got from gtk2, there are only three types of data:
* PANGO_ATTR_UNDERLINE, PANGO_ATTR_FOREGROUND, PANGO_ATTR_BACKGROUND.
* Corresponding to XIMUnderline, XIMReverse.
* Don't take PANGO_ATTR_BACKGROUND into account, since
* PANGO_ATTR_BACKGROUND and PANGO_ATTR_FOREGROUND are always
* a couple.
*/
do {
PangoAttribute* attrUnderline =
pango_attr_iterator_get(iter, PANGO_ATTR_UNDERLINE);
PangoAttribute* attrForeground =
pango_attr_iterator_get(iter, PANGO_ATTR_FOREGROUND);
if (!attrUnderline && !attrForeground) {
TextRange range;
if (!SetTextRange(iter, preedit_string, caretOffsetInUTF16, range)) {
continue;
}
// Get the range of the current attribute(s)
gint start, end;
pango_attr_iterator_range(iter, &start, &end);
TextRange range;
// XIMReverse | XIMUnderline
if (attrUnderline && attrForeground) {
range.mRangeType = NS_TEXTRANGE_SELECTEDCONVERTEDTEXT;
}
// XIMUnderline
else if (attrUnderline) {
range.mRangeType = NS_TEXTRANGE_CONVERTEDTEXT;
}
// XIMReverse
else if (attrForeground) {
range.mRangeType = NS_TEXTRANGE_SELECTEDRAWTEXT;
} else {
range.mRangeType = NS_TEXTRANGE_RAWINPUT;
}
gunichar2* uniStr = nullptr;
if (start == 0) {
range.mStartOffset = 0;
} else {
glong uniStrLen;
uniStr = g_utf8_to_utf16(preedit_string, start,
nullptr, &uniStrLen, nullptr);
if (uniStr) {
range.mStartOffset = uniStrLen;
g_free(uniStr);
uniStr = nullptr;
}
}
glong uniStrLen;
uniStr = g_utf8_to_utf16(preedit_string + start, end - start,
nullptr, &uniStrLen, nullptr);
if (!uniStr) {
range.mEndOffset = range.mStartOffset;
} else {
range.mEndOffset = range.mStartOffset + uniStrLen;
g_free(uniStr);
uniStr = nullptr;
}
textRangeArray->AppendElement(range);
MOZ_LOG(gGtkIMLog, LogLevel::Debug,
("GTKIM: %p CreateTextRangeArray(), mStartOffset=%u, "
"mEndOffset=%u, mRangeType=%s",
this, range.mStartOffset, range.mEndOffset,
GetRangeTypeName(range.mRangeType)));
} while (pango_attr_iterator_next(iter));
TextRange range;
if (cursor_pos < 0) {
range.mStartOffset = 0;
} else if (uint32_t(cursor_pos) > aLastDispatchedData.Length()) {
range.mStartOffset = aLastDispatchedData.Length();
} else {
range.mStartOffset = uint32_t(cursor_pos);
}
range.mEndOffset = range.mStartOffset;
range.mStartOffset = range.mEndOffset = caretOffsetInUTF16;
range.mRangeType = NS_TEXTRANGE_CARETPOSITION;
textRangeArray->AppendElement(range);
MOZ_LOG(gGtkIMLog, LogLevel::Debug,
("GTKIM: %p CreateTextRangeArray(), mStartOffset=%u, mEndOffset=%u, "
"mRangeType=%s",
("GTKIM: %p CreateTextRangeArray(), mStartOffset=%u, "
"mEndOffset=%u, mRangeType=%s",
this, range.mStartOffset, range.mEndOffset,
GetRangeTypeName(range.mRangeType)));
@@ -1531,6 +1580,196 @@ IMContextWrapper::CreateTextRangeArray(GtkIMContext* aContext,
return textRangeArray.forget();
}
/* static */
nscolor
IMContextWrapper::ToNscolor(PangoAttrColor* aPangoAttrColor)
{
PangoColor& pangoColor = aPangoAttrColor->color;
uint8_t r = pangoColor.red / 0x100;
uint8_t g = pangoColor.green / 0x100;
uint8_t b = pangoColor.blue / 0x100;
return NS_RGB(r, g, b);
}
bool
IMContextWrapper::SetTextRange(PangoAttrIterator* aPangoAttrIter,
const gchar* aUTF8CompositionString,
uint32_t aUTF16CaretOffset,
TextRange& aTextRange) const
{
// Set the range offsets in UTF-16 string.
gint utf8ClauseStart, utf8ClauseEnd;
pango_attr_iterator_range(aPangoAttrIter, &utf8ClauseStart, &utf8ClauseEnd);
if (utf8ClauseStart == utf8ClauseEnd) {
MOZ_LOG(gGtkIMLog, LogLevel::Error,
("GTKIM: %p SetTextRange(), FAILED, due to collapsed range",
this));
return false;
}
if (!utf8ClauseStart) {
aTextRange.mStartOffset = 0;
} else {
glong utf16PreviousClausesLength;
gunichar2* utf16PreviousClausesString =
g_utf8_to_utf16(aUTF8CompositionString, utf8ClauseStart, nullptr,
&utf16PreviousClausesLength, nullptr);
if (NS_WARN_IF(!utf16PreviousClausesString)) {
MOZ_LOG(gGtkIMLog, LogLevel::Error,
("GTKIM: %p SetTextRange(), FAILED, due to g_utf8_to_utf16() "
"failure (retrieving previous string of current clause)",
this));
return false;
}
aTextRange.mStartOffset = utf16PreviousClausesLength;
g_free(utf16PreviousClausesString);
}
glong utf16CurrentClauseLength;
gunichar2* utf16CurrentClauseString =
g_utf8_to_utf16(aUTF8CompositionString + utf8ClauseStart,
utf8ClauseEnd - utf8ClauseStart,
nullptr, &utf16CurrentClauseLength, nullptr);
if (NS_WARN_IF(!utf16CurrentClauseString)) {
MOZ_LOG(gGtkIMLog, LogLevel::Error,
("GTKIM: %p SetTextRange(), FAILED, due to g_utf8_to_utf16() "
"failure (retrieving current clause)",
this));
return false;
}
aTextRange.mEndOffset = aTextRange.mStartOffset + utf16CurrentClauseLength;
g_free(utf16CurrentClauseString);
utf16CurrentClauseString = nullptr;
// Set styles
TextRangeStyle& style = aTextRange.mRangeStyle;
// Underline
PangoAttrInt* attrUnderline =
reinterpret_cast<PangoAttrInt*>(
pango_attr_iterator_get(aPangoAttrIter, PANGO_ATTR_UNDERLINE));
if (attrUnderline) {
switch (attrUnderline->value) {
case PANGO_UNDERLINE_NONE:
style.mLineStyle = TextRangeStyle::LINESTYLE_NONE;
break;
case PANGO_UNDERLINE_DOUBLE:
style.mLineStyle = TextRangeStyle::LINESTYLE_DOUBLE;
break;
case PANGO_UNDERLINE_ERROR:
style.mLineStyle = TextRangeStyle::LINESTYLE_WAVY;
break;
case PANGO_UNDERLINE_SINGLE:
case PANGO_UNDERLINE_LOW:
style.mLineStyle = TextRangeStyle::LINESTYLE_SOLID;
break;
default:
MOZ_LOG(gGtkIMLog, LogLevel::Warning,
("GTKIM: %p SetTextRange(), retrieved unknown underline "
"style: %d",
this, attrUnderline->value));
style.mLineStyle = TextRangeStyle::LINESTYLE_SOLID;
break;
}
style.mDefinedStyles |= TextRangeStyle::DEFINED_LINESTYLE;
// Underline color
PangoAttrColor* attrUnderlineColor =
reinterpret_cast<PangoAttrColor*>(
pango_attr_iterator_get(aPangoAttrIter,
PANGO_ATTR_UNDERLINE_COLOR));
if (attrUnderlineColor) {
style.mUnderlineColor = ToNscolor(attrUnderlineColor);
style.mDefinedStyles |= TextRangeStyle::DEFINED_UNDERLINE_COLOR;
}
} else {
style.mLineStyle = TextRangeStyle::LINESTYLE_NONE;
style.mDefinedStyles |= TextRangeStyle::DEFINED_LINESTYLE;
}
// Don't set colors if they are not specified. They should be computed by
// textframe if only one of the colors are specified.
// Foreground color (text color)
PangoAttrColor* attrForeground =
reinterpret_cast<PangoAttrColor*>(
pango_attr_iterator_get(aPangoAttrIter, PANGO_ATTR_FOREGROUND));
if (attrForeground) {
style.mForegroundColor = ToNscolor(attrForeground);
style.mDefinedStyles |= TextRangeStyle::DEFINED_FOREGROUND_COLOR;
}
// Background color
PangoAttrColor* attrBackground =
reinterpret_cast<PangoAttrColor*>(
pango_attr_iterator_get(aPangoAttrIter, PANGO_ATTR_BACKGROUND));
if (attrBackground) {
style.mBackgroundColor = ToNscolor(attrBackground);
style.mDefinedStyles |= TextRangeStyle::DEFINED_BACKGROUND_COLOR;
}
/**
* We need to judge the meaning of the clause for a11y. Before we support
* IME specific composition string style, we used following rules:
*
* 1: If attrUnderline and attrForground are specified, we assumed the
* clause is NS_TEXTRANGE_SELECTEDCONVERTEDTEXT.
* 2: If only attrUnderline is specified, we assumed the clause is
* NS_TEXTRANGE_CONVERTEDTEXT.
* 3: If only attrForground is specified, we assumed the clause is
* NS_TEXTRANGE_SELECTEDRAWTEXT.
* 4: If neither attrUnderline nor attrForeground is specified, we assumed
* the clause is NS_TEXTRANGE_RAWINPUT.
*
* However, this rules are odd since there can be two or more selected
* clauses. Additionally, our old rules caused that IME developers/users
* cannot specify composition string style as they want.
*
* So, we shouldn't guess the meaning from its visual style.
*/
if (!attrUnderline && !attrForeground && !attrBackground) {
MOZ_LOG(gGtkIMLog, LogLevel::Warning,
("GTKIM: %p SetTextRange(), FAILED, due to no attr, "
"aTextRange= { mStartOffset=%u, mEndOffset=%u }",
this, aTextRange.mStartOffset, aTextRange.mEndOffset));
return false;
}
// If the range covers whole of composition string and the caret is at
// the end of the composition string, the range is probably not converted.
if (!utf8ClauseStart &&
utf8ClauseEnd == static_cast<gint>(strlen(aUTF8CompositionString)) &&
aTextRange.mEndOffset == aUTF16CaretOffset) {
aTextRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
}
// Typically, the caret is set at the start of the selected clause.
// So, if the caret is in the clause, we can assume that the clause is
// selected.
else if (aTextRange.mStartOffset <= aUTF16CaretOffset &&
aTextRange.mEndOffset > aUTF16CaretOffset) {
aTextRange.mRangeType = NS_TEXTRANGE_SELECTEDCONVERTEDTEXT;
}
// Otherwise, we should assume that the clause is converted but not
// selected.
else {
aTextRange.mRangeType = NS_TEXTRANGE_CONVERTEDTEXT;
}
MOZ_LOG(gGtkIMLog, LogLevel::Debug,
("GTKIM: %p SetTextRange(), succeeded, aTextRange= { "
"mStartOffset=%u, mEndOffset=%u, mRangeType=%s, mRangeStyle=%s }",
this, aTextRange.mStartOffset, aTextRange.mEndOffset,
GetRangeTypeName(aTextRange.mRangeType),
GetTextRangeStyleText(aTextRange.mRangeStyle).get()));
return true;
}
void
IMContextWrapper::SetCursorPosition(GtkIMContext* aContext)
{
@@ -1571,7 +1810,7 @@ IMContextWrapper::SetCursorPosition(GtkIMContext* aContext)
}
WidgetQueryContentEvent charRect(true,
useCaret ? NS_QUERY_CARET_RECT :
useCaret ? eQueryCaretRect :
NS_QUERY_TEXT_RECT,
mLastFocusedWindow);
if (useCaret) {
@@ -1594,7 +1833,7 @@ IMContextWrapper::SetCursorPosition(GtkIMContext* aContext)
if (!charRect.mSucceeded) {
MOZ_LOG(gGtkIMLog, LogLevel::Error,
("GTKIM: %p SetCursorPosition(), FAILED, %s was failed",
this, useCaret ? "NS_QUERY_CARET_RECT" : "NS_QUERY_TEXT_RECT"));
this, useCaret ? "eQueryCaretRect" : "NS_QUERY_TEXT_RECT"));
return;
}
@@ -1670,8 +1909,7 @@ IMContextWrapper::GetCurrentParagraph(nsAString& aText,
}
// Get all text contents of the focused editor
WidgetQueryContentEvent queryTextContentEvent(true,
NS_QUERY_TEXT_CONTENT,
WidgetQueryContentEvent queryTextContentEvent(true, eQueryTextContent,
mLastFocusedWindow);
queryTextContentEvent.InitForQueryTextContent(0, UINT32_MAX);
mLastFocusedWindow->DispatchEvent(&queryTextContentEvent, status);
@@ -1767,8 +2005,7 @@ IMContextWrapper::DeleteText(GtkIMContext* aContext,
}
// Get all text contents of the focused editor
WidgetQueryContentEvent queryTextContentEvent(true,
NS_QUERY_TEXT_CONTENT,
WidgetQueryContentEvent queryTextContentEvent(true, eQueryTextContent,
mLastFocusedWindow);
queryTextContentEvent.InitForQueryTextContent(0, UINT32_MAX);
mLastFocusedWindow->DispatchEvent(&queryTextContentEvent, status);
@@ -1814,7 +2051,7 @@ IMContextWrapper::DeleteText(GtkIMContext* aContext,
g_utf8_offset_to_pointer(utf8Str.get(), endInUTF8Characters);
// Set selection to delete
WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET,
WidgetSelectionEvent selectionEvent(true, eSetSelection,
mLastFocusedWindow);
nsDependentCSubstring utf8StrBeforeOffset(utf8Str, 0,
@@ -1913,7 +2150,7 @@ IMContextWrapper::EnsureToCacheSelection(nsAString* aSelectedString)
}
nsEventStatus status;
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT,
WidgetQueryContentEvent selection(true, eQuerySelectedText,
mLastFocusedWindow);
InitEvent(selection);
mLastFocusedWindow->DispatchEvent(&selection, status);
@@ -1962,7 +2199,7 @@ IMContextWrapper::Selection::Assign(const IMENotification& aIMENotification)
void
IMContextWrapper::Selection::Assign(const WidgetQueryContentEvent& aEvent)
{
MOZ_ASSERT(aEvent.mMessage == NS_QUERY_SELECTED_TEXT);
MOZ_ASSERT(aEvent.mMessage == eQuerySelectedText);
MOZ_ASSERT(aEvent.mSucceeded);
mOffset = aEvent.mReply.mOffset;
mLength = aEvent.mReply.mString.Length();
+25 -4
View File
@@ -345,13 +345,34 @@ protected:
* Generates our text range array from current composition string.
*
* @param aContext A GtkIMContext which is being handled.
* @param aLastDispatchedData The data of the last compositionchange event
* of current composition. This should be
* mDispatchedCompositionString.
* @param aCompositionString The data to be dispatched with
* compositionchange event.
*/
already_AddRefed<TextRangeArray>
CreateTextRangeArray(GtkIMContext* aContext,
const nsAString& aLastDispatchedData);
const nsAString& aCompositionString);
/**
* SetTextRange() initializes aTextRange with aPangoAttrIter.
*
* @param aPangoAttrIter An iter which represents a clause of the
* composition string.
* @param aUTF8CompositionString The whole composition string (UTF-8).
* @param aUTF16CaretOffset The caret offset in the composition
* string encoded as UTF-16.
* @param aTextRange The result.
* @return true if this initializes aTextRange.
* Otherwise, false.
*/
bool SetTextRange(PangoAttrIterator* aPangoAttrIter,
const gchar* aUTF8CompositionString,
uint32_t aUTF16CaretOffset,
TextRange& aTextRange) const;
/**
* ToNscolor() converts the PangoColor in aPangoAttrColor to nscolor.
*/
static nscolor ToNscolor(PangoAttrColor* aPangoAttrColor);
/**
* Move the candidate window with "fake" cursor position.
+1 -1
View File
@@ -5968,7 +5968,7 @@ nsWindow::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
// Check if we're targeting content with vertical writing mode,
// and if so remap the arrow keys.
WidgetQueryContentEvent query(true, NS_QUERY_SELECTED_TEXT, this);
WidgetQueryContentEvent query(true, eQuerySelectedText, this);
nsEventStatus status;
DispatchEvent(&query, status);
+10 -10
View File
@@ -1886,12 +1886,12 @@ TestApp::TestSelection(void)
bool succeeded = true;
/* If these fail the cause is probably one or more of:
* nsTextStore::GetSelection not sending NS_QUERY_SELECTED_TEXT
* NS_QUERY_SELECTED_TEXT not handled by ContentEventHandler
* Bug in NS_QUERY_SELECTED_TEXT handler
* nsTextStore::SetSelection not sending NS_SELECTION_SET
* NS_SELECTION_SET not handled by ContentEventHandler
* Bug in NS_SELECTION_SET handler
* nsTextStore::GetSelection not sending eQuerySelectedText
* eQuerySelectedText not handled by ContentEventHandler
* Bug in eQuerySelectedText handler
* nsTextStore::SetSelection not sending eSetSelection
* eSetSelection not handled by ContentEventHandler
* Bug in eSetSelection handler
*/
TS_SELECTION_ACP testSel;
@@ -1960,12 +1960,12 @@ TestApp::TestText(void)
HRESULT hr;
/* If these fail the cause is probably one or more of:
* nsTextStore::GetText not sending NS_QUERY_TEXT_CONTENT
* NS_QUERY_TEXT_CONTENT not handled by ContentEventHandler
* Bug in NS_QUERY_TEXT_CONTENT handler
* nsTextStore::GetText not sending eQueryTextContent
* eQueryTextContent not handled by ContentEventHandler
* Bug in eQueryTextContent handler
* nsTextStore::SetText not calling SetSelection or InsertTextAtSelection
* Bug in SetSelection or InsertTextAtSelection
* NS_SELECTION_SET bug or NS_COMPOSITION_* / NS_COMPOSITION_CHANGE bug
* eSetSelection bug or NS_COMPOSITION_* / NS_COMPOSITION_CHANGE bug
*/
if (!mMgr->GetFocusedStore()) {
+6 -8
View File
@@ -1726,14 +1726,13 @@ IMMHandler::HandleDocumentFeed(nsWindow* aWindow,
}
// Get all contents of the focused editor.
WidgetQueryContentEvent textContent(true, NS_QUERY_TEXT_CONTENT, aWindow);
WidgetQueryContentEvent textContent(true, eQueryTextContent, aWindow);
textContent.InitForQueryTextContent(0, UINT32_MAX);
aWindow->InitEvent(textContent, &point);
aWindow->DispatchWindowEvent(&textContent);
if (!textContent.mSucceeded) {
MOZ_LOG(gIMMLog, LogLevel::Error,
("IMM: HandleDocumentFeed, FAILED, due to NS_QUERY_TEXT_CONTENT "
"failure"));
("IMM: HandleDocumentFeed, FAILED, due to eQueryTextContent failure"));
return false;
}
@@ -2203,13 +2202,13 @@ IMMHandler::GetCaretRect(nsWindow* aWindow,
return false;
}
WidgetQueryContentEvent caretRect(true, NS_QUERY_CARET_RECT, aWindow);
WidgetQueryContentEvent caretRect(true, eQueryCaretRect, aWindow);
caretRect.InitForQueryCaretRect(selection.mOffset);
aWindow->InitEvent(caretRect, &point);
aWindow->DispatchWindowEvent(&caretRect);
if (!caretRect.mSucceeded) {
MOZ_LOG(gIMMLog, LogLevel::Info,
("IMM: GetCaretRect, FAILED, due to NS_QUERY_CARET_RECT failure"));
("IMM: GetCaretRect, FAILED, due to eQueryCaretRect failure"));
return false;
}
aCaretRect = LayoutDevicePixel::ToUntyped(caretRect.mReply.mRect);
@@ -2753,14 +2752,13 @@ IMMHandler::Selection::Init(nsWindow* aWindow)
{
Clear();
WidgetQueryContentEvent selection(true, NS_QUERY_SELECTED_TEXT, aWindow);
WidgetQueryContentEvent selection(true, eQuerySelectedText, aWindow);
nsIntPoint point(0, 0);
aWindow->InitEvent(selection, &point);
aWindow->DispatchWindowEvent(&selection);
if (NS_WARN_IF(!selection.mSucceeded)) {
MOZ_LOG(gIMMLog, LogLevel::Error,
("IMM: Selection::Init, FAILED, due to NS_QUERY_SELECTED_TEXT "
"failure"));
("IMM: Selection::Init, FAILED, due to eQuerySelectedText failure"));
return false;
}
// If the window is destroyed during querying selected text, we shouldn't
+59 -27
View File
@@ -1301,7 +1301,7 @@ TSFTextStore::TSFTextStore()
, mPendingOnSelectionChange(false)
, mPendingOnLayoutChange(false)
, mPendingDestroy(false)
, mPendingClearLockedContent(false)
, mDeferClearingLockedContent(false)
, mNativeCaretIsCreated(false)
, mDeferNotifyingTSF(false)
{
@@ -1674,11 +1674,6 @@ TSFTextStore::FlushPendingActions()
return;
}
// If dispatching event causes NOTIFY_IME_OF_COMPOSITION_UPDATE, we should
// wait to abandon mLockedContent until it's notified because the dispatched
// event may be handled asynchronously in e10s mode.
mPendingClearLockedContent = !mPendingActions.Length();
nsRefPtr<nsWindowBase> kungFuDeathGrip(mWidget);
for (uint32_t i = 0; i < mPendingActions.Length(); i++) {
PendingAction& action = mPendingActions[i];
@@ -1692,7 +1687,7 @@ TSFTextStore::FlushPendingActions()
if (action.mAdjustSelection) {
// Select composition range so the new composition replaces the range
WidgetSelectionEvent selectionSet(true, NS_SELECTION_SET, mWidget);
WidgetSelectionEvent selectionSet(true, eSetSelection, mWidget);
mWidget->InitEvent(selectionSet);
selectionSet.mOffset = static_cast<uint32_t>(action.mSelectionStart);
selectionSet.mLength = static_cast<uint32_t>(action.mSelectionLength);
@@ -1701,7 +1696,7 @@ TSFTextStore::FlushPendingActions()
if (!selectionSet.mSucceeded) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("TSF: 0x%p TSFTextStore::FlushPendingActions() "
"FAILED due to NS_SELECTION_SET failure", this));
"FAILED due to eSetSelection failure", this));
break;
}
}
@@ -1712,7 +1707,9 @@ TSFTextStore::FlushPendingActions()
mWidget);
mWidget->InitEvent(compositionStart);
// NS_COMPOSITION_START always causes NOTIFY_IME_OF_COMPOSITION_UPDATE.
mPendingClearLockedContent = true;
// Therefore, we should wait to clear the locked content until it's
// notified.
mDeferClearingLockedContent = true;
DispatchEvent(compositionStart);
if (!mWidget || mWidget->Destroyed()) {
break;
@@ -1777,9 +1774,11 @@ TSFTextStore::FlushPendingActions()
}
compositionChange.mRanges = action.mRanges;
// When the NS_COMPOSITION_CHANGE causes a DOM text event,
// NOTIFY_IME_OF_COMPOSITION_UPDATE will be notified.
// the IME will be notified of NOTIFY_IME_OF_COMPOSITION_UPDATE. In
// such case, we should not clear the locked content until we notify
// the IME of the composition update.
if (compositionChange.CausesDOMTextEvent()) {
mPendingClearLockedContent = true;
mDeferClearingLockedContent = true;
}
DispatchEvent(compositionChange);
// Be aware, the mWidget might already have been destroyed.
@@ -1802,9 +1801,11 @@ TSFTextStore::FlushPendingActions()
mWidget->InitEvent(compositionCommit);
compositionCommit.mData = action.mData;
// When the NS_COMPOSITION_COMMIT causes a DOM text event,
// NOTIFY_IME_OF_COMPOSITION_UPDATE will be notified.
// the IME will be notified of NOTIFY_IME_OF_COMPOSITION_UPDATE. In
// such case, we should not clear the locked content until we notify
// the IME of the composition update.
if (compositionCommit.CausesDOMTextEvent()) {
mPendingClearLockedContent = true;
mDeferClearingLockedContent = true;
}
DispatchEvent(compositionCommit);
if (!mWidget || mWidget->Destroyed()) {
@@ -1812,15 +1813,15 @@ TSFTextStore::FlushPendingActions()
}
break;
}
case PendingAction::SELECTION_SET: {
case PendingAction::SET_SELECTION: {
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("TSF: 0x%p TSFTextStore::FlushPendingActions() "
"flushing SELECTION_SET={ mSelectionStart=%d, "
"flushing SET_SELECTION={ mSelectionStart=%d, "
"mSelectionLength=%d, mSelectionReversed=%s }",
this, action.mSelectionStart, action.mSelectionLength,
GetBoolName(action.mSelectionReversed)));
WidgetSelectionEvent selectionSet(true, NS_SELECTION_SET, mWidget);
WidgetSelectionEvent selectionSet(true, eSetSelection, mWidget);
selectionSet.mOffset =
static_cast<uint32_t>(action.mSelectionStart);
selectionSet.mLength =
@@ -1868,9 +1869,11 @@ TSFTextStore::MaybeFlushPendingNotifications()
return;
}
if (mPendingClearLockedContent) {
mPendingClearLockedContent = false;
if (!mDeferClearingLockedContent && mLockedContent.IsInitialized()) {
mLockedContent.Clear();
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("TSF: 0x%p TSFTextStore::MaybeFlushPendingNotifications(), "
"mLockedContent is cleared", this));
}
if (mPendingOnLayoutChange) {
@@ -1997,12 +2000,21 @@ TSFTextStore::LockedContent()
// This should be called when the document is locked or the content hasn't
// been abandoned yet.
if (NS_WARN_IF(!IsReadLocked() && !mLockedContent.IsInitialized())) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("TSF: 0x%p TSFTextStore::LockedContent(), FAILED, due to "
"called wrong timing, IsReadLocked()=%s, "
"mLockedContent.IsInitialized()=%s",
this, GetBoolName(IsReadLocked()),
GetBoolName(mLockedContent.IsInitialized())));
mLockedContent.Clear();
return mLockedContent;
}
Selection& currentSel = CurrentSelection();
if (currentSel.IsDirty()) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("TSF: 0x%p TSFTextStore::LockedContent(), FAILED, due to "
"CurrentSelection() failure", this));
mLockedContent.Clear();
return mLockedContent;
}
@@ -2010,19 +2022,31 @@ TSFTextStore::LockedContent()
if (!mLockedContent.IsInitialized()) {
nsAutoString text;
if (NS_WARN_IF(!GetCurrentText(text))) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("TSF: 0x%p TSFTextStore::LockedContent(), FAILED, due to "
"GetCurrentText() failure", this));
mLockedContent.Clear();
return mLockedContent;
}
mLockedContent.Init(text);
// Basically, the locked content should be cleared after the document is
// unlocked. However, in e10s mode, content will be modified
// asynchronously. In such case, mDeferClearingLockedContent may be
// true even after the document is unlocked.
mDeferClearingLockedContent = false;
}
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("TSF: 0x%p TSFTextStore::LockedContent(): "
"mLockedContent={ mText.Length()=%d, mLastCompositionString=\"%s\", "
"mLockedContent={ mText=\"%s\" (Length()=%u), "
"mLastCompositionString=\"%s\" (Length()=%u), "
"mMinTextModifiedOffset=%u }",
this, mLockedContent.Text().Length(),
this, mLockedContent.Text().Length() <= 20 ?
NS_ConvertUTF16toUTF8(mLockedContent.Text()).get() : "<omitted>",
mLockedContent.Text().Length(),
NS_ConvertUTF16toUTF8(mLockedContent.LastCompositionString()).get(),
mLockedContent.LastCompositionString().Length(),
mLockedContent.MinTextModifiedOffset()));
return mLockedContent;
@@ -2038,11 +2062,18 @@ TSFTextStore::GetCurrentText(nsAString& aTextContent)
MOZ_ASSERT(mWidget && !mWidget->Destroyed());
WidgetQueryContentEvent queryText(true, NS_QUERY_TEXT_CONTENT, mWidget);
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("TSF: 0x%p TSFTextStore::GetCurrentText(): "
"retrieving text from the content...", this));
WidgetQueryContentEvent queryText(true, eQueryTextContent, mWidget);
queryText.InitForQueryTextContent(0, UINT32_MAX);
mWidget->InitEvent(queryText);
DispatchEvent(queryText);
if (NS_WARN_IF(!queryText.mSucceeded)) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("TSF: 0x%p TSFTextStore::GetCurrentText(), FAILED, due to "
"eQueryTextContent failure", this));
aTextContent.Truncate();
return false;
}
@@ -2061,8 +2092,7 @@ TSFTextStore::CurrentSelection()
MOZ_CRASH();
}
WidgetQueryContentEvent querySelection(true, NS_QUERY_SELECTED_TEXT,
mWidget);
WidgetQueryContentEvent querySelection(true, eQuerySelectedText, mWidget);
mWidget->InitEvent(querySelection);
DispatchEvent(querySelection);
NS_ENSURE_TRUE(querySelection.mSucceeded, mSelection);
@@ -2664,7 +2694,7 @@ TSFTextStore::SetSelectionInternal(const TS_SELECTION_ACP* pSelection,
CompleteLastActionIfStillIncomplete();
PendingAction* action = mPendingActions.AppendElement();
action->mType = PendingAction::SELECTION_SET;
action->mType = PendingAction::SET_SELECTION;
action->mSelectionStart = pSelection->acpStart;
action->mSelectionLength = pSelection->acpEnd - pSelection->acpStart;
action->mSelectionReversed = (pSelection->style.ase == TS_AE_START);
@@ -4676,7 +4706,9 @@ TSFTextStore::OnUpdateCompositionInternal()
"mDeferNotifyingTSF=%s",
this, GetBoolName(mDeferNotifyingTSF)));
mPendingClearLockedContent = true;
// Now, all sent composition events are handled by the content even in
// e10s mode.
mDeferClearingLockedContent = false;
mDeferNotifyingTSF = false;
MaybeFlushPendingNotifications();
return NS_OK;
@@ -4779,14 +4811,14 @@ TSFTextStore::CreateNativeCaret()
// collapsed, is it OK?
uint32_t caretOffset = currentSel.MaxOffset();
WidgetQueryContentEvent queryCaretRect(true, NS_QUERY_CARET_RECT, mWidget);
WidgetQueryContentEvent queryCaretRect(true, eQueryCaretRect, mWidget);
queryCaretRect.InitForQueryCaretRect(caretOffset);
mWidget->InitEvent(queryCaretRect);
DispatchEvent(queryCaretRect);
if (!queryCaretRect.mSucceeded) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("TSF: 0x%p TSFTextStore::CreateNativeCaret() FAILED due to "
"NS_QUERY_CARET_RECT failure (offset=%d)", this, caretOffset));
"eQueryCaretRect failure (offset=%d)", this, caretOffset));
return;
}
+3 -3
View File
@@ -511,7 +511,7 @@ protected:
COMPOSITION_START,
COMPOSITION_UPDATE,
COMPOSITION_END,
SELECTION_SET
SET_SELECTION
};
ActionType mType;
// For compositionstart and selectionset
@@ -793,9 +793,9 @@ protected:
// During the documet is locked, we shouldn't destroy the instance.
// If this is true, the instance will be destroyed after unlocked.
bool mPendingDestroy;
// If this is true, MaybeFlushPendingNotifications() will clear the
// If this is false, MaybeFlushPendingNotifications() will clear the
// mLockedContent.
bool mPendingClearLockedContent;
bool mDeferClearingLockedContent;
// While there is native caret, this is true. Otherwise, false.
bool mNativeCaretIsCreated;
// While the instance is dispatching events, the event may not be handled