1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Daniel Glazman <glazman@netscape.com>
24 * L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * representation of CSS style rules (selectors+declaration) and CSS
45 #ifndef nsICSSStyleRule_h___
46 #define nsICSSStyleRule_h___
49 #include "nsICSSRule.h"
52 #include "nsCSSValue.h"
53 #include "nsCSSPseudoElements.h"
54 #include "nsCSSPseudoClasses.h"
57 class nsCSSStyleSheet
;
58 struct nsCSSSelectorList
;
68 nsAtomList(nsIAtom
* aAtom
);
69 nsAtomList(const nsString
& aAtomValue
);
72 /** Do a deep clone. Should be used only on the first in the linked list. */
73 nsAtomList
* Clone() const { return Clone(PR_TRUE
); }
75 nsCOMPtr
<nsIAtom
> mAtom
;
78 nsAtomList
* Clone(PRBool aDeep
) const;
80 // These are not supported and are not implemented!
81 nsAtomList(const nsAtomList
& aCopy
);
82 nsAtomList
& operator=(const nsAtomList
& aCopy
);
85 struct nsPseudoClassList
{
87 nsPseudoClassList(nsIAtom
* aAtom
, nsCSSPseudoClasses::Type aType
);
88 nsPseudoClassList(nsIAtom
* aAtom
, nsCSSPseudoClasses::Type aType
,
89 const PRUnichar
*aString
);
90 nsPseudoClassList(nsIAtom
* aAtom
, nsCSSPseudoClasses::Type aType
,
91 const PRInt32
*aIntPair
);
92 nsPseudoClassList(nsIAtom
* aAtom
, nsCSSPseudoClasses::Type aType
,
93 nsCSSSelectorList
*aSelectorList
/* takes ownership */);
94 ~nsPseudoClassList(void);
96 /** Do a deep clone. Should be used only on the first in the linked list. */
97 nsPseudoClassList
* Clone() const { return Clone(PR_TRUE
); }
99 nsCOMPtr
<nsIAtom
> mAtom
;
101 // For a given value of mAtom, we have either:
102 // a. no value, which means mMemory is always null
103 // (if none of the conditions for (b), (c), or (d) is true)
104 // b. a string value, which means mString/mMemory is non-null
105 // (if nsCSSPseudoClasses::HasStringArg(mAtom))
106 // c. an integer pair value, which means mNumbers/mMemory is non-null
107 // (if nsCSSPseudoClasses::HasNthPairArg(mAtom))
108 // d. a selector list, which means mSelectors is non-null
109 // (if nsCSSPseudoClasses::HasSelectorListArg(mAtom))
110 void* mMemory
; // mString and mNumbers use NS_Alloc/NS_Free
113 nsCSSSelectorList
* mSelectors
;
115 nsCSSPseudoClasses::Type mType
;
116 nsPseudoClassList
* mNext
;
118 nsPseudoClassList
* Clone(PRBool aDeep
) const;
120 // These are not supported and are not implemented!
121 nsPseudoClassList(const nsPseudoClassList
& aCopy
);
122 nsPseudoClassList
& operator=(const nsPseudoClassList
& aCopy
);
125 #define NS_ATTR_FUNC_SET 0 // [attr]
126 #define NS_ATTR_FUNC_EQUALS 1 // [attr=value]
127 #define NS_ATTR_FUNC_INCLUDES 2 // [attr~=value] (space separated)
128 #define NS_ATTR_FUNC_DASHMATCH 3 // [attr|=value] ('-' truncated)
129 #define NS_ATTR_FUNC_BEGINSMATCH 4 // [attr^=value] (begins with)
130 #define NS_ATTR_FUNC_ENDSMATCH 5 // [attr$=value] (ends with)
131 #define NS_ATTR_FUNC_CONTAINSMATCH 6 // [attr*=value] (contains substring)
133 struct nsAttrSelector
{
135 nsAttrSelector(PRInt32 aNameSpace
, const nsString
& aAttr
);
136 nsAttrSelector(PRInt32 aNameSpace
, const nsString
& aAttr
, PRUint8 aFunction
,
137 const nsString
& aValue
, PRBool aCaseSensitive
);
138 nsAttrSelector(PRInt32 aNameSpace
, nsIAtom
* aLowercaseAttr
,
139 nsIAtom
* aCasedAttr
, PRUint8 aFunction
,
140 const nsString
& aValue
, PRBool aCaseSensitive
);
141 ~nsAttrSelector(void);
143 /** Do a deep clone. Should be used only on the first in the linked list. */
144 nsAttrSelector
* Clone() const { return Clone(PR_TRUE
); }
147 nsAttrSelector
* mNext
;
148 nsCOMPtr
<nsIAtom
> mLowercaseAttr
;
149 nsCOMPtr
<nsIAtom
> mCasedAttr
;
152 PRPackedBool mCaseSensitive
; // If we are in an HTML document,
153 // is the value case sensitive?
155 nsAttrSelector
* Clone(PRBool aDeep
) const;
157 // These are not supported and are not implemented!
158 nsAttrSelector(const nsAttrSelector
& aCopy
);
159 nsAttrSelector
& operator=(const nsAttrSelector
& aCopy
);
162 struct nsCSSSelector
{
165 ~nsCSSSelector(void);
167 /** Do a deep clone. Should be used only on the first in the linked list. */
168 nsCSSSelector
* Clone() const { return Clone(PR_TRUE
, PR_TRUE
); }
171 void SetNameSpace(PRInt32 aNameSpace
);
172 void SetTag(const nsString
& aTag
);
173 void AddID(const nsString
& aID
);
174 void AddClass(const nsString
& aClass
);
175 void AddPseudoClass(nsIAtom
* aPseudoClass
, nsCSSPseudoClasses::Type aType
);
176 void AddPseudoClass(nsIAtom
* aPseudoClass
, nsCSSPseudoClasses::Type aType
,
177 const PRUnichar
* aString
);
178 void AddPseudoClass(nsIAtom
* aPseudoClass
, nsCSSPseudoClasses::Type aType
,
179 const PRInt32
* aIntPair
);
180 // takes ownership of aSelectorList
181 void AddPseudoClass(nsIAtom
* aPseudoClass
, nsCSSPseudoClasses::Type aType
,
182 nsCSSSelectorList
* aSelectorList
);
183 void AddAttribute(PRInt32 aNameSpace
, const nsString
& aAttr
);
184 void AddAttribute(PRInt32 aNameSpace
, const nsString
& aAttr
, PRUint8 aFunc
,
185 const nsString
& aValue
, PRBool aCaseSensitive
);
186 void SetOperator(PRUnichar aOperator
);
188 inline PRBool
HasTagSelector() const {
192 inline PRBool
IsPseudoElement() const {
193 return mLowercaseTag
&& !mCasedTag
;
196 // Calculate the specificity of this selector (not including its mNext!).
197 PRInt32
CalcWeight() const;
199 void ToString(nsAString
& aString
, nsCSSStyleSheet
* aSheet
,
200 PRBool aAppend
= PR_FALSE
) const;
203 void AddPseudoClassInternal(nsPseudoClassList
*aPseudoClass
);
204 nsCSSSelector
* Clone(PRBool aDeepNext
, PRBool aDeepNegations
) const;
206 void AppendToStringWithoutCombinators(nsAString
& aString
,
207 nsCSSStyleSheet
* aSheet
) const;
208 void AppendToStringWithoutCombinatorsOrNegations(nsAString
& aString
,
209 nsCSSStyleSheet
* aSheet
,
212 // Returns true if this selector can have a namespace specified (which
213 // happens if and only if the default namespace would apply to this
215 PRBool
CanBeNamespaced(PRBool aIsNegated
) const;
216 // Calculate the specificity of this selector (not including its mNext
217 // or its mNegations).
218 PRInt32
CalcWeightWithoutNegations() const;
221 // Get and set the selector's pseudo type
222 nsCSSPseudoElements::Type
PseudoType() const {
223 return static_cast<nsCSSPseudoElements::Type
>(mPseudoType
);
225 void SetPseudoType(nsCSSPseudoElements::Type aType
) {
226 NS_ASSERTION(aType
> PR_INT16_MIN
&& aType
< PR_INT16_MAX
, "Out of bounds");
227 mPseudoType
= static_cast<PRInt16
>(aType
);
230 // For case-sensitive documents, mLowercaseTag is the same as mCasedTag,
231 // but in case-insensitive documents (HTML) mLowercaseTag is lowercase.
232 // Also, for pseudo-elements mCasedTag will be null but mLowercaseTag
233 // contains their name.
234 nsCOMPtr
<nsIAtom
> mLowercaseTag
;
235 nsCOMPtr
<nsIAtom
> mCasedTag
;
237 nsAtomList
* mClassList
;
238 nsPseudoClassList
* mPseudoClassList
; // atom for the pseudo, string for
239 // the argument to functional pseudos
240 nsAttrSelector
* mAttrList
;
241 nsCSSSelector
* mNegations
;
242 nsCSSSelector
* mNext
;
246 // PRInt16 to make sure it packs well with mOperator
248 // These are not supported and are not implemented!
249 nsCSSSelector(const nsCSSSelector
& aCopy
);
250 nsCSSSelector
& operator=(const nsCSSSelector
& aCopy
);
254 * A selector list is the unit of selectors that each style rule has.
255 * For example, "P B, H1 B { ... }" would be a selector list with two
256 * items (where each |nsCSSSelectorList| object's |mSelectors| has
257 * an |mNext| for the P or H1). We represent them as linked lists.
259 struct nsCSSSelectorList
{
260 nsCSSSelectorList(void);
261 ~nsCSSSelectorList(void);
264 * Create a new selector and push it onto the beginning of |mSelectors|,
265 * setting its |mNext| to the current value of |mSelectors|. If there is an
266 * earlier selector, set its |mOperator| to |aOperator|; else |aOperator|
267 * must be PRUnichar(0).
268 * Returns the new selector.
269 * The list owns the new selector.
270 * The caller is responsible for updating |mWeight|.
272 nsCSSSelector
* AddSelector(PRUnichar aOperator
);
275 * Should be used only on the first in the list
277 void ToString(nsAString
& aResult
, nsCSSStyleSheet
* aSheet
);
280 * Do a deep clone. Should be used only on the first in the list.
282 nsCSSSelectorList
* Clone() const { return Clone(PR_TRUE
); }
284 nsCSSSelector
* mSelectors
;
286 nsCSSSelectorList
* mNext
;
288 nsCSSSelectorList
* Clone(PRBool aDeep
) const;
290 // These are not supported and are not implemented!
291 nsCSSSelectorList(const nsCSSSelectorList
& aCopy
);
292 nsCSSSelectorList
& operator=(const nsCSSSelectorList
& aCopy
);
295 // 97eb9881-55fb-462c-be1a-b6309d42f8d0
296 #define NS_ICSS_STYLE_RULE_IID \
297 { 0x97eb9881, 0x55fb, 0x462c, \
298 { 0xbe, 0x1a, 0xb6, 0x30, 0x9d, 0x42, 0xf8, 0xd0 } }
300 class nsICSSStyleRule
: public nsICSSRule
{
302 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICSS_STYLE_RULE_IID
)
304 // null for style attribute
305 virtual nsCSSSelectorList
* Selector(void) = 0;
307 virtual PRUint32
GetLineNumber(void) const = 0;
308 virtual void SetLineNumber(PRUint32 aLineNumber
) = 0;
310 virtual mozilla::css::Declaration
* GetDeclaration(void) const = 0;
313 * Return a new |nsIStyleRule| instance that replaces the current
314 * one, with |aDecl| replacing the previous declaration. Due to the
315 * |nsIStyleRule| contract of immutability, this must be called if
316 * the declaration is modified.
318 * |DeclarationChanged| handles replacing the object in the container
319 * sheet or group rule if |aHandleContainer| is true.
321 virtual already_AddRefed
<nsICSSStyleRule
>
322 DeclarationChanged(mozilla::css::Declaration
* aDecl
,
323 PRBool aHandleContainer
) = 0;
326 * The rule processor must call this method before calling
327 * nsRuleWalker::Forward on this rule during rule matching.
329 virtual void RuleMatched() = 0;
331 // hooks for DOM rule
332 virtual nsresult
GetCssText(nsAString
& aCssText
) = 0;
333 virtual nsresult
SetCssText(const nsAString
& aCssText
) = 0;
334 virtual nsresult
GetParentStyleSheet(nsCSSStyleSheet
** aSheet
) = 0;
335 virtual nsresult
GetParentRule(nsICSSGroupRule
** aParentRule
) = 0;
336 virtual nsresult
GetSelectorText(nsAString
& aSelectorText
) = 0;
337 virtual nsresult
SetSelectorText(const nsAString
& aSelectorText
) = 0;
340 NS_DEFINE_STATIC_IID_ACCESSOR(nsICSSStyleRule
, NS_ICSS_STYLE_RULE_IID
)
342 already_AddRefed
<nsICSSStyleRule
>
343 NS_NewCSSStyleRule(nsCSSSelectorList
* aSelector
,
344 mozilla::css::Declaration
* aDeclaration
);
346 #endif /* nsICSSStyleRule_h___ */