summaryrefslogtreecommitdiff
path: root/dom/base/DirectionalityUtils.h
blob: 3948d81980f38cb9ba65a2782c990ce6d5fb3166 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef DirectionalityUtils_h___
#define DirectionalityUtils_h___

#include "nscore.h"

class nsIContent;
class nsAString;
class nsAttrValue;
class nsTextNode;

namespace mozilla {
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla

namespace mozilla {

enum Directionality : uint8_t {
  eDir_NotSet,
  eDir_RTL,
  eDir_LTR,
  eDir_Auto
};

/**
 * Set the directionality of an element according to the algorithm defined at
 * http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-directionality,
 * not including elements with auto direction.
 *
 * @return the directionality that the element was set to
 */
Directionality RecomputeDirectionality(mozilla::dom::Element* aElement,
                                       bool aNotify = true);

/**
 * Set the directionality of any descendants of a node that do not themselves
 * have a dir attribute.
 * For performance reasons we walk down the descendant tree in the rare case
 * of setting the dir attribute, rather than walking up the ancestor tree in
 * the much more common case of getting the element's directionality.
 */
void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement,
                                    Directionality aDir,
                                    bool aNotify = true);

/**
 * Walk the descendants of a node in tree order and, for any text node
 * descendant that determines the directionality of some element and is not a
 * descendant of another descendant of the original node with dir=auto,
 * redetermine that element's directionality
  */
void WalkDescendantsResetAutoDirection(mozilla::dom::Element* aElement);

/**
 * After setting dir=auto on an element, walk its descendants in tree order.
 * If the node doesn't have the NODE_ANCESTOR_HAS_DIR_AUTO flag, set the
 * NODE_ANCESTOR_HAS_DIR_AUTO flag on all of its descendants.
 * Resolve the directionality of the element by the "downward propagation
 * algorithm" (defined in section 3 in the comments at the beginning of
 * DirectionalityUtils.cpp)
 */
void WalkDescendantsSetDirAuto(mozilla::dom::Element* aElement,
                               bool aNotify = true);

/**
 * After unsetting dir=auto on an element, walk its descendants in tree order,
 * skipping any that have dir=auto themselves, and unset the
 * NODE_ANCESTOR_HAS_DIR_AUTO flag
 */
void WalkDescendantsClearAncestorDirAuto(mozilla::dom::Element* aElement);

/**
 * When the contents of a text node are about to change, retrieve the current
 * directionality of the text
 *
 * @return whether the text node affects the directionality of any element
 */
bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir,
                                 uint32_t aOffset);

/**
 * After the contents of a text node have changed, change the directionality
 * of any elements whose directionality is determined by that node
 */
void TextNodeChangedDirection(nsTextNode* aTextNode, Directionality aOldDir,
                              bool aNotify);

/**
 * When a text node is appended to an element, find any ancestors with dir=auto
 * whose directionality will be determined by the text node
 */
void SetDirectionFromNewTextNode(nsTextNode* aTextNode);

/**
 * When a text node is removed from a document, find any ancestors whose
 * directionality it determined and redetermine their directionality
 *
 * @param aTextNode the text node
 */
void ResetDirectionSetByTextNode(nsTextNode* aTextNode);

/**
 * Set the directionality of an element according to the directionality of the
 * text in aValue
 */
void SetDirectionalityFromValue(mozilla::dom::Element* aElement,
                                const nsAString& aValue,
                                bool aNotify);

/**
 * Called when setting the dir attribute on an element, immediately after
 * AfterSetAttr. This is instead of using BeforeSetAttr or AfterSetAttr, because
 * in AfterSetAttr we don't know the old value, so we can't identify all cases
 * where we need to walk up or down the document tree and reset the direction;
 * and in BeforeSetAttr we can't do the walk because this element hasn't had the
 * value set yet so the results will be wrong.
 */
void OnSetDirAttr(mozilla::dom::Element* aElement,
                  const nsAttrValue* aNewValue,
                  bool hadValidDir,
                  bool hadDirAuto,
                  bool aNotify);

/**
 * Called when binding a new element to the tree, to set the
 * NodeAncestorHasDirAuto flag and set the direction of the element and its
 * ancestors if necessary
 */
void SetDirOnBind(mozilla::dom::Element* aElement, nsIContent* aParent);

/**
 * Called when unbinding an element from the tree, to recompute the
 * directionality of the element if it doesn't have autodirection, and to
 * clean up any entries in nsTextDirectionalityMap that refer to it.
 */
void ResetDir(mozilla::dom::Element* aElement);
} // end namespace mozilla

#endif /* DirectionalityUtils_h___ */