Add some assertions to DirectionalityUtils.cpp, Bug 861606, r=ehsan

This commit is contained in:
Simon Montagu 2013-04-15 23:14:39 +03:00
Родитель f56bb56e9c
Коммит b8ea0ca67a
1 изменённых файлов: 38 добавлений и 6 удалений

Просмотреть файл

@ -385,7 +385,9 @@ static nsINode*
WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true, WalkDescendantsSetDirectionFromText(Element* aElement, bool aNotify = true,
nsINode* aChangedNode = nullptr) nsINode* aChangedNode = nullptr)
{ {
MOZ_ASSERT(aElement, "aElement is null"); MOZ_ASSERT(aElement, "Must have an element");
MOZ_ASSERT(aElement->HasDirAuto(), "Element must have dir=auto");
if (DoesNotParticipateInAutoDirection(aElement)) { if (DoesNotParticipateInAutoDirection(aElement)) {
return nullptr; return nullptr;
} }
@ -428,6 +430,7 @@ class nsTextNodeDirectionalityMap
nsTextNodeDirectionalityMap* map = nsTextNodeDirectionalityMap* map =
reinterpret_cast<nsTextNodeDirectionalityMap * >(aPropertyValue); reinterpret_cast<nsTextNodeDirectionalityMap * >(aPropertyValue);
map->EnsureMapIsClear(textNode);
delete map; delete map;
} }
@ -511,6 +514,14 @@ private:
return PL_DHASH_REMOVE; return PL_DHASH_REMOVE;
} }
static PLDHashOperator ClearEntry(nsPtrHashKey<Element>* aEntry, void* aData)
{
Element* rootNode = aEntry->GetKey();
rootNode->ClearHasDirAutoSet();
rootNode->UnsetProperty(nsGkAtoms::dirAutoSetBy);
return PL_DHASH_REMOVE;
}
public: public:
void UpdateAutoDirection(Directionality aDir) void UpdateAutoDirection(Directionality aDir)
{ {
@ -522,6 +533,13 @@ public:
mElements.EnumerateEntries(ResetNodeDirection, aTextNode); mElements.EnumerateEntries(ResetNodeDirection, aTextNode);
} }
void EnsureMapIsClear(nsINode* aTextNode)
{
uint32_t clearedEntries =
mElements.EnumerateEntries(ClearEntry, aTextNode);
MOZ_ASSERT(clearedEntries == 0, "Map should be empty already");
}
static void RemoveElementFromMap(nsINode* aTextNode, Element* aElement) static void RemoveElementFromMap(nsINode* aTextNode, Element* aElement)
{ {
if (aTextNode->HasTextNodeDirectionalityMap()) { if (aTextNode->HasTextNodeDirectionalityMap()) {
@ -552,6 +570,13 @@ public:
"Map missing in ResetTextNodeDirection"); "Map missing in ResetTextNodeDirection");
GetDirectionalityMap(aTextNode)->ResetAutoDirection(aTextNode); GetDirectionalityMap(aTextNode)->ResetAutoDirection(aTextNode);
} }
static void EnsureMapIsClearFor(nsINode* aTextNode)
{
if (aTextNode->HasTextNodeDirectionalityMap()) {
GetDirectionalityMap(aTextNode)->EnsureMapIsClear(aTextNode);
}
}
}; };
Directionality Directionality
@ -655,6 +680,7 @@ WalkDescendantsResetAutoDirection(Element* aElement)
if (child->HasTextNodeDirectionalityMap()) { if (child->HasTextNodeDirectionalityMap()) {
nsTextNodeDirectionalityMap::ResetTextNodeDirection(child); nsTextNodeDirectionalityMap::ResetTextNodeDirection(child);
nsTextNodeDirectionalityMap::EnsureMapIsClearFor(child);
} }
child = child->GetNextNode(aElement); child = child->GetNextNode(aElement);
} }
@ -731,9 +757,13 @@ void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir,
if (parent->HasDirAuto()) { if (parent->HasDirAuto()) {
bool resetDirection = false; bool resetDirection = false;
nsINode* directionWasSetByTextNode =
static_cast<nsINode*>(parent->GetProperty(nsGkAtoms::dirAutoSetBy));
if (!parent->HasDirAutoSet()) { if (!parent->HasDirAutoSet()) {
// Fast path if parent's direction is not yet set by any descendant // Fast path if parent's direction is not yet set by any descendant
MOZ_ASSERT(!directionWasSetByTextNode,
"dirAutoSetBy property should be null");
resetDirection = true; resetDirection = true;
} else { } else {
// If parent's direction is already set, we need to know if // If parent's direction is already set, we need to know if
@ -741,8 +771,6 @@ void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir,
// We will walk parent's descendants in tree order starting from // We will walk parent's descendants in tree order starting from
// aTextNode to optimize for the most common case where text nodes are // aTextNode to optimize for the most common case where text nodes are
// being appended to tree. // being appended to tree.
nsINode* directionWasSetByTextNode =
static_cast<nsINode*>(parent->GetProperty(nsGkAtoms::dirAutoSetBy));
if (!directionWasSetByTextNode) { if (!directionWasSetByTextNode) {
resetDirection = true; resetDirection = true;
} else if (directionWasSetByTextNode != aTextNode) { } else if (directionWasSetByTextNode != aTextNode) {
@ -758,9 +786,6 @@ void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir,
// we found the node that set the element's direction after our // we found the node that set the element's direction after our
// text node, so we need to reset the direction // text node, so we need to reset the direction
resetDirection = true; resetDirection = true;
nsTextNodeDirectionalityMap::RemoveElementFromMap(
directionWasSetByTextNode, parent
);
break; break;
} }
@ -770,6 +795,11 @@ void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir,
} }
if (resetDirection) { if (resetDirection) {
if (directionWasSetByTextNode) {
nsTextNodeDirectionalityMap::RemoveElementFromMap(
directionWasSetByTextNode, parent
);
}
parent->SetDirectionality(aDir, aNotify); parent->SetDirectionality(aDir, aNotify);
nsTextNodeDirectionalityMap::AddEntryToMap(aTextNode, parent); nsTextNodeDirectionalityMap::AddEntryToMap(aTextNode, parent);
SetDirectionalityOnDescendants(parent, aDir, aNotify); SetDirectionalityOnDescendants(parent, aDir, aNotify);
@ -790,6 +820,7 @@ SetDirectionFromChangedTextNode(nsIContent* aTextNode, uint32_t aOffset,
bool aNotify) bool aNotify)
{ {
if (!NodeAffectsDirAutoAncestor(aTextNode)) { if (!NodeAffectsDirAutoAncestor(aTextNode)) {
nsTextNodeDirectionalityMap::EnsureMapIsClearFor(aTextNode);
return; return;
} }
@ -846,6 +877,7 @@ void
ResetDirectionSetByTextNode(nsTextNode* aTextNode) ResetDirectionSetByTextNode(nsTextNode* aTextNode)
{ {
if (!NodeAffectsDirAutoAncestor(aTextNode)) { if (!NodeAffectsDirAutoAncestor(aTextNode)) {
nsTextNodeDirectionalityMap::EnsureMapIsClearFor(aTextNode);
return; return;
} }