diff --git a/mozilla/content/base/public/nsContentUtils.h b/mozilla/content/base/public/nsContentUtils.h index 716b88e8af0..ead2f49623e 100644 --- a/mozilla/content/base/public/nsContentUtils.h +++ b/mozilla/content/base/public/nsContentUtils.h @@ -92,6 +92,9 @@ struct JSRuntime; #ifdef MOZ_XTF class nsIXTFService; #endif +#ifdef IBMBIDI +class nsIBidiKeyboard; +#endif extern const char kLoadAsData[]; @@ -380,6 +383,10 @@ public: static nsIXTFService* GetXTFService(); #endif +#ifdef IBMBIDI + static nsIBidiKeyboard* GetBidiKeyboard(); +#endif + /** * Get the cache security manager service. Can return null if the layout * module has been shut down. @@ -968,7 +975,11 @@ private: static nsIJSRuntimeService* sJSRuntimeService; static JSRuntime* sScriptRuntime; static PRInt32 sScriptRootCount; - + +#ifdef IBMBIDI + static nsIBidiKeyboard* sBidiKeyboard; +#endif + static PRBool sInitialized; }; diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index ab9d2864dc5..6d1a5e6ef42 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -135,6 +135,9 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "nsIEventListenerManager.h" #include "nsAttrName.h" #include "nsIDOMUserDataHandler.h" +#ifdef IBMBIDI +#include "nsIBidiKeyboard.h" +#endif // for ReportToConsole #include "nsIStringBundle.h" @@ -171,6 +174,9 @@ nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease; nsIJSRuntimeService *nsContentUtils::sJSRuntimeService; JSRuntime *nsContentUtils::sScriptRuntime; PRInt32 nsContentUtils::sScriptRootCount = 0; +#ifdef IBMBIDI +nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull; +#endif PRBool nsContentUtils::sInitialized = PR_FALSE; @@ -407,6 +413,20 @@ nsContentUtils::GetXTFService() } #endif +#ifdef IBMBIDI +nsIBidiKeyboard* +nsContentUtils::GetBidiKeyboard() +{ + if (!sBidiKeyboard) { + nsresult rv = CallGetService("@mozilla.org/widget/bidikeyboard;1", &sBidiKeyboard); + if (NS_FAILED(rv)) { + sBidiKeyboard = nsnull; + } + } + return sBidiKeyboard; +} +#endif + template struct NormalizeNewlinesCharTraits { public: @@ -603,6 +623,9 @@ nsContentUtils::Shutdown() NS_IF_RELEASE(sImgLoader); NS_IF_RELEASE(sPrefBranch); NS_IF_RELEASE(sPref); +#ifdef IBMBIDI + NS_IF_RELEASE(sBidiKeyboard); +#endif if (sPtrsToPtrsToRelease) { for (i = 0; i < sPtrsToPtrsToRelease->Count(); ++i) { nsISupports** ptrToPtr = diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp index 1843c7be193..d7c73e44c32 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp @@ -80,6 +80,7 @@ #include "nsReadableUtils.h" #include "nsUnicharUtils.h" +#include "nsFrameSelection.h" //const static char* kMOZEditorBogusNodeAttr="MOZ_EDITOR_BOGUS_NODE"; //const static char* kMOZEditorBogusNodeValue="TRUE"; @@ -401,10 +402,15 @@ nsHTMLEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection) */ if (action == nsEditor::kOpInsertText || action == nsEditor::kOpInsertIMEText) { - nsCOMPtr shell; - mEditor->GetPresShell(getter_AddRefs(shell)); - if (shell) { - shell->UndefineCaretBidiLevel(); + + nsCOMPtr selection; + nsresult res = mHTMLEditor->GetSelection(getter_AddRefs(selection)); + if (NS_FAILED(res)) return res; + nsCOMPtr privateSelection(do_QueryInterface(selection)); + nsCOMPtr frameSelection; + privateSelection->GetFrameSelection(getter_AddRefs(frameSelection)); + if (frameSelection) { + frameSelection->UndefineCaretBidiLevel(); } } } diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.cpp b/mozilla/editor/libeditor/text/nsTextEditRules.cpp index 0100c2e9110..9ffb4afd74e 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRules.cpp @@ -63,6 +63,7 @@ // for IBMBIDI #include "nsIPresShell.h" +#include "nsFrameSelection.h" #define CANCEL_OPERATION_IF_READONLY_OR_DISABLED \ if ((mFlags & nsIPlaintextEditor::eEditorReadonlyMask) || (mFlags & nsIPlaintextEditor::eEditorDisabledMask)) \ @@ -264,10 +265,11 @@ nsTextEditRules::AfterEdit(PRInt32 action, nsIEditor::EDirection aDirection) */ if (action == nsEditor::kOpInsertText || action == nsEditor::kOpInsertIMEText) { - nsCOMPtr shell; - mEditor->GetPresShell(getter_AddRefs(shell)); - if (shell) { - shell->UndefineCaretBidiLevel(); + nsCOMPtr privateSelection(do_QueryInterface(selection)); + nsCOMPtr frameSelection; + privateSelection->GetFrameSelection(getter_AddRefs(frameSelection)); + if (frameSelection) { + frameSelection->UndefineCaretBidiLevel(); } } } diff --git a/mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp b/mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp index a5da9d133de..f1390b66f0a 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp @@ -91,16 +91,13 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsISelection *aSelection, levelBefore = levels.mLevelBefore; levelAfter = levels.mLevelAfter; - - PRUint8 currentCursorLevel; - res = shell->GetCaretBidiLevel(¤tCursorLevel); - if (NS_FAILED(res)) - return res; + + PRUint8 currentCaretLevel = frameSelection->GetCaretBidiLevel(); PRUint8 levelOfDeletion; levelOfDeletion = (nsIEditor::eNext==aAction) ? levelAfter : levelBefore; - if (currentCursorLevel == levelOfDeletion) + if (currentCaretLevel == levelOfDeletion) ; // perform the deletion else { @@ -111,9 +108,7 @@ nsTextEditRules::CheckBidiLevelForDeletion(nsISelection *aSelection, // Set the bidi level of the caret to that of the // character that will be (or would have been) deleted - res = shell->SetCaretBidiLevel(levelOfDeletion); - if (NS_FAILED(res)) - return res; + frameSelection->SetCaretBidiLevel(levelOfDeletion); } return NS_OK; } diff --git a/mozilla/layout/base/nsCaret.cpp b/mozilla/layout/base/nsCaret.cpp index 2e044485fe7..8cc85cd093a 100644 --- a/mozilla/layout/base/nsCaret.cpp +++ b/mozilla/layout/base/nsCaret.cpp @@ -74,10 +74,9 @@ static const PRUint32 kMinBidiIndicatorPixels = 2; #ifdef IBMBIDI -//-------------------------------IBM BIDI-------------------------------------- -// Mamdouh : Modifiaction of the caret to work with Bidi in the LTR and RTL #include "nsLayoutAtoms.h" -//------------------------------END OF IBM BIDI-------------------------------- +#include "nsIBidiKeyboard.h" +#include "nsContentUtils.h" #endif //IBMBIDI //----------------------------------------------------------------------------- @@ -163,13 +162,6 @@ NS_IMETHODIMP nsCaret::Init(nsIPresShell *inPresShell) return rv; } -#ifdef IBMBIDI - PRBool isRTL = PR_FALSE; - mBidiKeyboard = do_GetService("@mozilla.org/widget/bidikeyboard;1"); - if (mBidiKeyboard && NS_SUCCEEDED(mBidiKeyboard->IsLangRTL(&isRTL))) - mKeyboardRTL = isRTL; -#endif - return NS_OK; } @@ -193,10 +185,6 @@ NS_IMETHODIMP nsCaret::Terminate() mLastContent = nsnull; -#ifdef IBMBIDI - mBidiKeyboard = nsnull; -#endif - return NS_OK; } @@ -275,9 +263,6 @@ NS_IMETHODIMP nsCaret::GetCaretCoordinates(EViewCoordinates aRelativeToType, return NS_ERROR_NULL_POINTER; nsCOMPtr domSelection = aDOMSel; - nsCOMPtr privateSelection(do_QueryInterface(domSelection)); - if (!privateSelection) - return NS_ERROR_NOT_INITIALIZED; // no selection if (outView) *outView = nsnull; @@ -314,14 +299,10 @@ NS_IMETHODIMP nsCaret::GetCaretCoordinates(EViewCoordinates aRelativeToType, nsIFrame* theFrame = nsnull; PRInt32 theFrameOffset = 0; - nsCOMPtr frameSelection; - privateSelection->GetFrameSelection(getter_AddRefs(frameSelection)); - - PRUint8 bidiLevel; - nsCOMPtr presShell = do_QueryReferent(mPresShell); - if (!presShell) + nsFrameSelection* frameSelection = GetFrameSelection(); + if (!frameSelection) return NS_ERROR_FAILURE; - presShell->GetCaretBidiLevel(&bidiLevel); + PRUint8 bidiLevel = frameSelection->GetCaretBidiLevel(); err = GetCaretFrameForNodeOffset(contentNode, focusOffset, frameSelection->GetHint(), bidiLevel, @@ -337,6 +318,9 @@ NS_IMETHODIMP nsCaret::GetCaretCoordinates(EViewCoordinates aRelativeToType, return NS_ERROR_UNEXPECTED; // ramp up to make a rendering context for measuring text. // First, we get the pres context ... + nsCOMPtr presShell = do_QueryReferent(mPresShell); + if (!presShell) + return NS_ERROR_FAILURE; nsPresContext *presContext = presShell->GetPresContext(); // ... then tell it to make a rendering context @@ -412,10 +396,10 @@ NS_IMETHODIMP nsCaret::DrawAtPosition(nsIDOMNode* aNode, PRInt32 aOffset) NS_ENSURE_ARG(aNode); PRUint8 bidiLevel; - nsCOMPtr presShell = do_QueryReferent(mPresShell); - if (!presShell) + nsFrameSelection* frameSelection = GetFrameSelection(); + if (!frameSelection) return NS_ERROR_FAILURE; - presShell->GetCaretBidiLevel(&bidiLevel); + bidiLevel = frameSelection->GetCaretBidiLevel(); // XXX we need to do more work here to get the correct hint. nsresult rv = DrawAtPositionWithHint(aNode, aOffset, @@ -618,9 +602,6 @@ nsCaret::DrawAtPositionWithHint(nsIDOMNode* aNode, return PR_FALSE; } - nsCOMPtr presShell = do_QueryReferent(mPresShell); - if (!presShell) - return PR_FALSE; if (!mDrawn) { // save stuff so we can figure out what frame we're in later. @@ -630,8 +611,12 @@ nsCaret::DrawAtPositionWithHint(nsIDOMNode* aNode, mLastBidiLevel = aBidiLevel; // If there has been a reflow, set the caret Bidi level to the level of the current frame - if (aBidiLevel & BIDI_LEVEL_UNDEFINED) - presShell->SetCaretBidiLevel(NS_GET_EMBEDDING_LEVEL(theFrame)); + if (aBidiLevel & BIDI_LEVEL_UNDEFINED) { + nsFrameSelection* frameSelection = GetFrameSelection(); + if (!frameSelection) + return NS_ERROR_FAILURE; + frameSelection->SetCaretBidiLevel(NS_GET_EMBEDDING_LEVEL(theFrame)); + } // Only update the caret's rect when we're not currently drawn. rv = UpdateCaretRects(theFrame, theFrameOffset); @@ -659,13 +644,10 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, if (!presShell) return NS_ERROR_FAILURE; - nsCOMPtr privateSelection(do_QueryReferent(mDomSelectionWeak)); - if (!privateSelection) + nsFrameSelection* frameSelection = GetFrameSelection(); + if (!frameSelection) return NS_ERROR_FAILURE; - nsCOMPtr frameSelection; - privateSelection->GetFrameSelection(getter_AddRefs(frameSelection)); - nsIFrame* theFrame = nsnull; PRInt32 theFrameOffset = 0; @@ -978,10 +960,10 @@ void nsCaret::DrawCaret(PRBool aInvalidate) if (NS_FAILED(domSelection->GetFocusOffset(&offset))) return; - nsCOMPtr presShell = do_QueryReferent(mPresShell); - if (!presShell) + nsFrameSelection* frameSelection = GetFrameSelection(); + if (!frameSelection) return; - presShell->GetCaretBidiLevel(&bidiLevel); + bidiLevel = frameSelection->GetCaretBidiLevel(); } else { @@ -1081,8 +1063,9 @@ nsresult nsCaret::UpdateHookRect(nsPresContext* aPresContext) // Simon -- make a hook to draw to the left or right of the caret to show keyboard language direction PRBool bidiEnabled; PRBool isCaretRTL=PR_FALSE; - if (!mBidiKeyboard || NS_FAILED(mBidiKeyboard->IsLangRTL(&isCaretRTL))) - // if mBidiKeyboard->IsLangRTL() failed, there is no way to tell the + nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard(); + if (!bidiKeyboard || NS_FAILED(bidiKeyboard->IsLangRTL(&isCaretRTL))) + // if bidiKeyboard->IsLangRTL() failed, 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. return NS_OK; @@ -1155,6 +1138,17 @@ void nsCaret::CaretBlinkCallback(nsITimer *aTimer, void *aClosure) } +//----------------------------------------------------------------------------- +nsFrameSelection* nsCaret::GetFrameSelection() { + nsCOMPtr privateSelection(do_QueryReferent(mDomSelectionWeak)); + if (!privateSelection) + return nsnull; + nsCOMPtr frameSelection; + privateSelection->GetFrameSelection(getter_AddRefs(frameSelection)); + return frameSelection; +} + + //----------------------------------------------------------------------------- nsresult NS_NewCaret(nsICaret** aInstancePtrResult) { diff --git a/mozilla/layout/base/nsCaret.h b/mozilla/layout/base/nsCaret.h index ea32ca56333..f1822f188e7 100644 --- a/mozilla/layout/base/nsCaret.h +++ b/mozilla/layout/base/nsCaret.h @@ -45,9 +45,6 @@ #include "nsITimer.h" #include "nsICaret.h" #include "nsWeakPtr.h" -#ifdef IBMBIDI -#include "nsIBidiKeyboard.h" -#endif class nsIView; @@ -156,6 +153,8 @@ class nsCaret : public nsICaret, } void ToggleDrawnStatus() { mDrawn = !mDrawn; } + nsFrameSelection* GetFrameSelection(); + protected: nsWeakPtr mPresShell; @@ -187,7 +186,6 @@ protected: #ifdef IBMBIDI nsRect mHookRect; // directional hook on the caret - nsCOMPtr mBidiKeyboard; // Bidi keyboard object to set and query keyboard language PRUint8 mLastBidiLevel; // saved bidi level of the last draw request, to use when we erase PRPackedBool mKeyboardRTL; // is the keyboard language right-to-left #endif diff --git a/mozilla/layout/base/nsIPresShell.h b/mozilla/layout/base/nsIPresShell.h index 2db6f519d5c..2c2307e2728 100644 --- a/mozilla/layout/base/nsIPresShell.h +++ b/mozilla/layout/base/nsIPresShell.h @@ -98,9 +98,10 @@ class nsWeakFrame; typedef short SelectionType; +// 0d8a87aa-3e6f-409f-a518-96fd8a29b423 #define NS_IPRESSHELL_IID \ -{ 0x67880b18, 0xaf91, 0x431b, \ - { 0x89, 0x69, 0xfa, 0xd9, 0x2b, 0x3c, 0x33, 0x32 } } +{ 0x0d8a87aa, 0x3e6f, 0x409f, \ + { 0xa5, 0x18, 0x96, 0xfd, 0x8a, 0x29, 0xb4, 0x23 } } // Constants uses for ScrollFrameIntoView() function @@ -122,10 +123,6 @@ typedef short SelectionType; #define VERIFY_REFLOW_INCLUDE_SPACE_MANAGER 0x40 #define VERIFY_REFLOW_DURING_RESIZE_REFLOW 0x80 -#ifdef IBMBIDI // Constant for Set/Get CaretBidiLevel -#define BIDI_LEVEL_UNDEFINED 0x80 -#endif - // for PostAttributeChanged enum nsAttributeChangeType { eChangeType_Set = 0, // Set attribute @@ -672,21 +669,6 @@ public: #endif #ifdef IBMBIDI - /** - * SetCaretBidiLevel will set the Bidi embedding level for the cursor. 0-63 - */ - NS_IMETHOD SetCaretBidiLevel(PRUint8 aLevel) = 0; - - /** - * GetCaretBidiLevel will get the Bidi embedding level for the cursor. 0-63 - */ - NS_IMETHOD GetCaretBidiLevel(PRUint8 *aOutLevel) = 0; - - /** - * UndefineCaretBidiLevel will set the Bidi embedding level for the cursor to an out-of-range value - */ - NS_IMETHOD UndefineCaretBidiLevel(void) = 0; - /** * Reconstruct and reflow frame model */ diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index cb9cbd8889b..eeb3255094b 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -197,10 +197,6 @@ // Content viewer interfaces #include "nsIContentViewer.h" -#ifdef IBMBIDI -#include "nsIBidiKeyboard.h" -#endif // IBMBIDI - #include "nsContentCID.h" static NS_DEFINE_CID(kCSSStyleSheetCID, NS_CSS_STYLESHEET_CID); static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID); @@ -1164,9 +1160,6 @@ public: nsIRenderingContext** aRenderedContext); #ifdef IBMBIDI - NS_IMETHOD SetCaretBidiLevel(PRUint8 aLevel); - NS_IMETHOD GetCaretBidiLevel(PRUint8 *aOutLevel); - NS_IMETHOD UndefineCaretBidiLevel(); NS_IMETHOD BidiStyleChangeReflow(); #endif @@ -1336,10 +1329,6 @@ protected: nsIScrollableView* GetViewToScroll(nsLayoutUtils::Direction aDirection); PRBool mCaretEnabled; -#ifdef IBMBIDI - PRUint8 mBidiLevel; // The Bidi level of the cursor - nsCOMPtr mBidiKeyboard; -#endif // IBMBIDI #ifdef NS_DEBUG nsresult CloneStyleSet(nsStyleSet* aSet, nsStyleSet** aResult); PRBool VerifyIncrementalReflow(); @@ -1648,9 +1637,6 @@ NS_NewPresShell(nsIPresShell** aInstancePtrResult) } PresShell::PresShell() -#ifdef IBMBIDI - : mBidiLevel(BIDI_LEVEL_UNDEFINED) -#endif { mIsAccessibilityActive = PR_FALSE; mSelection = nsnull; @@ -1659,9 +1645,6 @@ PresShell::PresShell() mReflowCountMgr->SetPresContext(mPresContext); mReflowCountMgr->SetPresShell(this); #endif -#ifdef IBMBIDI - mBidiLevel = BIDI_LEVEL_UNDEFINED; -#endif #ifdef PR_LOGGING if (! gLog) gLog = PR_NewLogModule("PresShell"); @@ -1843,10 +1826,6 @@ PresShell::Init(nsIDocument* aDocument, // cache the drag service so we can check it during reflows mDragService = do_GetService("@mozilla.org/widget/dragservice;1"); -#ifdef IBMBIDI - mBidiKeyboard = do_GetService("@mozilla.org/widget/bidikeyboard;1"); -#endif - #ifdef MOZ_REFLOW_PERF if (mReflowCountMgr) { PRBool paintFrameCounts = @@ -5543,36 +5522,6 @@ PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame, } #ifdef IBMBIDI -NS_IMETHODIMP -PresShell::SetCaretBidiLevel(PRUint8 aLevel) -{ - // If the current level is undefined, we have just inserted new text. - // In this case, we don't want to reset the keyboard language - PRBool afterInsert = mBidiLevel & BIDI_LEVEL_UNDEFINED; - mBidiLevel = aLevel; - -// PRBool parityChange = ((mBidiLevel ^ aLevel) & 1); // is the parity of the new level different from the current level? -// if (parityChange) // if so, change the keyboard language - if (mBidiKeyboard && !afterInsert) - mBidiKeyboard->SetLangFromBidiLevel(aLevel); - return NS_OK; -} - -NS_IMETHODIMP -PresShell::GetCaretBidiLevel(PRUint8 *aOutLevel) -{ - if (!aOutLevel) { return NS_ERROR_INVALID_ARG; } - *aOutLevel = mBidiLevel; - return NS_OK; -} - -NS_IMETHODIMP -PresShell::UndefineCaretBidiLevel() -{ - mBidiLevel |= BIDI_LEVEL_UNDEFINED; - return NS_OK; -} - NS_IMETHODIMP PresShell::BidiStyleChangeReflow() { diff --git a/mozilla/layout/generic/nsFrameSelection.h b/mozilla/layout/generic/nsFrameSelection.h index e259bdb41f9..8b4ce2ccb27 100644 --- a/mozilla/layout/generic/nsFrameSelection.h +++ b/mozilla/layout/generic/nsFrameSelection.h @@ -40,10 +40,14 @@ #include "nsGUIEvent.h" // IID for the nsFrameSelection interface -// cdfa6280-eba6-4938-9406-427818da8ce3 +// 6c2c1a4c-47ec-42be-a790-00417bf4c241 #define NS_FRAME_SELECTION_IID \ -{ 0xcdfa6280, 0xeba6, 0x4938, \ - { 0x94, 0x06, 0x42, 0x78, 0x18, 0xda, 0x8c, 0xe3 } } +{ 0x6c2c1a4c, 0x47ec, 0x42be, \ + { 0xa7, 0x90, 0x00, 0x41, 0x7b, 0xf4, 0xc2, 0x41 } } + +#ifdef IBMBIDI // Constant for Set/Get CaretBidiLevel +#define BIDI_LEVEL_UNDEFINED 0x80 +#endif //---------------------------------------------------------------------- @@ -352,6 +356,22 @@ public: void SetHint(HINT aHintRight) { mHint = aHintRight; } HINT GetHint() { return mHint; } + +#ifdef IBMBIDI + /** SetCaretBidiLevel sets the caret bidi level + * @param aLevel the caret bidi level + * This method is virtual since it gets called from outside of layout. + */ + virtual void SetCaretBidiLevel (PRUint8 aLevel); + /** GetCaretBidiLevel gets the caret bidi level + * This method is virtual since it gets called from outside of layout. + */ + virtual PRUint8 GetCaretBidiLevel(); + /** UndefineCaretBidiLevel sets the caret bidi level to "undefined" + * This method is virtual since it gets called from outside of layout. + */ + virtual void UndefineCaretBidiLevel(); +#endif /** CharacterMove will generally be called from the nsiselectioncontroller implementations. * the effect being the selection will move one character left or right. @@ -619,6 +639,9 @@ private: PRInt16 mDisplaySelection; //for visual display purposes. HINT mHint; //hint to tell if the selection is at the end of this line or beginning of next +#ifdef IBMBIDI + PRInt8 mCaretBidiLevel; +#endif PRInt32 mDesiredX; nsIScrollableView *mScrollView; diff --git a/mozilla/layout/generic/nsSelection.cpp b/mozilla/layout/generic/nsSelection.cpp index bb42e0e3ce6..435e52d9687 100644 --- a/mozilla/layout/generic/nsSelection.cpp +++ b/mozilla/layout/generic/nsSelection.cpp @@ -109,6 +109,10 @@ static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); #include "nsCopySupport.h" #include "nsIClipboard.h" +#ifdef IBMBIDI +#include "nsIBidiKeyboard.h" +#endif // IBMBIDI + #define STATUS_CHECK_RETURN_MACRO() {if (!mShell) return NS_ERROR_FAILURE;} @@ -830,6 +834,9 @@ nsFrameSelection::nsFrameSelection() mMouseDoubleDownState = PR_FALSE; mHint = HINTLEFT; +#ifdef IBMBIDI + mCaretBidiLevel = BIDI_LEVEL_UNDEFINED; +#endif mDragSelectingCells = PR_FALSE; mSelectingTableCellMode = 0; mSelectedCellIndex = 0; @@ -1085,6 +1092,34 @@ nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree(nsIFrame *aFrame, return NS_OK; } +#ifdef IBMBIDI +void +nsFrameSelection::SetCaretBidiLevel(PRUint8 aLevel) +{ + // If the current level is undefined, we have just inserted new text. + // In this case, we don't want to reset the keyboard language + PRBool afterInsert = mCaretBidiLevel & BIDI_LEVEL_UNDEFINED; + mCaretBidiLevel = aLevel; + + nsIBidiKeyboard* bidiKeyboard = nsContentUtils::GetBidiKeyboard(); + if (bidiKeyboard && !afterInsert) + bidiKeyboard->SetLangFromBidiLevel(aLevel); + return; +} + +PRUint8 +nsFrameSelection::GetCaretBidiLevel() +{ + return mCaretBidiLevel; +} + +void +nsFrameSelection::UndefineCaretBidiLevel() +{ + mCaretBidiLevel |= BIDI_LEVEL_UNDEFINED; +} +#endif + #ifdef XP_MAC #pragma mark - #endif @@ -1350,7 +1385,7 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode, case nsIDOMKeyEvent::DOM_VK_HOME: case nsIDOMKeyEvent::DOM_VK_END: // set the caret Bidi level to the paragraph embedding level - mShell->SetCaretBidiLevel(NS_GET_BASE_LEVEL(theFrame)); + SetCaretBidiLevel(NS_GET_BASE_LEVEL(theFrame)); break; default: @@ -1358,7 +1393,7 @@ nsFrameSelection::MoveCaret(PRUint32 aKeycode, if ((pos.mContentOffset != frameStart && pos.mContentOffset != frameEnd) || (eSelectLine == aAmount)) { - mShell->SetCaretBidiLevel(NS_GET_EMBEDDING_LEVEL(theFrame)); + SetCaretBidiLevel(NS_GET_EMBEDDING_LEVEL(theFrame)); } else BidiLevelFromMove(mShell, pos.mResultContent, pos.mContentOffset, aKeycode, tHint); @@ -2068,9 +2103,6 @@ void nsFrameSelection::BidiLevelFromMove(nsIPresShell* aPresShell, PRUint32 aKeycode, HINT aHint) { - PRUint8 currentLevel; - aPresShell->GetCaretBidiLevel(¤tLevel); - switch (aKeycode) { // Right and Left: the new cursor Bidi level is the level of the character moved over @@ -2081,9 +2113,9 @@ void nsFrameSelection::BidiLevelFromMove(nsIPresShell* aPresShell, aHint, PR_FALSE); if (HINTLEFT == aHint) - aPresShell->SetCaretBidiLevel(levels.mLevelBefore); + SetCaretBidiLevel(levels.mLevelBefore); else - aPresShell->SetCaretBidiLevel(levels.mLevelAfter); + SetCaretBidiLevel(levels.mLevelAfter); break; } /* @@ -2096,7 +2128,7 @@ void nsFrameSelection::BidiLevelFromMove(nsIPresShell* aPresShell, */ default: - aPresShell->UndefineCaretBidiLevel(); + UndefineCaretBidiLevel(); } } @@ -2116,7 +2148,7 @@ void nsFrameSelection::BidiLevelFromClick(nsIContent *aNode, if (!clickInFrame) return; - mShell->SetCaretBidiLevel(NS_GET_EMBEDDING_LEVEL(clickInFrame)); + SetCaretBidiLevel(NS_GET_EMBEDDING_LEVEL(clickInFrame)); } @@ -4791,8 +4823,7 @@ nsTypedSelection::GetPrimaryFrameForFocusNode(nsIFrame **aReturnFrame, PRInt32 * nsFrameSelection::HINT hint = mFrameSelection->GetHint(); - PRUint8 caretBidiLevel; - presShell->GetCaretBidiLevel(&caretBidiLevel); + PRUint8 caretBidiLevel = mFrameSelection->GetCaretBidiLevel(); return caret->GetCaretFrameForNodeOffset(content, FetchFocusOffset(), hint, caretBidiLevel, aReturnFrame, aOffsetUsed); @@ -7433,10 +7464,6 @@ nsTypedSelection::SelectionLanguageChange(PRBool aLangRTL) levelAfter = levels.mLevelAfter; } - nsIPresShell* shell = context->GetPresShell(); - if (!shell) - return NS_ERROR_FAILURE; - if ((levelBefore & 1) == (levelAfter & 1)) { // if cursor is between two characters with the same orientation, changing the keyboard language // must toggle the cursor level between the level of the character with the lowest level @@ -7445,17 +7472,17 @@ nsTypedSelection::SelectionLanguageChange(PRBool aLangRTL) if ((level != levelBefore) && (level != levelAfter)) level = PR_MIN(levelBefore, levelAfter); if ((level & 1) == aLangRTL) - shell->SetCaretBidiLevel(level); + mFrameSelection->SetCaretBidiLevel(level); else - shell->SetCaretBidiLevel(level + 1); + mFrameSelection->SetCaretBidiLevel(level + 1); } else { // if cursor is between characters with opposite orientations, changing the keyboard language must change // the cursor level to that of the adjacent character with the orientation corresponding to the new language. if ((levelBefore & 1) == aLangRTL) - shell->SetCaretBidiLevel(levelBefore); + mFrameSelection->SetCaretBidiLevel(levelBefore); else - shell->SetCaretBidiLevel(levelAfter); + mFrameSelection->SetCaretBidiLevel(levelAfter); } // The caret might have moved, so invalidate the desired X position