зеркало из https://github.com/mozilla/gecko-dev.git
r=jfrancis, sr=sfraser, r=leaf for build changes Putting back Bidi selection code that was removed by 65557
This commit is contained in:
Родитель
7f6ec20ca4
Коммит
18a8225acf
|
@ -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
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<nsIDOMNode> 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<nsIDOMNode> startNode, nextNode, selNode;
|
||||
PRInt32 startOffset;
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMText> 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<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = mEditor->GetStartNodeAndOffset(aSelection, address_of(node), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!node) return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mEditor->GetPresShell(getter_AddRefs(shell));
|
||||
if (shell)
|
||||
{
|
||||
nsCOMPtr<nsIPresContext> context;
|
||||
shell->GetPresContext(getter_AddRefs(context));
|
||||
if (context)
|
||||
{
|
||||
PRBool bidiEnabled;
|
||||
context->GetBidiEnabled(&bidiEnabled);
|
||||
if (bidiEnabled)
|
||||
{
|
||||
nsCOMPtr<nsIFrameSelection> frameSelection;
|
||||
shell->GetFrameSelection(getter_AddRefs(frameSelection));
|
||||
if (frameSelection)
|
||||
{
|
||||
nsCOMPtr<nsIContent> 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<nsIAtom> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<nsIPresShell> shell;
|
||||
res = mEditor->GetPresShell(getter_AddRefs(shell));
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
if (!shell)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIPresContext> 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<nsIContent> 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<nsIAtom> embeddingLevel = getter_AddRefs(NS_NewAtom("EmbeddingLevel"));
|
||||
nsCOMPtr<nsIAtom> 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;
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
|
@ -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<nsIDOMNode> 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<nsIDOMNode> startNode, nextNode, selNode;
|
||||
PRInt32 startOffset;
|
||||
nsCOMPtr<nsIDOMNode> 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<nsIDOMText> 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<nsIDOMNode> node;
|
||||
PRInt32 offset;
|
||||
|
||||
res = mEditor->GetStartNodeAndOffset(aSelection, address_of(node), &offset);
|
||||
if (NS_FAILED(res)) return res;
|
||||
if (!node) return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
mEditor->GetPresShell(getter_AddRefs(shell));
|
||||
if (shell)
|
||||
{
|
||||
nsCOMPtr<nsIPresContext> context;
|
||||
shell->GetPresContext(getter_AddRefs(context));
|
||||
if (context)
|
||||
{
|
||||
PRBool bidiEnabled;
|
||||
context->GetBidiEnabled(&bidiEnabled);
|
||||
if (bidiEnabled)
|
||||
{
|
||||
nsCOMPtr<nsIFrameSelection> frameSelection;
|
||||
shell->GetFrameSelection(getter_AddRefs(frameSelection));
|
||||
if (frameSelection)
|
||||
{
|
||||
nsCOMPtr<nsIContent> 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<nsIAtom> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<nsIPresShell> shell;
|
||||
res = mEditor->GetPresShell(getter_AddRefs(shell));
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
if (!shell)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIPresContext> 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<nsIContent> 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<nsIAtom> embeddingLevel = getter_AddRefs(NS_NewAtom("EmbeddingLevel"));
|
||||
nsCOMPtr<nsIAtom> 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;
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче