DirectionalityUtils.h (6417B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef DirectionalityUtils_h___ 8 #define DirectionalityUtils_h___ 9 10 #include "nsStringFwd.h" 11 #include "nscore.h" 12 13 class nsIContent; 14 class nsINode; 15 class nsAttrValue; 16 17 namespace mozilla::dom { 18 class Element; 19 class HTMLSlotElement; 20 class Text; 21 struct UnbindContext; 22 } // namespace mozilla::dom 23 24 namespace mozilla { 25 26 enum class Directionality : uint8_t { Unset, Rtl, Ltr, Auto }; 27 28 /** 29 * Various methods for returning the directionality of a string using the 30 * first-strong algorithm defined in http://unicode.org/reports/tr9/#P2 31 * 32 * @param[out] aFirstStrong the offset to the first character in the string with 33 * strong directionality, or UINT32_MAX if there is none (in which 34 * case the return value is Directionality::Unset). 35 * @return the directionality of the string, or Unset if not available. 36 */ 37 Directionality GetDirectionFromText(const char16_t* aText, 38 const uint32_t aLength, 39 uint32_t* aFirstStrong = nullptr); 40 41 /** 42 * Set the directionality of an element according to the algorithm defined at 43 * https://html.spec.whatwg.org/#the-directionality, not including elements with 44 * auto direction. 45 * 46 * @return the directionality that the element was set to 47 */ 48 Directionality RecomputeDirectionality(mozilla::dom::Element* aElement, 49 bool aNotify = true); 50 51 /** 52 * https://html.spec.whatwg.org/#parent-directionality 53 */ 54 Directionality GetParentDirectionality(const mozilla::dom::Element* aElement); 55 56 /** 57 * Set the directionality of any descendants of a node that do not themselves 58 * have a dir attribute. 59 * For performance reasons we walk down the descendant tree in the rare case 60 * of setting the dir attribute, rather than walking up the ancestor tree in 61 * the much more common case of getting the element's directionality. 62 */ 63 void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement, 64 Directionality aDir, bool aNotify = true); 65 66 /** 67 * Walk the descendants of a node in tree order and, for any text node 68 * descendant that determines the directionality of some element and is not a 69 * descendant of another descendant of the original node with dir=auto, 70 * redetermine that element's directionality 71 */ 72 void WalkDescendantsResetAutoDirection(mozilla::dom::Element* aElement); 73 74 /** 75 * In case a element was added to a slot it may change the directionality 76 * of ancestors or assigned nodes. 77 */ 78 void SlotAssignedNodeAdded(dom::HTMLSlotElement* aSlot, 79 nsIContent& aAssignedNode); 80 81 /** 82 * In case a element was removed from a slot it may change the directionality 83 * of ancestors or assigned nodes. 84 */ 85 void SlotAssignedNodeRemoved(dom::HTMLSlotElement* aSlot, 86 nsIContent& aUnassignedNode); 87 88 /** 89 * After setting dir=auto on an element, walk its descendants in tree order. 90 * If the node doesn't have the NODE_ANCESTOR_HAS_DIR_AUTO flag, set the 91 * NODE_ANCESTOR_HAS_DIR_AUTO flag on all of its descendants. 92 * Resolve the directionality of the element by the "downward propagation 93 * algorithm" (defined in section 3 in the comments at the beginning of 94 * DirectionalityUtils.cpp) 95 */ 96 void WalkDescendantsSetDirAuto(mozilla::dom::Element* aElement, 97 bool aNotify = true); 98 99 /** 100 * After unsetting dir=auto on an element, walk its descendants in tree order, 101 * skipping any that have dir=auto themselves, and unset the 102 * NODE_ANCESTOR_HAS_DIR_AUTO flag 103 */ 104 void WalkDescendantsClearAncestorDirAuto(nsIContent* aContent); 105 106 /** 107 * When the contents of a text node are about to change, retrieve the current 108 * directionality of the text 109 * 110 * @return whether the text node affects the directionality of any element 111 */ 112 bool TextNodeWillChangeDirection(dom::Text* aTextNode, Directionality* aOldDir, 113 uint32_t aOffset); 114 115 /** 116 * After the contents of a text node have changed, change the directionality 117 * of any elements whose directionality is determined by that node 118 */ 119 void TextNodeChangedDirection(dom::Text* aTextNode, Directionality aOldDir, 120 bool aNotify); 121 122 /** 123 * When a text node is appended to an element, find any ancestors with dir=auto 124 * whose directionality will be determined by the text node 125 */ 126 void SetDirectionFromNewTextNode(dom::Text* aTextNode); 127 128 /** 129 * When a text node is removed from a document, find any ancestors whose 130 * directionality it determined and redetermine their directionality 131 */ 132 void ResetDirectionSetByTextNode(dom::Text*, dom::UnbindContext&); 133 134 /** 135 * Update directionality of this and other affected elements. 136 */ 137 void ResetDirFormAssociatedElement(mozilla::dom::Element* aElement, 138 bool aNotify, bool aHasDirAuto, 139 const nsAString* aKnownValue = nullptr); 140 141 /** 142 * Called when setting the dir attribute on an element, immediately after 143 * AfterSetAttr. This is instead of using BeforeSetAttr or AfterSetAttr, because 144 * in AfterSetAttr we don't know the old value, so we can't identify all cases 145 * where we need to walk up or down the document tree and reset the direction; 146 * and in BeforeSetAttr we can't do the walk because this element hasn't had the 147 * value set yet so the results will be wrong. 148 */ 149 void OnSetDirAttr(mozilla::dom::Element* aElement, const nsAttrValue* aNewValue, 150 bool hadValidDir, bool hadDirAuto, bool aNotify); 151 152 /** 153 * Called when binding a new element to the tree, to set the 154 * NodeAncestorHasDirAuto flag and set the direction of the element and its 155 * ancestors if necessary 156 */ 157 void SetDirOnBind(mozilla::dom::Element* aElement, nsIContent* aParent); 158 159 /** 160 * Called when unbinding an element from the tree, to recompute the 161 * directionality of the element if it doesn't have autodirection, and to 162 * clean up any entries in nsTextDirectionalityMap that refer to it. 163 */ 164 void ResetDir(mozilla::dom::Element* aElement); 165 } // end namespace mozilla 166 167 #endif /* DirectionalityUtils_h___ */