More DHTML fixes.
git-svn-id: svn://10.0.0.236/branches/Style_20010518_Branch@95865 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -113,6 +113,7 @@ public:
|
||||
PRBool aForceUnique = PR_FALSE);
|
||||
|
||||
NS_IMETHOD ClearRuleTree();
|
||||
virtual nsresult GetRuleTree(nsIRuleNode** aResult);
|
||||
|
||||
NS_IMETHOD ReParentStyleContext(nsIPresContext* aPresContext,
|
||||
nsIStyleContext* aStyleContext,
|
||||
@@ -971,6 +972,14 @@ StyleSetImpl::ClearRuleTree()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
StyleSetImpl::GetRuleTree(nsIRuleNode** aResult)
|
||||
{
|
||||
*aResult = mRuleTree;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
StyleSetImpl::ReParentStyleContext(nsIPresContext* aPresContext,
|
||||
nsIStyleContext* aStyleContext,
|
||||
|
||||
@@ -396,6 +396,7 @@ public:
|
||||
NS_IMETHOD GetPresContext(nsIPresContext** aResult)=0;
|
||||
|
||||
NS_IMETHOD ClearCachedData(nsIStyleRule* aRule)=0;
|
||||
NS_IMETHOD ClearCachedDataInSubtree(nsIStyleRule* aRule)=0;
|
||||
|
||||
virtual const nsStyleStruct* GetStyleData(nsStyleStructID aSID,
|
||||
nsIStyleContext* aContext)=0;
|
||||
|
||||
@@ -418,8 +418,10 @@ nsRuleNode::ClearCachedData(nsIStyleRule* aRule)
|
||||
while (curr) {
|
||||
if (curr->mRule == aRule) {
|
||||
// We have a match. Blow away all data stored at this node.
|
||||
if (mStyleData.mResetData || mStyleData.mInheritedData)
|
||||
mStyleData.Destroy(0, mPresContext);
|
||||
if (curr->mStyleData.mResetData || curr->mStyleData.mInheritedData)
|
||||
curr->mStyleData.Destroy(0, mPresContext);
|
||||
curr->mNoneBits &= ~NS_STYLE_INHERIT_MASK;
|
||||
curr->mInheritBits &= ~NS_STYLE_INHERIT_MASK;
|
||||
break;
|
||||
}
|
||||
curr = curr->mParent;
|
||||
@@ -428,6 +430,31 @@ nsRuleNode::ClearCachedData(nsIStyleRule* aRule)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool PR_CALLBACK ClearCachedDataHelper(nsHashKey* aKey, void* aData, void* aClosure)
|
||||
{
|
||||
nsIRuleNode* ruleNode = (nsIRuleNode*)aData;
|
||||
nsIStyleRule* rule = (nsIStyleRule*)aClosure;
|
||||
ruleNode->ClearCachedDataInSubtree(rule);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRuleNode::ClearCachedDataInSubtree(nsIStyleRule* aRule)
|
||||
{
|
||||
if (mRule == aRule) {
|
||||
// We have a match. Blow away all data stored at this node.
|
||||
if (mStyleData.mResetData || mStyleData.mInheritedData)
|
||||
mStyleData.Destroy(0, mPresContext);
|
||||
mNoneBits &= ~NS_STYLE_INHERIT_MASK;
|
||||
mInheritBits &= ~NS_STYLE_INHERIT_MASK;
|
||||
}
|
||||
|
||||
if (mChildren)
|
||||
mChildren->Enumerate(ClearCachedDataHelper, (void*)aRule);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRuleNode::GetPresContext(nsIPresContext** aResult)
|
||||
{
|
||||
|
||||
@@ -232,6 +232,7 @@ public:
|
||||
NS_IMETHOD IsRoot(PRBool* aResult);
|
||||
NS_IMETHOD GetRule(nsIStyleRule** aResult);
|
||||
NS_IMETHOD ClearCachedData(nsIStyleRule* aRule);
|
||||
NS_IMETHOD ClearCachedDataInSubtree(nsIStyleRule* aRule);
|
||||
NS_IMETHOD GetPresContext(nsIPresContext** aResult);
|
||||
const nsStyleStruct* GetStyleData(nsStyleStructID aSID,
|
||||
nsIStyleContext* aContext);
|
||||
|
||||
@@ -105,6 +105,7 @@ public:
|
||||
NS_IMETHOD ClearPlaceholderFrameMap() = 0;
|
||||
|
||||
// Mapping undisplayed content
|
||||
NS_IMETHOD GetUndisplayedContent(nsIContent* aContent, nsIStyleContext** aStyleContext)=0;
|
||||
NS_IMETHOD SetUndisplayedContent(nsIContent* aContent, nsIStyleContext* aStyleContext) = 0;
|
||||
NS_IMETHOD SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext,
|
||||
nsIContent* aParentContent) = 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ class nsIFrame;
|
||||
class nsIDocument;
|
||||
class nsIFrameManager;
|
||||
class nsISupportsArray;
|
||||
class nsIRuleNode;
|
||||
struct nsFindFrameHint;
|
||||
|
||||
#include "nsVoidArray.h"
|
||||
@@ -79,6 +80,8 @@ public:
|
||||
virtual nsIStyleSheet* GetBackstopStyleSheetAt(PRInt32 aIndex) = 0;
|
||||
virtual void ReplaceBackstopStyleSheets(nsISupportsArray* aNewSheets) = 0;
|
||||
|
||||
virtual nsresult GetRuleTree(nsIRuleNode** aResult) = 0;
|
||||
|
||||
// enable / disable the Quirk style sheet:
|
||||
// returns NS_FAILURE if none is found, otherwise NS_OK
|
||||
NS_IMETHOD EnableQuirkStyleSheet(PRBool aEnable) = 0;
|
||||
|
||||
@@ -161,6 +161,8 @@ public:
|
||||
nsresult RemoveNodeFor(nsIContent* aParentContent, UndisplayedNode* aNode);
|
||||
nsresult RemoveNodesFor(nsIContent* aParentContent);
|
||||
|
||||
nsresult GetNodeFor(nsIContent* aContent, nsIStyleContext** aResult);
|
||||
|
||||
// Removes all entries from the hash table
|
||||
void Clear(void);
|
||||
|
||||
@@ -223,6 +225,7 @@ public:
|
||||
NS_IMETHOD ClearPlaceholderFrameMap();
|
||||
|
||||
// Undisplayed content functions
|
||||
NS_IMETHOD GetUndisplayedContent(nsIContent* aContent, nsIStyleContext** aStyleContext);
|
||||
NS_IMETHOD SetUndisplayedContent(nsIContent* aContent, nsIStyleContext* aStyleContext);
|
||||
NS_IMETHOD SetUndisplayedPseudoIn(nsIStyleContext* aPseudoContext,
|
||||
nsIContent* aParentContent);
|
||||
@@ -675,6 +678,20 @@ FrameManager::ClearPlaceholderFrameMap()
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::GetUndisplayedContent(nsIContent* aContent, nsIStyleContext** aResult)
|
||||
{
|
||||
if (!aContent || !aResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aResult = nsnull; // initialize out param
|
||||
|
||||
if (mUndisplayedMap)
|
||||
mUndisplayedMap->GetNodeFor(aContent, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FrameManager::SetUndisplayedContent(nsIContent* aContent,
|
||||
nsIStyleContext* aStyleContext)
|
||||
@@ -2583,6 +2600,20 @@ UndisplayedMap::AddNodeFor(nsIContent* aParentContent, nsIStyleContext* aPseudoS
|
||||
return AppendNodeFor(node, aParentContent);
|
||||
}
|
||||
|
||||
nsresult
|
||||
UndisplayedMap::GetNodeFor(nsIContent* aContent, nsIStyleContext** aResult)
|
||||
{
|
||||
PLHashEntry** entry = GetEntryFor(aContent);
|
||||
if (*entry) {
|
||||
UndisplayedNode* node = (UndisplayedNode*)((*entry)->value);
|
||||
*aResult = node->mStyle;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
}
|
||||
else
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UndisplayedMap::RemoveNodeFor(nsIContent* aParentContent, UndisplayedNode* aNode)
|
||||
{
|
||||
|
||||
@@ -9800,6 +9800,66 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
||||
}
|
||||
#endif // INCLUDE_XUL
|
||||
|
||||
// check for inline style. we need to clear the data at the style context's rule
|
||||
// node whenever the inline style property changes.
|
||||
if (aAttribute == nsHTMLAtoms::style) {
|
||||
nsCOMPtr<nsIHTMLContent> html(do_QueryInterface(aContent));
|
||||
if (html) {
|
||||
nsHTMLValue val;
|
||||
html->GetHTMLAttribute(nsHTMLAtoms::style, val);
|
||||
if (eHTMLUnit_ISupports == val.GetUnit()) {
|
||||
// This style rule exists and we need to blow away any computed data that this
|
||||
// rule cached in the rule tree.
|
||||
nsCOMPtr<nsIStyleRule> rule = getter_AddRefs((nsIStyleRule*)val.GetISupportsValue());
|
||||
nsCOMPtr<nsIStyleContext> context;
|
||||
if (primaryFrame)
|
||||
primaryFrame->GetStyleContext(getter_AddRefs(context));
|
||||
else {
|
||||
// We might be in the undisplayed map. Retrieve the style context from there.
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
frameManager->GetUndisplayedContent(aContent, getter_AddRefs(context));
|
||||
if (!context) {
|
||||
// Well, we don't have a context to use as a guide.
|
||||
// Attempt #3 will be to resolve style if we at least have a parent frame.
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
aContent->GetParent(*getter_AddRefs(parent));
|
||||
if (parent) {
|
||||
nsIFrame* parentFrame;
|
||||
shell->GetPrimaryFrameFor(parent, &parentFrame);
|
||||
if (parentFrame) {
|
||||
nsCOMPtr<nsIStyleContext> parentContext;
|
||||
parentFrame->GetStyleContext(getter_AddRefs(parentContext));
|
||||
aPresContext->ResolveStyleContextFor(aContent, parentContext, PR_FALSE,
|
||||
getter_AddRefs(context));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (context) {
|
||||
nsCOMPtr<nsIRuleNode> ruleNode;
|
||||
context->GetRuleNode(getter_AddRefs(ruleNode));
|
||||
ruleNode->ClearCachedData(rule); // XXXdwh. If we're willing to *really* special case
|
||||
// inline style, we could only invalidate the struct data
|
||||
// that actually changed. For example, if someone changes
|
||||
// style.left, we really only need to blow away cached
|
||||
// data in the position struct.
|
||||
}
|
||||
else {
|
||||
// Ok, our only option left is to just crawl the entire rule
|
||||
// tree and blow away the data that way.
|
||||
nsCOMPtr<nsIStyleSet> set;
|
||||
shell->GetStyleSet(getter_AddRefs(set));
|
||||
nsCOMPtr<nsIRuleNode> rootNode;
|
||||
set->GetRuleTree(getter_AddRefs(rootNode));
|
||||
if (rootNode)
|
||||
rootNode->ClearCachedDataInSubtree(rule);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply changes
|
||||
if (primaryFrame && aHint == NS_STYLE_HINT_ATTRCHANGE)
|
||||
result = primaryFrame->AttributeChanged(aPresContext, aContent, aNameSpaceID, aAttribute, aHint);
|
||||
@@ -9814,30 +9874,6 @@ nsCSSFrameConstructor::AttributeChanged(nsIPresContext* aPresContext,
|
||||
// is there?
|
||||
if (primaryFrame) {
|
||||
|
||||
// check for inline style. we need to clear the data at the style context's rule
|
||||
// node whenever the inline style property changes.
|
||||
if (aAttribute == nsHTMLAtoms::style) {
|
||||
nsCOMPtr<nsIHTMLContent> html(do_QueryInterface(aContent));
|
||||
if (html) {
|
||||
nsHTMLValue val;
|
||||
html->GetHTMLAttribute(nsHTMLAtoms::style, val);
|
||||
if (eHTMLUnit_ISupports == val.GetUnit()) {
|
||||
// This style rule exists and we need to blow away any computed data that this
|
||||
// rule cached in the rule tree.
|
||||
nsCOMPtr<nsIStyleRule> rule = getter_AddRefs((nsIStyleRule*)val.GetISupportsValue());
|
||||
nsCOMPtr<nsIStyleContext> context;
|
||||
primaryFrame->GetStyleContext(getter_AddRefs(context));
|
||||
nsCOMPtr<nsIRuleNode> ruleNode;
|
||||
context->GetRuleNode(getter_AddRefs(ruleNode));
|
||||
ruleNode->ClearCachedData(rule); // XXXdwh. If we're willing to *really* special case
|
||||
// inline style, we could only invalidate the struct data
|
||||
// that actually changed. For example, if someone changes
|
||||
// style.left, we really only need to blow away cached
|
||||
// data in the position struct.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 maxHint = aHint;
|
||||
nsStyleChangeList changeList;
|
||||
// put primary frame on list to deal with, re-resolve may update or add next in flows
|
||||
|
||||
Reference in New Issue
Block a user