mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1216096: restore previous RTL caret behaviour by backout of bug 1164963, bug 1177505, and bug 1180417. r=jfkthame
This commit is contained in:
parent
c7090ef533
commit
3457b582d2
@ -734,42 +734,31 @@ nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsIFrame* frame0 = frameCount > 0 ? aBpd->FrameAt(0) : nullptr;
|
if (runCount == 1 && frameCount == 1 &&
|
||||||
|
|
||||||
// Non-bidi frames
|
|
||||||
if (runCount == 1 &&
|
|
||||||
aBpd->mParagraphDepth == 0 && aBpd->GetDirection() == NSBIDI_LTR &&
|
aBpd->mParagraphDepth == 0 && aBpd->GetDirection() == NSBIDI_LTR &&
|
||||||
aBpd->GetParaLevel() == 0 &&
|
aBpd->GetParaLevel() == 0) {
|
||||||
frame0 && frame0 != NS_BIDI_CONTROL_FRAME &&
|
// We have a single left-to-right frame in a left-to-right paragraph,
|
||||||
!frame0->Properties().Get(nsIFrame::EmbeddingLevelProperty()) &&
|
|
||||||
!frame0->Properties().Get(nsIFrame::BaseLevelProperty())) {
|
|
||||||
// We have a left-to-right frame in a left-to-right paragraph,
|
|
||||||
// without bidi isolation from the surrounding text.
|
// without bidi isolation from the surrounding text.
|
||||||
// The embedding level and base level frame properties aren't
|
// Make sure that the embedding level and base level frame properties aren't
|
||||||
// set (because if they are this frame used to have some other direction,
|
// set (because if they are this frame used to have some other direction,
|
||||||
// so we can't do this optimization)
|
// so we can't do this optimization), and we're done.
|
||||||
|
nsIFrame* frame = aBpd->FrameAt(0);
|
||||||
// Make all continuations fluid within this run
|
if (frame != NS_BIDI_CONTROL_FRAME &&
|
||||||
for (int i = 0; i < frameCount; ++i) {
|
!frame->Properties().Get(nsIFrame::EmbeddingLevelProperty()) &&
|
||||||
nsIFrame* frame = aBpd->FrameAt(i);
|
!frame->Properties().Get(nsIFrame::BaseLevelProperty())) {
|
||||||
if (frame && frame != NS_BIDI_CONTROL_FRAME) {
|
|
||||||
JoinInlineAncestors(frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#ifdef NOISY_BIDI
|
#ifdef NOISY_BIDI
|
||||||
printf("early return for single direction frame %p\n", (void*)frame);
|
printf("early return for single direction frame %p\n", (void*)frame);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
frame->AddStateBits(NS_FRAME_IS_BIDI);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* firstFrame = nullptr;
|
nsIFrame* firstFrame = nullptr;
|
||||||
nsIFrame* lastFrame = nullptr;
|
nsIFrame* lastFrame = nullptr;
|
||||||
|
|
||||||
// Bidi frames
|
|
||||||
for (; ;) {
|
for (; ;) {
|
||||||
if (fragmentLength <= 0) {
|
if (fragmentLength <= 0) {
|
||||||
// Get the next frame from mLogicalFrames
|
// Get the next frame from mLogicalFrames
|
||||||
|
@ -115,14 +115,9 @@ AdjustCaretFrameForLineEnd(nsIFrame** aFrame, int32_t* aOffset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsKeyboardRTL()
|
IsBidiUI()
|
||||||
{
|
{
|
||||||
bool isKeyboardRTL = false;
|
return Preferences::GetBool("bidi.browser.ui");
|
||||||
nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard();
|
|
||||||
if (bidiKeyboard) {
|
|
||||||
bidiKeyboard->IsLangRTL(&isKeyboardRTL);
|
|
||||||
}
|
|
||||||
return isKeyboardRTL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCaret::nsCaret()
|
nsCaret::nsCaret()
|
||||||
@ -503,21 +498,6 @@ nsCaret::SetCaretPosition(nsIDOMNode* aNode, int32_t aOffset)
|
|||||||
SchedulePaint();
|
SchedulePaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
nsCaret::IsBidiUI()
|
|
||||||
{
|
|
||||||
nsIFrame* frame = nullptr;
|
|
||||||
|
|
||||||
if(Selection* selection = GetSelectionInternal()) {
|
|
||||||
int32_t contentOffset;
|
|
||||||
frame = GetFrameAndOffset(selection, mOverrideContent, mOverrideOffset,
|
|
||||||
&contentOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (frame && frame->GetStateBits() & NS_FRAME_IS_BIDI) ||
|
|
||||||
Preferences::GetBool("bidi.browser.ui");
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsCaret::CheckSelectionLanguageChange()
|
nsCaret::CheckSelectionLanguageChange()
|
||||||
{
|
{
|
||||||
@ -525,8 +505,11 @@ nsCaret::CheckSelectionLanguageChange()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isKeyboardRTL = IsKeyboardRTL();
|
bool isKeyboardRTL = false;
|
||||||
|
nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard();
|
||||||
|
if (bidiKeyboard) {
|
||||||
|
bidiKeyboard->IsLangRTL(&isKeyboardRTL);
|
||||||
|
}
|
||||||
// Call SelectionLanguageChange on every paint. Mostly it will be a noop
|
// Call SelectionLanguageChange on every paint. Mostly it will be a noop
|
||||||
// but it should be fast anyway. This guarantees we never paint the caret
|
// but it should be fast anyway. This guarantees we never paint the caret
|
||||||
// at the wrong place.
|
// at the wrong place.
|
||||||
@ -715,9 +698,8 @@ nsCaret::GetCaretFrameForNodeOffset(nsFrameSelection* aFrameSelection,
|
|||||||
if (theFrame->PresContext()->BidiEnabled())
|
if (theFrame->PresContext()->BidiEnabled())
|
||||||
{
|
{
|
||||||
// If there has been a reflow, take the caret Bidi level to be the level of the current frame
|
// If there has been a reflow, take the caret Bidi level to be the level of the current frame
|
||||||
if (aBidiLevel & BIDI_LEVEL_UNDEFINED) {
|
if (aBidiLevel & BIDI_LEVEL_UNDEFINED)
|
||||||
aBidiLevel = NS_GET_EMBEDDING_LEVEL(theFrame);
|
aBidiLevel = NS_GET_EMBEDDING_LEVEL(theFrame);
|
||||||
}
|
|
||||||
|
|
||||||
int32_t start;
|
int32_t start;
|
||||||
int32_t end;
|
int32_t end;
|
||||||
@ -941,22 +923,21 @@ nsCaret::ComputeCaretRects(nsIFrame* aFrame, int32_t aFrameOffset,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simon -- make a hook to draw to the left or right of the caret to show keyboard language direction
|
||||||
aHookRect->SetEmpty();
|
aHookRect->SetEmpty();
|
||||||
|
if (!IsBidiUI()) {
|
||||||
Selection* selection = GetSelectionInternal();
|
|
||||||
if (!selection || !selection->GetFrameSelection()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsBidiUI() || IsKeyboardRTL()) {
|
bool isCaretRTL;
|
||||||
// If caret level is RTL, draw the hook on the left; if LTR, to the right
|
nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard();
|
||||||
|
// if bidiKeyboard->IsLangRTL() fails, there is no way to tell the
|
||||||
|
// keyboard direction, or the user has no right-to-left keyboard
|
||||||
|
// installed, so we never draw the hook.
|
||||||
|
if (bidiKeyboard && NS_SUCCEEDED(bidiKeyboard->IsLangRTL(&isCaretRTL))) {
|
||||||
|
// If keyboard language is RTL, draw the hook on the left; if LTR, to the right
|
||||||
// The height of the hook rectangle is the same as the width of the caret
|
// The height of the hook rectangle is the same as the width of the caret
|
||||||
// rectangle.
|
// rectangle.
|
||||||
int caretBidiLevel = selection->GetFrameSelection()->GetCaretBidiLevel();
|
|
||||||
if (caretBidiLevel & BIDI_LEVEL_UNDEFINED) {
|
|
||||||
caretBidiLevel = NS_GET_EMBEDDING_LEVEL(aFrame);
|
|
||||||
}
|
|
||||||
bool isCaretRTL = caretBidiLevel % 2;
|
|
||||||
if (isVertical) {
|
if (isVertical) {
|
||||||
bool isSidewaysLR = wm.IsVerticalLR() && !wm.IsLineInverted();
|
bool isSidewaysLR = wm.IsVerticalLR() && !wm.IsLineInverted();
|
||||||
if (isSidewaysLR) {
|
if (isSidewaysLR) {
|
||||||
|
@ -183,7 +183,6 @@ class nsCaret final : public nsISelectionListener
|
|||||||
protected:
|
protected:
|
||||||
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
|
static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure);
|
||||||
|
|
||||||
bool IsBidiUI();
|
|
||||||
void CheckSelectionLanguageChange();
|
void CheckSelectionLanguageChange();
|
||||||
|
|
||||||
void ResetBlinking();
|
void ResetBlinking();
|
||||||
|
@ -3,14 +3,13 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
</head>
|
</head>
|
||||||
<body onload="start()">
|
<body onload="start()">
|
||||||
<textarea onfocus="done()" style="-moz-appearance: none">س‎</textarea>
|
<textarea onfocus="done()" style="-moz-appearance: none">س</textarea>
|
||||||
<script>
|
<script>
|
||||||
var textarea = document.querySelector("textarea");
|
var textarea = document.querySelector("textarea");
|
||||||
function start() {
|
function start() {
|
||||||
textarea.focus();
|
textarea.focus();
|
||||||
}
|
}
|
||||||
function done() {
|
function done() {
|
||||||
textarea.selectionStart = textarea.selectionEnd = 2;
|
|
||||||
document.documentElement.removeAttribute("class");
|
document.documentElement.removeAttribute("class");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
<html class="reftest-wait">
|
<html class="reftest-wait">
|
||||||
<body onload="start()">
|
<body onload="start()">
|
||||||
<textarea dir="rtl" onfocus="done()" style="-moz-appearance: none">s‏</textarea>
|
<textarea dir="rtl" onfocus="done()" style="-moz-appearance: none">s</textarea>
|
||||||
<script>
|
<script>
|
||||||
var textarea = document.querySelector("textarea");
|
var textarea = document.querySelector("textarea");
|
||||||
function start() {
|
function start() {
|
||||||
textarea.focus();
|
textarea.focus();
|
||||||
}
|
}
|
||||||
function done() {
|
function done() {
|
||||||
textarea.selectionStart = textarea.selectionEnd = 2;
|
|
||||||
document.documentElement.removeAttribute("class");
|
document.documentElement.removeAttribute("class");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -621,9 +621,7 @@ private:
|
|||||||
uint32_t aContentOffset,
|
uint32_t aContentOffset,
|
||||||
nsSelectionAmount aAmount,
|
nsSelectionAmount aAmount,
|
||||||
CaretAssociateHint aHint);
|
CaretAssociateHint aHint);
|
||||||
void BidiLevelFromClick(nsIContent *aNewFocus,
|
void BidiLevelFromClick(nsIContent *aNewFocus, uint32_t aContentOffset);
|
||||||
uint32_t aContentOffset,
|
|
||||||
CaretAssociateHint aHint);
|
|
||||||
nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode,
|
nsPrevNextBidiLevels GetPrevNextBidiLevels(nsIContent *aNode,
|
||||||
uint32_t aContentOffset,
|
uint32_t aContentOffset,
|
||||||
CaretAssociateHint aHint,
|
CaretAssociateHint aHint,
|
||||||
|
@ -1460,13 +1460,12 @@ void nsFrameSelection::BidiLevelFromMove(nsIPresShell* aPresShell,
|
|||||||
* @param aContentOffset is the new caret position, as an offset into aNode
|
* @param aContentOffset is the new caret position, as an offset into aNode
|
||||||
*/
|
*/
|
||||||
void nsFrameSelection::BidiLevelFromClick(nsIContent *aNode,
|
void nsFrameSelection::BidiLevelFromClick(nsIContent *aNode,
|
||||||
uint32_t aContentOffset,
|
uint32_t aContentOffset)
|
||||||
CaretAssociateHint aHint)
|
|
||||||
{
|
{
|
||||||
nsIFrame* clickInFrame=nullptr;
|
nsIFrame* clickInFrame=nullptr;
|
||||||
int32_t OffsetNotUsed;
|
int32_t OffsetNotUsed;
|
||||||
|
|
||||||
clickInFrame = GetFrameForNodeOffset(aNode, aContentOffset, aHint, &OffsetNotUsed);
|
clickInFrame = GetFrameForNodeOffset(aNode, aContentOffset, mHint, &OffsetNotUsed);
|
||||||
if (!clickInFrame)
|
if (!clickInFrame)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1545,7 +1544,7 @@ nsFrameSelection::HandleClick(nsIContent* aNewFocus,
|
|||||||
// Don't take focus when dragging off of a table
|
// Don't take focus when dragging off of a table
|
||||||
if (!mDragSelectingCells)
|
if (!mDragSelectingCells)
|
||||||
{
|
{
|
||||||
BidiLevelFromClick(aNewFocus, aContentOffset, aHint);
|
BidiLevelFromClick(aNewFocus, aContentOffset);
|
||||||
PostReason(nsISelectionListener::MOUSEDOWN_REASON + nsISelectionListener::DRAG_REASON);
|
PostReason(nsISelectionListener::MOUSEDOWN_REASON + nsISelectionListener::DRAG_REASON);
|
||||||
if (aContinueSelection &&
|
if (aContinueSelection &&
|
||||||
AdjustForMaintainedSelection(aNewFocus, aContentOffset))
|
AdjustForMaintainedSelection(aNewFocus, aContentOffset))
|
||||||
|
@ -627,7 +627,7 @@ struct FlowLengthProperty {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int32_t nsTextFrame::GetInFlowContentLength() {
|
int32_t nsTextFrame::GetInFlowContentLength() {
|
||||||
if (!PresContext()->BidiEnabled()) {
|
if (!(mState & NS_FRAME_IS_BIDI)) {
|
||||||
return mContent->TextLength() - mContentOffset;
|
return mContent->TextLength() - mContentOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user