DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (2d9d0bebb5c6)

VCS Links

Directionality

Macros

Line Code
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 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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"
#include "nsStringFwd.h"

class nsIContent;
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
};

/**
 * Various methods for returning the directionality of a string using the
 * first-strong algorithm defined in http://unicode.org/reports/tr9/#P2
 *
 * @param[out] aFirstStrong the offset to the first character in the string with
 *             strong directionality, or UINT32_MAX if there is none (return
               value is eDir_NotSet).
 * @return the directionality of the string
 */
Directionality
GetDirectionFromText(const char16_t* aText, const uint32_t aLength,
                     uint32_t* aFirstStrong = nullptr);

/**
 * 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___ */