Blame editor/libeditor/TextEditRulesBidi.cpp

Packit f0b94e
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#include "mozilla/TextEditRules.h"
Packit f0b94e
Packit f0b94e
#include "mozilla/TextEditor.h"
Packit f0b94e
#include "mozilla/dom/Selection.h"
Packit f0b94e
#include "nsCOMPtr.h"
Packit f0b94e
#include "nsDebug.h"
Packit f0b94e
#include "nsError.h"
Packit f0b94e
#include "nsFrameSelection.h"
Packit f0b94e
#include "nsIContent.h"
Packit f0b94e
#include "nsIEditor.h"
Packit f0b94e
#include "nsIPresShell.h"
Packit f0b94e
#include "nsISupportsImpl.h"
Packit f0b94e
#include "nsPresContext.h"
Packit f0b94e
#include "nscore.h"
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
Packit f0b94e
using namespace dom;
Packit f0b94e
Packit f0b94e
// Test for distance between caret and text that will be deleted
Packit f0b94e
nsresult TextEditRules::CheckBidiLevelForDeletion(Selection* aSelection,
Packit f0b94e
                                                  nsINode* aSelNode,
Packit f0b94e
                                                  int32_t aSelOffset,
Packit f0b94e
                                                  nsIEditor::EDirection aAction,
Packit f0b94e
                                                  bool* aCancel) {
Packit f0b94e
  NS_ENSURE_ARG_POINTER(aCancel);
Packit f0b94e
  *aCancel = false;
Packit f0b94e
Packit f0b94e
  nsCOMPtr<nsIPresShell> shell = mTextEditor->GetPresShell();
Packit f0b94e
  NS_ENSURE_TRUE(shell, NS_ERROR_NOT_INITIALIZED);
Packit f0b94e
Packit f0b94e
  nsPresContext* context = shell->GetPresContext();
Packit f0b94e
  NS_ENSURE_TRUE(context, NS_ERROR_NULL_POINTER);
Packit f0b94e
Packit f0b94e
  if (!context->BidiEnabled()) {
Packit f0b94e
    return NS_OK;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  if (!aSelNode || !aSelNode->IsContent()) {
Packit f0b94e
    return NS_ERROR_NULL_POINTER;
Packit f0b94e
  }
Packit f0b94e
  nsCOMPtr<nsIContent> content = aSelNode->AsContent();
Packit f0b94e
Packit f0b94e
  nsBidiLevel levelBefore;
Packit f0b94e
  nsBidiLevel levelAfter;
Packit f0b94e
  RefPtr<nsFrameSelection> frameSelection =
Packit f0b94e
      aSelection->AsSelection()->GetFrameSelection();
Packit f0b94e
  NS_ENSURE_TRUE(frameSelection, NS_ERROR_NULL_POINTER);
Packit f0b94e
Packit f0b94e
  nsPrevNextBidiLevels levels =
Packit f0b94e
      frameSelection->GetPrevNextBidiLevels(content, aSelOffset, true);
Packit f0b94e
Packit f0b94e
  levelBefore = levels.mLevelBefore;
Packit f0b94e
  levelAfter = levels.mLevelAfter;
Packit f0b94e
Packit f0b94e
  nsBidiLevel currentCaretLevel = frameSelection->GetCaretBidiLevel();
Packit f0b94e
Packit f0b94e
  nsBidiLevel levelOfDeletion;
Packit f0b94e
  levelOfDeletion =
Packit f0b94e
      (nsIEditor::eNext == aAction || nsIEditor::eNextWord == aAction)
Packit f0b94e
          ? levelAfter
Packit f0b94e
          : levelBefore;
Packit f0b94e
Packit f0b94e
  if (currentCaretLevel == levelOfDeletion) {
Packit f0b94e
    return NS_OK;  // perform the deletion
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  if (!mDeleteBidiImmediately && levelBefore != levelAfter) {
Packit f0b94e
    *aCancel = true;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Set the bidi level of the caret to that of the
Packit f0b94e
  // character that will be (or would have been) deleted
Packit f0b94e
  frameSelection->SetCaretBidiLevel(levelOfDeletion);
Packit f0b94e
  return NS_OK;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
void TextEditRules::UndefineCaretBidiLevel(Selection* aSelection) {
Packit f0b94e
  /**
Packit f0b94e
   * After inserting text the caret Bidi level must be set to the level of the
Packit f0b94e
   * inserted text.This is difficult, because we cannot know what the level is
Packit f0b94e
   * until after the Bidi algorithm is applied to the whole paragraph.
Packit f0b94e
   *
Packit f0b94e
   * So we set the caret Bidi level to UNDEFINED here, and the caret code will
Packit f0b94e
   * set it correctly later
Packit f0b94e
   */
Packit f0b94e
  RefPtr<nsFrameSelection> frameSelection = aSelection->GetFrameSelection();
Packit f0b94e
  if (frameSelection) {
Packit f0b94e
    frameSelection->UndefineCaretBidiLevel();
Packit f0b94e
  }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
}  // namespace mozilla