Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "mozilla/TextEditRules.h"
7 :
8 : #include "mozilla/TextEditor.h"
9 : #include "mozilla/dom/Selection.h"
10 : #include "nsCOMPtr.h"
11 : #include "nsDebug.h"
12 : #include "nsError.h"
13 : #include "nsFrameSelection.h"
14 : #include "nsIContent.h"
15 : #include "nsIDOMNode.h"
16 : #include "nsIEditor.h"
17 : #include "nsIPresShell.h"
18 : #include "nsISupportsImpl.h"
19 : #include "nsPresContext.h"
20 : #include "nscore.h"
21 :
22 : namespace mozilla {
23 :
24 : using namespace dom;
25 :
26 : // Test for distance between caret and text that will be deleted
27 : nsresult
28 0 : TextEditRules::CheckBidiLevelForDeletion(Selection* aSelection,
29 : nsIDOMNode* aSelNode,
30 : int32_t aSelOffset,
31 : nsIEditor::EDirection aAction,
32 : bool* aCancel)
33 : {
34 0 : NS_ENSURE_ARG_POINTER(aCancel);
35 0 : *aCancel = false;
36 :
37 0 : nsCOMPtr<nsIPresShell> shell = mTextEditor->GetPresShell();
38 0 : NS_ENSURE_TRUE(shell, NS_ERROR_NOT_INITIALIZED);
39 :
40 0 : nsPresContext *context = shell->GetPresContext();
41 0 : NS_ENSURE_TRUE(context, NS_ERROR_NULL_POINTER);
42 :
43 0 : if (!context->BidiEnabled()) {
44 0 : return NS_OK;
45 : }
46 :
47 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(aSelNode);
48 0 : NS_ENSURE_TRUE(content, NS_ERROR_NULL_POINTER);
49 :
50 : nsBidiLevel levelBefore;
51 : nsBidiLevel levelAfter;
52 : RefPtr<nsFrameSelection> frameSelection =
53 0 : aSelection->AsSelection()->GetFrameSelection();
54 0 : NS_ENSURE_TRUE(frameSelection, NS_ERROR_NULL_POINTER);
55 :
56 : nsPrevNextBidiLevels levels = frameSelection->
57 0 : GetPrevNextBidiLevels(content, aSelOffset, true);
58 :
59 0 : levelBefore = levels.mLevelBefore;
60 0 : levelAfter = levels.mLevelAfter;
61 :
62 0 : nsBidiLevel currentCaretLevel = frameSelection->GetCaretBidiLevel();
63 :
64 : nsBidiLevel levelOfDeletion;
65 0 : levelOfDeletion =
66 0 : (nsIEditor::eNext==aAction || nsIEditor::eNextWord==aAction) ?
67 : levelAfter : levelBefore;
68 :
69 0 : if (currentCaretLevel == levelOfDeletion) {
70 0 : return NS_OK; // perform the deletion
71 : }
72 :
73 0 : if (!mDeleteBidiImmediately && levelBefore != levelAfter) {
74 0 : *aCancel = true;
75 : }
76 :
77 : // Set the bidi level of the caret to that of the
78 : // character that will be (or would have been) deleted
79 0 : frameSelection->SetCaretBidiLevel(levelOfDeletion);
80 0 : return NS_OK;
81 : }
82 :
83 : void
84 1 : TextEditRules::UndefineCaretBidiLevel(Selection* aSelection)
85 : {
86 : /**
87 : * After inserting text the caret Bidi level must be set to the level of the
88 : * inserted text.This is difficult, because we cannot know what the level is
89 : * until after the Bidi algorithm is applied to the whole paragraph.
90 : *
91 : * So we set the caret Bidi level to UNDEFINED here, and the caret code will
92 : * set it correctly later
93 : */
94 2 : RefPtr<nsFrameSelection> frameSelection = aSelection->GetFrameSelection();
95 1 : if (frameSelection) {
96 1 : frameSelection->UndefineCaretBidiLevel();
97 : }
98 1 : }
99 :
100 : } // namespace mozilla
|