michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsAutoPtr.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsDebug.h" michael@0: #include "nsError.h" michael@0: #include "nsFrameSelection.h" michael@0: #include "nsIContent.h" michael@0: #include "nsIDOMNode.h" michael@0: #include "nsIEditor.h" michael@0: #include "nsIPresShell.h" michael@0: #include "mozilla/dom/Selection.h" michael@0: #include "nsISelectionPrivate.h" michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsPlaintextEditor.h" michael@0: #include "nsPresContext.h" michael@0: #include "nsTextEditRules.h" michael@0: #include "nscore.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::dom; michael@0: michael@0: // Test for distance between caret and text that will be deleted michael@0: nsresult michael@0: nsTextEditRules::CheckBidiLevelForDeletion(nsISelection *aSelection, michael@0: nsIDOMNode *aSelNode, michael@0: int32_t aSelOffset, michael@0: nsIEditor::EDirection aAction, michael@0: bool *aCancel) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aCancel); michael@0: *aCancel = false; michael@0: michael@0: nsCOMPtr shell = mEditor->GetPresShell(); michael@0: NS_ENSURE_TRUE(shell, NS_ERROR_NOT_INITIALIZED); michael@0: michael@0: nsPresContext *context = shell->GetPresContext(); michael@0: NS_ENSURE_TRUE(context, NS_ERROR_NULL_POINTER); michael@0: michael@0: if (!context->BidiEnabled()) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr content = do_QueryInterface(aSelNode); michael@0: NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER); michael@0: michael@0: uint8_t levelBefore; michael@0: uint8_t levelAfter; michael@0: nsRefPtr frameSelection = michael@0: static_cast(aSelection)->GetFrameSelection(); michael@0: NS_ENSURE_TRUE(frameSelection, NS_ERROR_NULL_POINTER); michael@0: michael@0: nsPrevNextBidiLevels levels = frameSelection-> michael@0: GetPrevNextBidiLevels(content, aSelOffset, true); michael@0: michael@0: levelBefore = levels.mLevelBefore; michael@0: levelAfter = levels.mLevelAfter; michael@0: michael@0: uint8_t currentCaretLevel = frameSelection->GetCaretBidiLevel(); michael@0: michael@0: uint8_t levelOfDeletion; michael@0: levelOfDeletion = michael@0: (nsIEditor::eNext==aAction || nsIEditor::eNextWord==aAction) ? michael@0: levelAfter : levelBefore; michael@0: michael@0: if (currentCaretLevel == levelOfDeletion) michael@0: ; // perform the deletion michael@0: else michael@0: { michael@0: if (mDeleteBidiImmediately || levelBefore == levelAfter) michael@0: ; // perform the deletion michael@0: else michael@0: *aCancel = true; michael@0: michael@0: // Set the bidi level of the caret to that of the michael@0: // character that will be (or would have been) deleted michael@0: frameSelection->SetCaretBidiLevel(levelOfDeletion); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: