michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef DirectionalityUtils_h___ michael@0: #define DirectionalityUtils_h___ michael@0: michael@0: #include "nscore.h" michael@0: michael@0: class nsIContent; michael@0: class nsIDocument; michael@0: class nsINode; michael@0: class nsAString; michael@0: class nsAttrValue; michael@0: class nsTextNode; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: class Element; michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: namespace mozilla { michael@0: michael@0: enum Directionality { michael@0: eDir_NotSet, michael@0: eDir_RTL, michael@0: eDir_LTR, michael@0: eDir_Auto michael@0: }; michael@0: michael@0: /** michael@0: * Set the directionality of an element according to the algorithm defined at michael@0: * http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#the-directionality, michael@0: * not including elements with auto direction. michael@0: * michael@0: * @return the directionality that the element was set to michael@0: */ michael@0: Directionality RecomputeDirectionality(mozilla::dom::Element* aElement, michael@0: bool aNotify = true); michael@0: michael@0: /** michael@0: * Set the directionality of any descendants of a node that do not themselves michael@0: * have a dir attribute. michael@0: * For performance reasons we walk down the descendant tree in the rare case michael@0: * of setting the dir attribute, rather than walking up the ancestor tree in michael@0: * the much more common case of getting the element's directionality. michael@0: */ michael@0: void SetDirectionalityOnDescendants(mozilla::dom::Element* aElement, michael@0: Directionality aDir, michael@0: bool aNotify = true); michael@0: michael@0: /** michael@0: * Walk the descendants of a node in tree order and, for any text node michael@0: * descendant that determines the directionality of some element and is not a michael@0: * descendant of another descendant of the original node with dir=auto, michael@0: * redetermine that element's directionality michael@0: */ michael@0: void WalkDescendantsResetAutoDirection(mozilla::dom::Element* aElement); michael@0: michael@0: /** michael@0: * After setting dir=auto on an element, walk its descendants in tree order. michael@0: * If the node doesn't have the NODE_ANCESTOR_HAS_DIR_AUTO flag, set the michael@0: * NODE_ANCESTOR_HAS_DIR_AUTO flag on all of its descendants. michael@0: * Resolve the directionality of the element by the "downward propagation michael@0: * algorithm" (defined in section 3 in the comments at the beginning of michael@0: * DirectionalityUtils.cpp) michael@0: */ michael@0: void WalkDescendantsSetDirAuto(mozilla::dom::Element* aElement, michael@0: bool aNotify = true); michael@0: michael@0: /** michael@0: * After unsetting dir=auto on an element, walk its descendants in tree order, michael@0: * skipping any that have dir=auto themselves, and unset the michael@0: * NODE_ANCESTOR_HAS_DIR_AUTO flag michael@0: */ michael@0: void WalkDescendantsClearAncestorDirAuto(mozilla::dom::Element* aElement); michael@0: michael@0: /** michael@0: * When the contents of a text node are about to change, retrieve the current michael@0: * directionality of the text michael@0: * michael@0: * @return whether the text node affects the directionality of any element michael@0: */ michael@0: bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir, michael@0: uint32_t aOffset); michael@0: michael@0: /** michael@0: * After the contents of a text node have changed, change the directionality michael@0: * of any elements whose directionality is determined by that node michael@0: */ michael@0: void TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir, michael@0: bool aNotify); michael@0: michael@0: /** michael@0: * When a text node is appended to an element, find any ancestors with dir=auto michael@0: * whose directionality will be determined by the text node michael@0: */ michael@0: void SetDirectionFromNewTextNode(nsIContent* aTextNode); michael@0: michael@0: /** michael@0: * When a text node is removed from a document, find any ancestors whose michael@0: * directionality it determined and redetermine their directionality michael@0: * michael@0: * @param aTextNode the text node michael@0: * @param aNullParent whether the the parent is also being removed michael@0: * (passed from UnbindFromTree) michael@0: */ michael@0: void ResetDirectionSetByTextNode(nsTextNode* aTextNode, bool aNullParent); michael@0: michael@0: /** michael@0: * Set the directionality of an element according to the directionality of the michael@0: * text in aValue michael@0: */ michael@0: void SetDirectionalityFromValue(mozilla::dom::Element* aElement, michael@0: const nsAString& aValue, michael@0: bool aNotify); michael@0: michael@0: /** michael@0: * Called when setting the dir attribute on an element, immediately after michael@0: * AfterSetAttr. This is instead of using BeforeSetAttr or AfterSetAttr, because michael@0: * in AfterSetAttr we don't know the old value, so we can't identify all cases michael@0: * where we need to walk up or down the document tree and reset the direction; michael@0: * and in BeforeSetAttr we can't do the walk because this element hasn't had the michael@0: * value set yet so the results will be wrong. michael@0: */ michael@0: void OnSetDirAttr(mozilla::dom::Element* aElement, michael@0: const nsAttrValue* aNewValue, michael@0: bool hadValidDir, michael@0: bool hadDirAuto, michael@0: bool aNotify); michael@0: michael@0: /** michael@0: * Called when binding a new element to the tree, to set the michael@0: * NodeAncestorHasDirAuto flag and set the direction of the element and its michael@0: * ancestors if necessary michael@0: */ michael@0: void SetDirOnBind(mozilla::dom::Element* aElement, nsIContent* aParent); michael@0: michael@0: /** michael@0: * Called when unbinding an element from the tree, to recompute the michael@0: * directionality of the element if it doesn't have autodirection, and to michael@0: * clean up any entries in nsTextDirectionalityMap that refer to it. michael@0: */ michael@0: void ResetDir(mozilla::dom::Element* aElement); michael@0: } // end namespace mozilla michael@0: michael@0: #endif /* DirectionalityUtils_h___ */