From 0f48c5b4585428f76f85dd28517f73697c5146b4 Mon Sep 17 00:00:00 2001 From: "mkaply%us.ibm.com" Date: Mon, 21 May 2001 23:57:55 +0000 Subject: [PATCH] #80550 r=jfrancis, sr=sfraser, r=leaf for build changes Putting back Bidi selection code that was removed by 65557 git-svn-id: svn://10.0.0.236/trunk@95640 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/editor/base/Makefile.in | 8 +- mozilla/editor/base/makefile.win | 6 + mozilla/editor/base/nsHTMLEditRules.cpp | 12 +- mozilla/editor/base/nsTextEditRules.cpp | 70 ++------ mozilla/editor/base/nsTextEditRules.h | 15 +- mozilla/editor/base/nsTextEditRulesBidi.cpp | 149 ++++++++++++++++++ .../editor/libeditor/html/nsHTMLEditRules.cpp | 12 +- .../editor/libeditor/text/nsTextEditRules.cpp | 70 ++------ .../editor/libeditor/text/nsTextEditRules.h | 15 +- .../libeditor/text/nsTextEditRulesBidi.cpp | 149 ++++++++++++++++++ 10 files changed, 371 insertions(+), 135 deletions(-) create mode 100644 mozilla/editor/base/nsTextEditRulesBidi.cpp create mode 100644 mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp diff --git a/mozilla/editor/base/Makefile.in b/mozilla/editor/base/Makefile.in index 1403e3bd0b2..c815d59ae5c 100644 --- a/mozilla/editor/base/Makefile.in +++ b/mozilla/editor/base/Makefile.in @@ -66,6 +66,12 @@ CPPSRCS = \ SplitElementTxn.cpp \ TransactionFactory.cpp \ $(NULL) + +ifdef IBMBIDI +CPPSRCS += \ + nsTextEditRulesBidi.cpp \ + $(NULL) +endif # MOZ_BUILD_PLAINTEXT_EDITOR_CORE_ONLY=1 @@ -98,7 +104,7 @@ CPPSRCS += nsEditorParserObserver.cpp \ TypeInState.cpp \ SetDocTitleTxn.cpp \ $(NULL) - + # Enable Editor API Logging! ENABLE_EDITOR_API_LOG=1 diff --git a/mozilla/editor/base/makefile.win b/mozilla/editor/base/makefile.win index 1f700fbbf10..d8721123344 100644 --- a/mozilla/editor/base/makefile.win +++ b/mozilla/editor/base/makefile.win @@ -59,6 +59,9 @@ CPPSRCS = \ nsSelectionState.cpp \ nsStyleSheetTxns.cpp \ nsTextEditRules.cpp \ +!ifdef IBMBIDI + nsTextEditRulesBidi.cpp \ +!endif nsTextEditUtils.cpp \ nsWrapUtils.cpp \ PlaceholderTxn.cpp \ @@ -94,6 +97,9 @@ CPP_OBJS = \ .\$(OBJDIR)\nsSelectionState.obj \ .\$(OBJDIR)\nsStyleSheetTxns.obj \ .\$(OBJDIR)\nsTextEditRules.obj \ +!ifdef IBMBIDI + .\$(OBJDIR)\nsTextEditRulesBidi.obj \ +!endif .\$(OBJDIR)\nsTextEditUtils.obj \ .\$(OBJDIR)\PlaceholderTxn.obj \ .\$(OBJDIR)\SplitElementTxn.obj \ diff --git a/mozilla/editor/base/nsHTMLEditRules.cpp b/mozilla/editor/base/nsHTMLEditRules.cpp index 466c49f7d8a..ecab0c425a5 100644 --- a/mozilla/editor/base/nsHTMLEditRules.cpp +++ b/mozilla/editor/base/nsHTMLEditRules.cpp @@ -50,10 +50,6 @@ #include "nsIPresShell.h" #include "nsLayoutCID.h" #include "nsIPref.h" -#ifdef IBMBIDI -#include "nsIPresContext.h" -#include "nsIFrameSelection.h" -#endif // IBMBIDI #include "nsEditorUtils.h" #include "nsWSRunObject.h" @@ -1344,6 +1340,14 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection, return res; } } + +#ifdef IBMBIDI + // Test for distance between caret and text that will be deleted + res = CheckBidiLevelForDeletion(startNode, startOffset, aAction, aCancel); + if (NS_FAILED(res)) return res; + if (*aCancel) return NS_OK; +#endif // IBMBIDI + if (!bPlaintext) { // gather up ws data here. We may be next to non-significant ws. diff --git a/mozilla/editor/base/nsTextEditRules.cpp b/mozilla/editor/base/nsTextEditRules.cpp index 60858f85afc..f635b30a5f5 100644 --- a/mozilla/editor/base/nsTextEditRules.cpp +++ b/mozilla/editor/base/nsTextEditRules.cpp @@ -42,8 +42,8 @@ #include "EditTxn.h" #include "nsIPref.h" #ifdef IBMBIDI +#include "nsIPresShell.h" #include "nsIPresContext.h" -#include "nsIFrameSelection.h" #endif // IBMBIDI static NS_DEFINE_CID(kContentIteratorCID, NS_CONTENTITERATOR_CID); @@ -774,6 +774,8 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, } nsresult res = NS_OK; + nsCOMPtr startNode; + PRInt32 startOffset; if (mFlags & nsIPlaintextEditor::eEditorPasswordMask) { @@ -800,8 +802,7 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, res = aSelection->GetIsCollapsed(&bCollapsed); if (NS_FAILED(res)) return res; - nsCOMPtr startNode, nextNode, selNode; - PRInt32 startOffset; + nsCOMPtr nextNode, selNode; res = mEditor->GetStartNodeAndOffset(aSelection, address_of(startNode), &startOffset); if (NS_FAILED(res)) return res; @@ -809,6 +810,13 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, if (bCollapsed) { +#ifdef IBMBIDI + // Test for distance between caret and text that will be deleted + res = CheckBidiLevelForDeletion(startNode, startOffset, aCollapsedAction, aCancel); + if (NS_FAILED(res)) return res; + if (*aCancel) return NS_OK; +#endif // IBMBIDI + nsCOMPtr textNode; PRUint32 strLength; @@ -877,62 +885,6 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, } } -#ifdef IBMBIDI // Test for distance between caret and text that will be deleted - nsCOMPtr node; - PRInt32 offset; - - res = mEditor->GetStartNodeAndOffset(aSelection, address_of(node), &offset); - if (NS_FAILED(res)) return res; - if (!node) return NS_ERROR_FAILURE; - nsCOMPtr shell; - mEditor->GetPresShell(getter_AddRefs(shell)); - if (shell) - { - nsCOMPtr context; - shell->GetPresContext(getter_AddRefs(context)); - if (context) - { - PRBool bidiEnabled; - context->GetBidiEnabled(&bidiEnabled); - if (bidiEnabled) - { - nsCOMPtr frameSelection; - shell->GetFrameSelection(getter_AddRefs(frameSelection)); - if (frameSelection) - { - nsCOMPtr content = do_QueryInterface(node); - if (content) - { - nsIFrame *deleteInFrame; - PRInt32 frameOffset; - - shell->GetPrimaryFrameFor(content, &deleteInFrame); - if (deleteInFrame) - { - PRUint8 currentCursorLevel; - long frameLevel; - - res = deleteInFrame->GetChildFrameContainingOffset(offset, nsIEditor::eNext==aCollapsedAction, &frameOffset, &deleteInFrame); - if (NS_SUCCEEDED(res) && deleteInFrame) - { - shell->GetCursorBidiLevel(¤tCursorLevel); - nsCOMPtr embeddingLevel = NS_NewAtom("EmbeddingLevel"); - deleteInFrame->GetBidiProperty(context, embeddingLevel, (void**)&frameLevel); - shell->SetCursorBidiLevel(frameLevel); - if (currentCursorLevel != frameLevel) - { - *aCancel = PR_TRUE; - return NS_OK; - } - } - } - } - } - } - } - } -#endif // IBMBIDI - return res; } diff --git a/mozilla/editor/base/nsTextEditRules.h b/mozilla/editor/base/nsTextEditRules.h index da3360aed00..86dd04f122e 100644 --- a/mozilla/editor/base/nsTextEditRules.h +++ b/mozilla/editor/base/nsTextEditRules.h @@ -150,10 +150,10 @@ protected: /** returns a truncated insertion string if insertion would place us over aMaxLength */ - nsresult TruncateInsertionIfNeeded(nsISelection *aSelection, - const nsAReadableString *aInString, - nsAWritableString *aOutString, - PRInt32 aMaxLength); + nsresult TruncateInsertionIfNeeded(nsISelection *aSelection, + const nsAReadableString *aInString, + nsAWritableString *aOutString, + PRInt32 aMaxLength); /** Echo's the insertion text into the password buffer, and converts insertion text to '*'s */ @@ -163,6 +163,13 @@ protected: PRBool DeleteEmptyTextNode(nsIDOMNode *aNode); +#ifdef IBMBIDI + nsresult CheckBidiLevelForDeletion(nsIDOMNode *aSelNode, + PRInt32 aSelOffset, + nsIEditor::EDirection aAction, + PRBool *aCancel); +#endif // IBMBIDI + // data members nsPlaintextEditor *mEditor; // note that we do not refcount the editor nsString mPasswordText; // a buffer we use to store the real value of password editors diff --git a/mozilla/editor/base/nsTextEditRulesBidi.cpp b/mozilla/editor/base/nsTextEditRulesBidi.cpp new file mode 100644 index 00000000000..1e7d081bb48 --- /dev/null +++ b/mozilla/editor/base/nsTextEditRulesBidi.cpp @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsTextEditRules.h" +#include "nsCOMPtr.h" +#include "nsIDOMNode.h" +#include "nsIContent.h" +#include "nsIPresShell.h" +#include "nsIPresContext.h" +#include "nsIFrame.h" + +// Test for distance between caret and text that will be deleted +nsresult +nsTextEditRules::CheckBidiLevelForDeletion(nsIDOMNode *aSelNode, + PRInt32 aSelOffset, + nsIEditor::EDirection aAction, + PRBool *aCancel) +{ + NS_ENSURE_ARG_POINTER(aCancel); + *aCancel = PR_FALSE; + nsresult res = NS_OK; + + nsCOMPtr shell; + res = mEditor->GetPresShell(getter_AddRefs(shell)); + if (NS_FAILED(res)) + return res; + if (!shell) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr context; + res = shell->GetPresContext(getter_AddRefs(context)); + if (NS_FAILED(res)) + return res; + if (!context) + return NS_ERROR_NULL_POINTER; + + PRBool bidiEnabled; + context->GetBidiEnabled(&bidiEnabled); + if (!bidiEnabled) + return NS_OK; + + nsCOMPtr content = do_QueryInterface(aSelNode); + if (!content) + return NS_ERROR_NULL_POINTER; + + nsIFrame *primaryFrame; + nsIFrame *frameBefore; + nsIFrame *frameAfter; + PRInt32 frameOffset; + + res = shell->GetPrimaryFrameFor(content, &primaryFrame); + if (NS_FAILED(res)) + return res; + if (!primaryFrame) + return NS_ERROR_NULL_POINTER; + + res = primaryFrame->GetChildFrameContainingOffset(aSelOffset, PR_FALSE, &frameOffset, &frameBefore); + if (NS_FAILED(res)) + return res; + if (!frameBefore) + return NS_ERROR_NULL_POINTER; + + PRInt32 start, end; + PRUint8 currentCursorLevel; + PRUint8 levelAfter; + PRUint8 levelBefore; + PRUint8 levelOfDeletion; + nsCOMPtr embeddingLevel = getter_AddRefs(NS_NewAtom("EmbeddingLevel")); + nsCOMPtr baseLevel = getter_AddRefs(NS_NewAtom("BaseLevel")); + + // Get the bidi level of the frame before the caret + res = frameBefore->GetBidiProperty(context, embeddingLevel, (void**)&levelBefore); + if (NS_FAILED(res)) + return res; + + // If the caret is at the end of the frame, get the bidi level of the + // frame after the caret + frameBefore->GetOffsets(start, end); + if (aSelOffset == end + || aSelOffset == -1) + { + res = primaryFrame->GetChildFrameContainingOffset(aSelOffset, PR_TRUE, &frameOffset, &frameAfter); + if (NS_FAILED(res)) + return res; + if (!frameAfter) + return NS_ERROR_NULL_POINTER; + + if (frameBefore==frameAfter) + { + // there was no frameAfter, i.e. the caret is at the end of the + // document -- use the base paragraph level + res = frameBefore->GetBidiProperty(context, baseLevel, (void**)&levelAfter); + if (NS_FAILED(res)) + return res; + } + else + { + res = frameAfter->GetBidiProperty(context, embeddingLevel, (void**)&levelAfter); + if (NS_FAILED(res)) + return res; + } + } + else + { + levelAfter = levelBefore; + } + res = shell->GetCursorBidiLevel(¤tCursorLevel); + if (NS_FAILED(res)) + return res; + levelOfDeletion = (nsIEditor::eNext==aAction) ? levelAfter : levelBefore; + + if (currentCursorLevel == levelOfDeletion) + ; // perform the deletion + else + { + if ((levelBefore==levelAfter) + && (levelBefore & 1) == (currentCursorLevel & 1)) + ; // perform the deletion + else + *aCancel = PR_TRUE; + + // Set the bidi level of the caret to that of the + // character that will be (or would have been) deleted + res = shell->SetCursorBidiLevel(levelOfDeletion); + if (NS_FAILED(res)) + return res; + } + return NS_OK; +} + diff --git a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp index 466c49f7d8a..ecab0c425a5 100644 --- a/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/mozilla/editor/libeditor/html/nsHTMLEditRules.cpp @@ -50,10 +50,6 @@ #include "nsIPresShell.h" #include "nsLayoutCID.h" #include "nsIPref.h" -#ifdef IBMBIDI -#include "nsIPresContext.h" -#include "nsIFrameSelection.h" -#endif // IBMBIDI #include "nsEditorUtils.h" #include "nsWSRunObject.h" @@ -1344,6 +1340,14 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection, return res; } } + +#ifdef IBMBIDI + // Test for distance between caret and text that will be deleted + res = CheckBidiLevelForDeletion(startNode, startOffset, aAction, aCancel); + if (NS_FAILED(res)) return res; + if (*aCancel) return NS_OK; +#endif // IBMBIDI + if (!bPlaintext) { // gather up ws data here. We may be next to non-significant ws. diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.cpp b/mozilla/editor/libeditor/text/nsTextEditRules.cpp index 60858f85afc..f635b30a5f5 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.cpp +++ b/mozilla/editor/libeditor/text/nsTextEditRules.cpp @@ -42,8 +42,8 @@ #include "EditTxn.h" #include "nsIPref.h" #ifdef IBMBIDI +#include "nsIPresShell.h" #include "nsIPresContext.h" -#include "nsIFrameSelection.h" #endif // IBMBIDI static NS_DEFINE_CID(kContentIteratorCID, NS_CONTENTITERATOR_CID); @@ -774,6 +774,8 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, } nsresult res = NS_OK; + nsCOMPtr startNode; + PRInt32 startOffset; if (mFlags & nsIPlaintextEditor::eEditorPasswordMask) { @@ -800,8 +802,7 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, res = aSelection->GetIsCollapsed(&bCollapsed); if (NS_FAILED(res)) return res; - nsCOMPtr startNode, nextNode, selNode; - PRInt32 startOffset; + nsCOMPtr nextNode, selNode; res = mEditor->GetStartNodeAndOffset(aSelection, address_of(startNode), &startOffset); if (NS_FAILED(res)) return res; @@ -809,6 +810,13 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, if (bCollapsed) { +#ifdef IBMBIDI + // Test for distance between caret and text that will be deleted + res = CheckBidiLevelForDeletion(startNode, startOffset, aCollapsedAction, aCancel); + if (NS_FAILED(res)) return res; + if (*aCancel) return NS_OK; +#endif // IBMBIDI + nsCOMPtr textNode; PRUint32 strLength; @@ -877,62 +885,6 @@ nsTextEditRules::WillDeleteSelection(nsISelection *aSelection, } } -#ifdef IBMBIDI // Test for distance between caret and text that will be deleted - nsCOMPtr node; - PRInt32 offset; - - res = mEditor->GetStartNodeAndOffset(aSelection, address_of(node), &offset); - if (NS_FAILED(res)) return res; - if (!node) return NS_ERROR_FAILURE; - nsCOMPtr shell; - mEditor->GetPresShell(getter_AddRefs(shell)); - if (shell) - { - nsCOMPtr context; - shell->GetPresContext(getter_AddRefs(context)); - if (context) - { - PRBool bidiEnabled; - context->GetBidiEnabled(&bidiEnabled); - if (bidiEnabled) - { - nsCOMPtr frameSelection; - shell->GetFrameSelection(getter_AddRefs(frameSelection)); - if (frameSelection) - { - nsCOMPtr content = do_QueryInterface(node); - if (content) - { - nsIFrame *deleteInFrame; - PRInt32 frameOffset; - - shell->GetPrimaryFrameFor(content, &deleteInFrame); - if (deleteInFrame) - { - PRUint8 currentCursorLevel; - long frameLevel; - - res = deleteInFrame->GetChildFrameContainingOffset(offset, nsIEditor::eNext==aCollapsedAction, &frameOffset, &deleteInFrame); - if (NS_SUCCEEDED(res) && deleteInFrame) - { - shell->GetCursorBidiLevel(¤tCursorLevel); - nsCOMPtr embeddingLevel = NS_NewAtom("EmbeddingLevel"); - deleteInFrame->GetBidiProperty(context, embeddingLevel, (void**)&frameLevel); - shell->SetCursorBidiLevel(frameLevel); - if (currentCursorLevel != frameLevel) - { - *aCancel = PR_TRUE; - return NS_OK; - } - } - } - } - } - } - } - } -#endif // IBMBIDI - return res; } diff --git a/mozilla/editor/libeditor/text/nsTextEditRules.h b/mozilla/editor/libeditor/text/nsTextEditRules.h index da3360aed00..86dd04f122e 100644 --- a/mozilla/editor/libeditor/text/nsTextEditRules.h +++ b/mozilla/editor/libeditor/text/nsTextEditRules.h @@ -150,10 +150,10 @@ protected: /** returns a truncated insertion string if insertion would place us over aMaxLength */ - nsresult TruncateInsertionIfNeeded(nsISelection *aSelection, - const nsAReadableString *aInString, - nsAWritableString *aOutString, - PRInt32 aMaxLength); + nsresult TruncateInsertionIfNeeded(nsISelection *aSelection, + const nsAReadableString *aInString, + nsAWritableString *aOutString, + PRInt32 aMaxLength); /** Echo's the insertion text into the password buffer, and converts insertion text to '*'s */ @@ -163,6 +163,13 @@ protected: PRBool DeleteEmptyTextNode(nsIDOMNode *aNode); +#ifdef IBMBIDI + nsresult CheckBidiLevelForDeletion(nsIDOMNode *aSelNode, + PRInt32 aSelOffset, + nsIEditor::EDirection aAction, + PRBool *aCancel); +#endif // IBMBIDI + // data members nsPlaintextEditor *mEditor; // note that we do not refcount the editor nsString mPasswordText; // a buffer we use to store the real value of password editors diff --git a/mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp b/mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp new file mode 100644 index 00000000000..1e7d081bb48 --- /dev/null +++ b/mozilla/editor/libeditor/text/nsTextEditRulesBidi.cpp @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#include "nsTextEditRules.h" +#include "nsCOMPtr.h" +#include "nsIDOMNode.h" +#include "nsIContent.h" +#include "nsIPresShell.h" +#include "nsIPresContext.h" +#include "nsIFrame.h" + +// Test for distance between caret and text that will be deleted +nsresult +nsTextEditRules::CheckBidiLevelForDeletion(nsIDOMNode *aSelNode, + PRInt32 aSelOffset, + nsIEditor::EDirection aAction, + PRBool *aCancel) +{ + NS_ENSURE_ARG_POINTER(aCancel); + *aCancel = PR_FALSE; + nsresult res = NS_OK; + + nsCOMPtr shell; + res = mEditor->GetPresShell(getter_AddRefs(shell)); + if (NS_FAILED(res)) + return res; + if (!shell) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr context; + res = shell->GetPresContext(getter_AddRefs(context)); + if (NS_FAILED(res)) + return res; + if (!context) + return NS_ERROR_NULL_POINTER; + + PRBool bidiEnabled; + context->GetBidiEnabled(&bidiEnabled); + if (!bidiEnabled) + return NS_OK; + + nsCOMPtr content = do_QueryInterface(aSelNode); + if (!content) + return NS_ERROR_NULL_POINTER; + + nsIFrame *primaryFrame; + nsIFrame *frameBefore; + nsIFrame *frameAfter; + PRInt32 frameOffset; + + res = shell->GetPrimaryFrameFor(content, &primaryFrame); + if (NS_FAILED(res)) + return res; + if (!primaryFrame) + return NS_ERROR_NULL_POINTER; + + res = primaryFrame->GetChildFrameContainingOffset(aSelOffset, PR_FALSE, &frameOffset, &frameBefore); + if (NS_FAILED(res)) + return res; + if (!frameBefore) + return NS_ERROR_NULL_POINTER; + + PRInt32 start, end; + PRUint8 currentCursorLevel; + PRUint8 levelAfter; + PRUint8 levelBefore; + PRUint8 levelOfDeletion; + nsCOMPtr embeddingLevel = getter_AddRefs(NS_NewAtom("EmbeddingLevel")); + nsCOMPtr baseLevel = getter_AddRefs(NS_NewAtom("BaseLevel")); + + // Get the bidi level of the frame before the caret + res = frameBefore->GetBidiProperty(context, embeddingLevel, (void**)&levelBefore); + if (NS_FAILED(res)) + return res; + + // If the caret is at the end of the frame, get the bidi level of the + // frame after the caret + frameBefore->GetOffsets(start, end); + if (aSelOffset == end + || aSelOffset == -1) + { + res = primaryFrame->GetChildFrameContainingOffset(aSelOffset, PR_TRUE, &frameOffset, &frameAfter); + if (NS_FAILED(res)) + return res; + if (!frameAfter) + return NS_ERROR_NULL_POINTER; + + if (frameBefore==frameAfter) + { + // there was no frameAfter, i.e. the caret is at the end of the + // document -- use the base paragraph level + res = frameBefore->GetBidiProperty(context, baseLevel, (void**)&levelAfter); + if (NS_FAILED(res)) + return res; + } + else + { + res = frameAfter->GetBidiProperty(context, embeddingLevel, (void**)&levelAfter); + if (NS_FAILED(res)) + return res; + } + } + else + { + levelAfter = levelBefore; + } + res = shell->GetCursorBidiLevel(¤tCursorLevel); + if (NS_FAILED(res)) + return res; + levelOfDeletion = (nsIEditor::eNext==aAction) ? levelAfter : levelBefore; + + if (currentCursorLevel == levelOfDeletion) + ; // perform the deletion + else + { + if ((levelBefore==levelAfter) + && (levelBefore & 1) == (currentCursorLevel & 1)) + ; // perform the deletion + else + *aCancel = PR_TRUE; + + // Set the bidi level of the caret to that of the + // character that will be (or would have been) deleted + res = shell->SetCursorBidiLevel(levelOfDeletion); + if (NS_FAILED(res)) + return res; + } + return NS_OK; +} +