Fix for 99344, inline styles not being recognized under certain DHTML circumstances. r=dbaron, sr=waterson, a=asa

git-svn-id: svn://10.0.0.236/trunk@118229 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
hyatt%netscape.com
2002-04-05 08:05:33 +00:00
parent 6214d193b3
commit dd0e62d9ae
12 changed files with 200 additions and 13 deletions

View File

@@ -59,6 +59,7 @@
#include "nsIHTMLDocument.h"
#include "nsIDOMHTMLBodyElement.h"
#include "nsHTMLAtoms.h"
#include "nsHashtable.h"
#ifdef MOZ_PERF_METRICS
#include "nsITimeRecorder.h"
@@ -73,6 +74,34 @@
#include "nsISizeOfHandler.h"
// =====================================================
// nsRuleNodeList
// A class that represents a chain of rule nodes
struct nsRuleNodeList
{
nsRuleNodeList(nsRuleNode* aRuleNode, nsRuleNodeList* aNext = nsnull)
:mRuleNode(aRuleNode), mNext(aNext)
{};
void* operator new(size_t sz, nsIPresContext* aContext) {
void* result = nsnull;
aContext->AllocateFromShell(sz, &result);
return result;
};
void Destroy() {
if (mNext)
mNext->Destroy();
mRuleNode->PresContext()->FreeToShell(sizeof(nsRuleNodeList), this);
};
nsRuleNode* mRuleNode;
nsRuleNodeList* mNext;
};
// =====================================================
static NS_DEFINE_IID(kIStyleFrameConstructionIID, NS_ISTYLE_FRAME_CONSTRUCTION_IID);
class StyleSetImpl : public nsIStyleSet
@@ -160,6 +189,8 @@ public:
virtual nsresult GetRuleTree(nsRuleNode** aResult);
virtual nsresult ClearCachedDataInRuleTree(nsIStyleRule* aRule);
virtual nsresult AddRuleNodeMapping(nsRuleNode* aRuleNode);
virtual nsresult ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule, nsIStyleContext* aContext);
@@ -336,6 +367,7 @@ protected:
nsRuleNode* mOldRuleTree; // Used during rule tree reconstruction.
nsRuleWalker* mRuleWalker; // This is an instance of a rule walker that can be used
// to navigate through our tree.
nsHashtable mRuleMappings; // A hashtable from rules to rule node lists.
MOZ_TIMER_DECLARE(mStyleResolutionWatch)
@@ -353,7 +385,8 @@ StyleSetImpl::StyleSetImpl()
mQuirkStyleSheet(nsnull),
mRuleTree(nsnull),
mOldRuleTree(nsnull),
mRuleWalker(nsnull)
mRuleWalker(nsnull),
mRuleMappings(32)
#ifdef MOZ_PERF_METRICS
,mTimerEnabled(PR_FALSE)
#endif
@@ -1218,9 +1251,19 @@ nsIStyleContext* StyleSetImpl::ProbePseudoStyleFor(nsIPresContext* aPresContext,
return result;
}
PRBool PR_CALLBACK DeleteRuleNodeLists(nsHashKey* aKey, void* aData, void* aClosure)
{
nsRuleNodeList* ruleNodeList = (nsRuleNodeList*)aData;
ruleNodeList->Destroy();
return PR_TRUE;
}
NS_IMETHODIMP
StyleSetImpl::Shutdown()
{
mRuleMappings.Enumerate(DeleteRuleNodeLists);
mRuleMappings.Reset();
delete mRuleWalker;
if (mRuleTree)
{
@@ -1237,6 +1280,17 @@ StyleSetImpl::GetRuleTree(nsRuleNode** aResult)
return NS_OK;
}
nsresult
StyleSetImpl::AddRuleNodeMapping(nsRuleNode* aRuleNode)
{
nsVoidKey key(aRuleNode->Rule());
nsRuleNodeList* ruleList =
new (aRuleNode->PresContext()) nsRuleNodeList(aRuleNode,
NS_STATIC_CAST(nsRuleNodeList*, mRuleMappings.Get(&key)));
mRuleMappings.Put(&key, ruleList);
return NS_OK;
}
nsresult
StyleSetImpl::BeginRuleTreeReconstruct()
{
@@ -1244,6 +1298,8 @@ StyleSetImpl::BeginRuleTreeReconstruct()
mRuleWalker = nsnull;
mOldRuleTree = mRuleTree;
mRuleTree = nsnull;
mRuleMappings.Enumerate(DeleteRuleNodeLists);
mRuleMappings.Reset();
return NS_OK;
}
@@ -1274,6 +1330,20 @@ StyleSetImpl::ClearStyleData(nsIPresContext* aPresContext, nsIStyleRule* aRule,
// style.left, we really only need to blow away cached
// data in the position struct.
if (aContext) {
// |aRule| should never be null, but we'll sanity check it just in case.
if (aRule) {
// Obtain our rule node list and clear out the cached data in all rule nodes
// that correspond to this rule. See bug 99344 for more details as to how
// inline style rules can end up with multiple rule nodes in a rule tree.
nsVoidKey key(aRule);
nsRuleNodeList* ruleList = NS_STATIC_CAST(nsRuleNodeList*, mRuleMappings.Get(&key));
for ( ; ruleList; ruleList = ruleList->mNext)
ruleList->mRuleNode->ClearCachedData(aRule);
}
// XXXdwh I'm just being paranoid here. Also clear out the data starting at the style
// context's rule node. This really should always be done in the for loop above,
// but I'm going to leave this here just in case (for now).
nsRuleNode* ruleNode;
aContext->GetRuleNode(&ruleNode);
ruleNode->ClearCachedData(aRule);