Bug 474049: (first patch) Add SMILOverrideStyle rule & accessors on nsIContent/nsGenericElement, to store SMIL-animated style values. r=dbaron r=bz

This commit is contained in:
Daniel Holbert 2009-09-02 17:28:37 -07:00
Родитель bef18b0b3f
Коммит 1b7ae528d3
12 изменённых файлов: 202 добавлений и 10 удалений

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

@ -59,6 +59,7 @@ class nsTextFragment;
class nsIDocShell;
#ifdef MOZ_SMIL
class nsISMILAttr;
class nsIDOMCSSStyleDeclaration;
#endif // MOZ_SMIL
enum nsLinkState {
@ -69,9 +70,10 @@ enum nsLinkState {
};
// IID for the nsIContent interface
// b877753c-316a-422d-9aec-a1d0cf0928b0
#define NS_ICONTENT_IID \
{ 0x4aaa38b8, 0x6bc1, 0x4d01, \
{ 0xb6, 0x3d, 0xcd, 0x11, 0xc0, 0x84, 0x56, 0x9e } }
{ 0xb877753c, 0x316a, 0x422d, \
{ 0x9a, 0xec, 0xa1, 0xd0, 0xcf, 0x09, 0x28, 0xb0 } }
/**
* A node of content in a document's content model. This interface
@ -864,6 +866,31 @@ public:
* The CALLER OWNS the result and is responsible for deleting it.
*/
virtual nsISMILAttr* GetAnimatedAttr(const nsIAtom* aName) = 0;
/**
* Get the SMIL override style for this content node. This is a style
* declaration that is applied *after* the inline style, and it can be used
* e.g. to store animated style values.
*
* Note: This method is analogous to the 'GetStyle' method in
* nsGenericHTMLElement and nsStyledElement.
*/
virtual nsresult GetSMILOverrideStyle(nsIDOMCSSStyleDeclaration** aStyle) = 0;
/**
* Get the SMIL override style rule for this content node. If the rule
* hasn't been created (or if this nsIContent object doesn't support SMIL
* override style), this method simply returns null.
*/
virtual nsICSSStyleRule* GetSMILOverrideStyleRule() = 0;
/**
* Set the SMIL override style rule for this node. If aNotify is true, this
* method will notify the document's pres context, so that the style changes
* will be noticed.
*/
virtual nsresult SetSMILOverrideStyleRule(nsICSSStyleRule* aStyleRule,
PRBool aNotify) = 0;
#endif // MOZ_SMIL
private:

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

@ -1171,6 +1171,29 @@ nsGenericDOMDataNode::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
return NS_OK;
}
#ifdef MOZ_SMIL
nsresult
nsGenericDOMDataNode::GetSMILOverrideStyle(nsIDOMCSSStyleDeclaration** aStyle)
{
*aStyle = nsnull;
return NS_ERROR_NOT_IMPLEMENTED;
}
nsICSSStyleRule*
nsGenericDOMDataNode::GetSMILOverrideStyleRule()
{
return nsnull;
}
nsresult
nsGenericDOMDataNode::SetSMILOverrideStyleRule(nsICSSStyleRule* aStyleRule,
PRBool aNotify)
{
NS_NOTREACHED("How come we're setting SMILOverrideStyle on a non-element?");
return NS_ERROR_UNEXPECTED;
}
#endif // MOZ_SMIL
nsICSSStyleRule*
nsGenericDOMDataNode::GetInlineStyleRule()
{

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

@ -238,6 +238,10 @@ public:
{
return nsnull;
}
virtual nsresult GetSMILOverrideStyle(nsIDOMCSSStyleDeclaration** aStyle);
virtual nsICSSStyleRule* GetSMILOverrideStyleRule();
virtual nsresult SetSMILOverrideStyleRule(nsICSSStyleRule* aStyleRule,
PRBool aNotify);
#endif // MOZ_SMIL
#ifdef DEBUG

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

@ -71,7 +71,9 @@
#include "nsDOMCID.h"
#include "nsIServiceManager.h"
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsCSSDeclaration.h"
#include "nsDOMCSSDeclaration.h"
#include "nsDOMCSSAttrDeclaration.h"
#include "nsINameSpaceManager.h"
#include "nsContentList.h"
#include "nsDOMTokenList.h"
@ -2937,6 +2939,55 @@ nsGenericElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
return NS_OK;
}
#ifdef MOZ_SMIL
nsresult
nsGenericElement::GetSMILOverrideStyle(nsIDOMCSSStyleDeclaration** aStyle)
{
nsGenericElement::nsDOMSlots *slots = GetDOMSlots();
NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY);
if (!slots->mSMILOverrideStyle) {
slots->mSMILOverrideStyle = new nsDOMCSSAttributeDeclaration(this, PR_TRUE);
NS_ENSURE_TRUE(slots->mSMILOverrideStyle, NS_ERROR_OUT_OF_MEMORY);
}
// Why bother with QI?
NS_ADDREF(*aStyle = slots->mSMILOverrideStyle);
return NS_OK;
}
nsICSSStyleRule*
nsGenericElement::GetSMILOverrideStyleRule()
{
nsGenericElement::nsDOMSlots *slots = GetExistingDOMSlots();
return slots ? slots->mSMILOverrideStyleRule : nsnull;
}
nsresult
nsGenericElement::SetSMILOverrideStyleRule(nsICSSStyleRule* aStyleRule,
PRBool aNotify)
{
nsGenericElement::nsDOMSlots *slots = GetDOMSlots();
NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY);
slots->mSMILOverrideStyleRule = aStyleRule;
if (aNotify) {
nsIDocument* doc = GetCurrentDoc();
NS_ABORT_IF_FALSE(doc, "Shouldn't be able to animate style on a node "
"unless it's in a document...");
nsPresShellIterator iter(doc);
nsCOMPtr<nsIPresShell> shell;
while (shell = iter.GetNextShell()) {
nsPresContext* presContext = shell->GetPresContext();
presContext->SMILOverrideStyleChanged(this);
}
}
return NS_OK;
}
#endif // MOZ_SMIL
nsICSSStyleRule*
nsGenericElement::GetInlineStyleRule()
{
@ -4033,6 +4084,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement)
nsDOMSlots *slots = tmp->GetExistingDOMSlots();
if (slots) {
slots->mStyle = nsnull;
#ifdef MOZ_SMIL
slots->mSMILOverrideStyle = nsnull;
#endif // MOZ_SMIL
if (slots->mAttributeMap) {
slots->mAttributeMap->DropReference();
slots->mAttributeMap = nsnull;
@ -4114,6 +4168,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericElement)
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mStyle");
cb.NoteXPCOMChild(slots->mStyle.get());
#ifdef MOZ_SMIL
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mSMILOverrideStyle");
cb.NoteXPCOMChild(slots->mSMILOverrideStyle.get());
#endif // MOZ_SMIL
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "slots mAttributeMap");
cb.NoteXPCOMChild(slots->mAttributeMap.get());

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

@ -436,6 +436,10 @@ public:
{
return nsnull;
}
virtual nsresult GetSMILOverrideStyle(nsIDOMCSSStyleDeclaration** aStyle);
virtual nsICSSStyleRule* GetSMILOverrideStyleRule();
virtual nsresult SetSMILOverrideStyleRule(nsICSSStyleRule* aStyleRule,
PRBool aNotify);
#endif // MOZ_SMIL
#ifdef DEBUG
@ -929,6 +933,17 @@ public:
* @see nsGenericHTMLElement::GetStyle */
nsRefPtr<nsDOMCSSDeclaration> mStyle;
/**
* SMIL Overridde style rules (for SMIL animation of CSS properties)
* @see nsIContent::GetSMILOverrideStyle
*/
nsRefPtr<nsDOMCSSDeclaration> mSMILOverrideStyle;
/**
* Holds any SMIL override style rules for this element.
*/
nsCOMPtr<nsICSSStyleRule> mSMILOverrideStyleRule;
/**
* An object implementing nsIDOMNamedNodeMap for this content (attributes)
* @see nsGenericElement::GetAttributes

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

@ -177,7 +177,11 @@ nsStyledElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
// Just in case...
ReparseStyleAttribute(PR_TRUE);
slots->mStyle = new nsDOMCSSAttributeDeclaration(this);
slots->mStyle = new nsDOMCSSAttributeDeclaration(this
#ifdef MOZ_SMIL
, PR_FALSE
#endif // MOZ_SMIL
);
NS_ENSURE_TRUE(slots->mStyle, NS_ERROR_OUT_OF_MEMORY);
SetFlags(NODE_MAY_HAVE_STYLE);
}

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

@ -1967,7 +1967,11 @@ nsXULElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY);
if (!slots->mStyle) {
slots->mStyle = new nsDOMCSSAttributeDeclaration(this);
slots->mStyle = new nsDOMCSSAttributeDeclaration(this
#ifdef MOZ_SMIL
, PR_FALSE
#endif // MOZ_SMIL
);
NS_ENSURE_TRUE(slots->mStyle, NS_ERROR_OUT_OF_MEMORY);
SetFlags(NODE_MAY_HAVE_STYLE);
}

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

@ -1123,6 +1123,13 @@ nsPresContext::SetSMILAnimations(nsIDocument *aDoc, PRUint16 aNewMode,
}
}
}
void
nsPresContext::SMILOverrideStyleChanged(nsIContent* aContent)
{
mShell->FrameConstructor()->PostRestyleEvent(aContent, eReStyle_Self,
NS_STYLE_HINT_NONE);
}
#endif // MOZ_SMIL
void

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

@ -870,6 +870,13 @@ public:
*/
PRBool HasPendingInterrupt() { return mHasPendingInterrupt; }
#ifdef MOZ_SMIL
/**
* Indicates that the given element's SMIL Override Style has changed,
* and as a result, we need to update our display.
*/
void SMILOverrideStyleChanged(nsIContent* aContent);
#endif // MOZ_SMIL
protected:
friend class nsRunnableMethod<nsPresContext>;
NS_HIDDEN_(void) ThemeChangedInternal();

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

@ -51,8 +51,15 @@
#include "nsIContent.h"
#include "nsIPrincipal.h"
nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(nsIContent *aContent)
nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(nsIContent *aContent
#ifdef MOZ_SMIL
, PRBool aIsSMILOverride
#endif // MOZ_SMIL
)
: mContent(aContent)
#ifdef MOZ_SMIL
, mIsSMILOverride(aIsSMILOverride)
#endif // MOZ_SMIL
{
MOZ_COUNT_CTOR(nsDOMCSSAttributeDeclaration);
@ -96,7 +103,11 @@ nsresult
nsDOMCSSAttributeDeclaration::DeclarationChanged()
{
NS_ASSERTION(mContent, "Must have content node to set the decl!");
nsICSSStyleRule* oldRule = mContent->GetInlineStyleRule();
nsICSSStyleRule* oldRule =
#ifdef MOZ_SMIL
mIsSMILOverride ? mContent->GetSMILOverrideStyleRule() :
#endif // MOZ_SMIL
mContent->GetInlineStyleRule();
NS_ASSERTION(oldRule, "content must have rule");
nsCOMPtr<nsICSSStyleRule> newRule = oldRule->DeclarationChanged(PR_FALSE);
@ -104,7 +115,11 @@ nsDOMCSSAttributeDeclaration::DeclarationChanged()
return NS_ERROR_OUT_OF_MEMORY;
}
return mContent->SetInlineStyleRule(newRule, PR_TRUE);
return
#ifdef MOZ_SMIL
mIsSMILOverride ? mContent->SetSMILOverrideStyleRule(newRule, PR_TRUE) :
#endif // MOZ_SMIL
mContent->SetInlineStyleRule(newRule, PR_TRUE);
}
nsresult
@ -115,7 +130,11 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(nsCSSDeclaration **aDecl,
*aDecl = nsnull;
if (mContent) {
nsICSSStyleRule* cssRule = mContent->GetInlineStyleRule();
nsICSSStyleRule* cssRule =
#ifdef MOZ_SMIL
mIsSMILOverride ? mContent->GetSMILOverrideStyleRule() :
#endif // MOZ_SMIL
mContent->GetInlineStyleRule();
if (cssRule) {
*aDecl = cssRule->GetDeclaration();
}
@ -135,7 +154,12 @@ nsDOMCSSAttributeDeclaration::GetCSSDeclaration(nsCSSDeclaration **aDecl,
return result;
}
result = mContent->SetInlineStyleRule(newRule, PR_FALSE);
result =
#ifdef MOZ_SMIL
mIsSMILOverride ?
mContent->SetSMILOverrideStyleRule(newRule, PR_FALSE) :
#endif // MOZ_SMIL
mContent->SetInlineStyleRule(newRule, PR_FALSE);
if (NS_SUCCEEDED(result)) {
*aDecl = decl;
}

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

@ -53,7 +53,11 @@ class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration,
public nsWrapperCache
{
public:
nsDOMCSSAttributeDeclaration(nsIContent *aContent);
nsDOMCSSAttributeDeclaration(nsIContent *aContent
#ifdef MOZ_SMIL
, PRBool aIsSMILOverride
#endif // MOZ_SMIL
);
~nsDOMCSSAttributeDeclaration();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -79,6 +83,14 @@ protected:
virtual nsresult DeclarationChanged();
nsCOMPtr<nsIContent> mContent;
#ifdef MOZ_SMIL
/* If true, this indicates that this nsDOMCSSAttributeDeclaration
* should interact with mContent's SMIL override style rule (rather
* than the inline style rule).
*/
const PRBool mIsSMILOverride;
#endif // MOZ_SMIL
};
#endif /* nsDOMCSSAttributeDeclaration_h___ */

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

@ -145,6 +145,12 @@ HTMLCSSStyleSheetImpl::RulesMatching(ElementRuleProcessorData* aData)
nsICSSStyleRule* rule = content->GetInlineStyleRule();
if (rule)
aData->mRuleWalker->Forward(rule);
#ifdef MOZ_SMIL
rule = content->GetSMILOverrideStyleRule();
if (rule)
aData->mRuleWalker->Forward(rule);
#endif // MOZ_SMIL
}
return NS_OK;