Add flags to pseudo-elements, and add one that says which ones are expected to contain elements. (Bug 505515) r=bzbarsky

This commit is contained in:
L. David Baron 2009-08-10 15:52:29 -07:00
parent c46fca41b6
commit 1f2c562740
3 changed files with 84 additions and 45 deletions

View File

@ -42,45 +42,40 @@
* This file contains the list of nsIAtoms and their values for CSS * This file contains the list of nsIAtoms and their values for CSS
* pseudo-elements. It is designed to be used as inline input to * pseudo-elements. It is designed to be used as inline input to
* nsCSSPseudoElements.cpp *only* through the magic of C preprocessing. All * nsCSSPseudoElements.cpp *only* through the magic of C preprocessing. All
* entries must be enclosed either in the macro CSS_PSEUDO_ELEMENT or in the * entries must be enclosed either in the macro CSS_PSEUDO_ELEMENT;
* macro CSS2_PSEUDO_ELEMENT; these macros will have cruel and unusual things * these macros will have cruel and unusual things done to them. The
* done to them. The difference between the two macros is that the * entries should be kept in some sort of logical order.
* pseudo-elements enclosed in CSS2_PSEUDO_ELEMENT are the pseudo-elements
* which are allowed to have only a single ':' in stylesheets. The entries
* should be kept in some sort of logical order. The first argument to all the
* macros is the C++ identifier of the atom. The second argument is the string
* value of the atom.
* *
* Code including this file MUST define CSS_PSEUDO_ELEMENT. If desired, it can * Code including this file MUST define CSS_PSEUDO_ELEMENT, which takes
* also define CSS2_PSEUDO_ELEMENT to perform special handling of the CSS2 * three parameters:
* pseudo-elements. * name_ : The C++ identifier used for the atom (which will be a member
* of nsCSSPseudoElements)
* value_ : The pseudo-element as a string, with single-colon syntax,
* used as the string value of the atom.
* flags_ : A bitfield containing flags defined in nsCSSPseudoElements.h
*/ */
// OUTPUT_CLASS=nsCSSPseudoElements // OUTPUT_CLASS=nsCSSPseudoElements
// MACRO_NAME=CSS_PSEUDO_ELEMENT // MACRO_NAME=CSS_PSEUDO_ELEMENT
#ifndef CSS2_PSEUDO_ELEMENT CSS_PSEUDO_ELEMENT(after, ":after", CSS_PSEUDO_ELEMENT_IS_CSS2)
#define DEFINED_CSS2_PSEUDO_ELEMENT CSS_PSEUDO_ELEMENT(before, ":before", CSS_PSEUDO_ELEMENT_IS_CSS2)
#define CSS2_PSEUDO_ELEMENT(name_, value_) CSS_PSEUDO_ELEMENT(name_, value_)
#endif // CSS2_PSEUDO_ELEMENT
CSS2_PSEUDO_ELEMENT(after, ":after") CSS_PSEUDO_ELEMENT(firstLetter, ":first-letter",
CSS2_PSEUDO_ELEMENT(before, ":before") CSS_PSEUDO_ELEMENT_IS_CSS2 |
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
CSS_PSEUDO_ELEMENT(firstLine, ":first-line",
CSS_PSEUDO_ELEMENT_IS_CSS2 |
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
CSS2_PSEUDO_ELEMENT(firstLetter, ":first-letter") CSS_PSEUDO_ELEMENT(mozSelection, ":-moz-selection",
CSS2_PSEUDO_ELEMENT(firstLine, ":first-line") CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
CSS_PSEUDO_ELEMENT(mozSelection, ":-moz-selection") CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner", 0)
CSS_PSEUDO_ELEMENT(mozFocusOuter, ":-moz-focus-outer", 0)
CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner") CSS_PSEUDO_ELEMENT(mozListBullet, ":-moz-list-bullet", 0)
CSS_PSEUDO_ELEMENT(mozFocusOuter, ":-moz-focus-outer") CSS_PSEUDO_ELEMENT(mozListNumber, ":-moz-list-number", 0)
CSS_PSEUDO_ELEMENT(mozListBullet, ":-moz-list-bullet") CSS_PSEUDO_ELEMENT(horizontalFramesetBorder, ":-moz-hframeset-border", 0)
CSS_PSEUDO_ELEMENT(mozListNumber, ":-moz-list-number") CSS_PSEUDO_ELEMENT(verticalFramesetBorder, ":-moz-vframeset-border", 0)
CSS_PSEUDO_ELEMENT(horizontalFramesetBorder, ":-moz-hframeset-border")
CSS_PSEUDO_ELEMENT(verticalFramesetBorder, ":-moz-vframeset-border")
#ifdef DEFINED_CSS2_PSEUDO_ELEMENT
#undef CSS2_PSEUDO_ELEMENT
#endif

View File

@ -44,18 +44,30 @@
#include "nsMemory.h" #include "nsMemory.h"
// define storage for all atoms // define storage for all atoms
#define CSS_PSEUDO_ELEMENT(_name, _value) \ #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
nsICSSPseudoElement* nsCSSPseudoElements::_name; nsICSSPseudoElement* nsCSSPseudoElements::name_;
#include "nsCSSPseudoElementList.h" #include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT #undef CSS_PSEUDO_ELEMENT
static const nsStaticAtom CSSPseudoElements_info[] = { static const nsStaticAtom CSSPseudoElements_info[] = {
#define CSS_PSEUDO_ELEMENT(name_, value_) \ #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
{ value_, (nsIAtom**)&nsCSSPseudoElements::name_ }, { value_, (nsIAtom**)&nsCSSPseudoElements::name_ },
#include "nsCSSPseudoElementList.h" #include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT #undef CSS_PSEUDO_ELEMENT
}; };
// Separate from the array above so that we can have an array of
// nsStaticAtom (to pass to NS_RegisterStaticAtoms and
// nsAtomListUtils::IsMember), but with corresponding indices (so the
// i-th element of this array is the flags for the i-th pseudo-element
// in the previous array).
static const PRUint32 CSSPseudoElements_flags[] = {
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
flags_,
#include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT
};
void nsCSSPseudoElements::AddRefAtoms() void nsCSSPseudoElements::AddRefAtoms()
{ {
NS_RegisterStaticAtoms(CSSPseudoElements_info, NS_RegisterStaticAtoms(CSSPseudoElements_info,
@ -68,14 +80,16 @@ PRBool nsCSSPseudoElements::IsPseudoElement(nsIAtom *aAtom)
NS_ARRAY_LENGTH(CSSPseudoElements_info)); NS_ARRAY_LENGTH(CSSPseudoElements_info));
} }
PRBool nsCSSPseudoElements::IsCSS2PseudoElement(nsIAtom *aAtom) /* static */ PRUint32
nsCSSPseudoElements::FlagsForPseudoElement(nsIAtom *aAtom)
{ {
#define CSS2_PSEUDO_ELEMENT(name_, value_) \ PRUint32 i;
nsCSSPseudoElements::name_ == aAtom || for (i = 0; i < NS_ARRAY_LENGTH(CSSPseudoElements_info); ++i) {
#define CSS_PSEUDO_ELEMENT(name_, value_) if (*CSSPseudoElements_info[i].mAtom == aAtom) {
return break;
#include "nsCSSPseudoElementList.h" }
PR_FALSE; }
#undef CSS_PSEUDO_ELEMENT NS_ASSERTION(i < NS_ARRAY_LENGTH(CSSPseudoElements_info),
#undef CSS2_PSEUDO_ELEMENT "argument must be a pseudo-element");
return CSSPseudoElements_flags[i];
} }

View File

@ -43,6 +43,20 @@
#include "nsIAtom.h" #include "nsIAtom.h"
// Is this pseudo-element a CSS2 pseudo-element that can be specified
// with the single colon syntax (in addition to the double-colon syntax,
// which can be used for all pseudo-elements)?
#define CSS_PSEUDO_ELEMENT_IS_CSS2 (1<<0)
// Is this pseudo-element a pseudo-element that can contain other
// elements?
// (Currently pseudo-elements are either leaves of the tree (relative to
// real elements) or they contain other elements in a non-tree-like
// manner (i.e., like incorrectly-nested start and end tags). It's
// possible that in the future there might be container pseudo-elements
// that form a properly nested tree structure. If that happens, we
// should probably split this flag into two.)
#define CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS (1<<1)
// Empty class derived from nsIAtom so that function signatures can // Empty class derived from nsIAtom so that function signatures can
// require an atom from this atom list. // require an atom from this atom list.
class nsICSSPseudoElement : public nsIAtom {}; class nsICSSPseudoElement : public nsIAtom {};
@ -54,11 +68,27 @@ public:
static PRBool IsPseudoElement(nsIAtom *aAtom); static PRBool IsPseudoElement(nsIAtom *aAtom);
static PRBool IsCSS2PseudoElement(nsIAtom *aAtom); static PRBool IsCSS2PseudoElement(nsIAtom *aAtom) {
return PseudoElementHasFlags(aAtom, CSS_PSEUDO_ELEMENT_IS_CSS2);
}
#define CSS_PSEUDO_ELEMENT(_name, _value) static nsICSSPseudoElement* _name; static PRBool PseudoElementContainsElements(nsIAtom *aAtom) {
return PseudoElementHasFlags(aAtom, CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS);
}
#define CSS_PSEUDO_ELEMENT(_name, _value, _flags) \
static nsICSSPseudoElement* _name;
#include "nsCSSPseudoElementList.h" #include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT #undef CSS_PSEUDO_ELEMENT
private:
static PRUint32 FlagsForPseudoElement(nsIAtom *aAtom);
// Does the given pseudo-element have all of the flags given?
static PRBool PseudoElementHasFlags(nsIAtom *aAtom, PRUint32 aFlags)
{
return (FlagsForPseudoElement(aAtom) & aFlags) == aFlags;
}
}; };
#endif /* nsCSSPseudoElements_h___ */ #endif /* nsCSSPseudoElements_h___ */