enhancement for the 3 new attributes selectors in CSS 3. r=dbaron, sr=attinasi
This commit is contained in:
@@ -1855,7 +1855,10 @@ PRBool CSSParserImpl::ParseSelector(PRInt32& aErrorCode,
|
||||
}
|
||||
if ((eCSSToken_Symbol == mToken.mType) ||
|
||||
(eCSSToken_Includes == mToken.mType) ||
|
||||
(eCSSToken_Dashmatch == mToken.mType)) {
|
||||
(eCSSToken_Dashmatch == mToken.mType) ||
|
||||
(eCSSToken_Beginsmatch == mToken.mType) ||
|
||||
(eCSSToken_Endsmatch == mToken.mType) ||
|
||||
(eCSSToken_Containsmatch == mToken.mType)) {
|
||||
mToken.AppendToString(aSource);
|
||||
PRUint8 func;
|
||||
if (eCSSToken_Includes == mToken.mType) {
|
||||
@@ -1864,6 +1867,15 @@ PRBool CSSParserImpl::ParseSelector(PRInt32& aErrorCode,
|
||||
else if (eCSSToken_Dashmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_DASHMATCH;
|
||||
}
|
||||
else if (eCSSToken_Beginsmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_BEGINSMATCH;
|
||||
}
|
||||
else if (eCSSToken_Endsmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_ENDSMATCH;
|
||||
}
|
||||
else if (eCSSToken_Containsmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_CONTAINSMATCH;
|
||||
}
|
||||
else if (']' == mToken.mSymbol) {
|
||||
dataMask |= SEL_MASK_ATTRIB;
|
||||
aSelector.AddAttribute(nameSpaceID, attr);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman <glazman@netscape.com>
|
||||
*/
|
||||
#include "nsCSSScanner.h"
|
||||
#include "nsIInputStream.h"
|
||||
@@ -501,10 +502,25 @@ PRBool nsCSSScanner::Next(PRInt32& aErrorCode, nsCSSToken& aToken)
|
||||
}
|
||||
|
||||
// INCLUDES ("~=") and DASHMATCH ("|=")
|
||||
if (( ch == '|' ) || ( ch == '~')) {
|
||||
if (( ch == '|' ) || ( ch == '~' ) || ( ch == '^' ) ||
|
||||
( ch == '$' ) || ( ch == '*' )) {
|
||||
PRInt32 nextChar = Read(aErrorCode);
|
||||
if ( nextChar == '=' ) {
|
||||
aToken.mType = (ch == '~') ? eCSSToken_Includes : eCSSToken_Dashmatch;
|
||||
if (ch == '~') {
|
||||
aToken.mType = eCSSToken_Includes;
|
||||
}
|
||||
else if (ch == '|') {
|
||||
aToken.mType = eCSSToken_Dashmatch;
|
||||
}
|
||||
else if (ch == '^') {
|
||||
aToken.mType = eCSSToken_Beginsmatch;
|
||||
}
|
||||
else if (ch == '$') {
|
||||
aToken.mType = eCSSToken_Endsmatch;
|
||||
}
|
||||
else if (ch == '*') {
|
||||
aToken.mType = eCSSToken_Containsmatch;
|
||||
}
|
||||
return PR_TRUE;
|
||||
} else {
|
||||
Pushback(nextChar);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman <glazman@netscape.com>
|
||||
*/
|
||||
#ifndef nsCSSScanner_h___
|
||||
#define nsCSSScanner_h___
|
||||
@@ -67,7 +68,10 @@ enum nsCSSTokenType {
|
||||
eCSSToken_HTMLComment = 12, // "<!--" or "-->"
|
||||
|
||||
eCSSToken_Includes = 13, // "~="
|
||||
eCSSToken_Dashmatch = 14 // "|="
|
||||
eCSSToken_Dashmatch = 14, // "|="
|
||||
eCSSToken_Beginsmatch = 15, // "^="
|
||||
eCSSToken_Endsmatch = 16, // "$="
|
||||
eCSSToken_Containsmatch = 17 // "*="
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -732,6 +732,15 @@ nsresult nsCSSSelector::ToString( nsAWritableString& aString, nsICSSStyleSheet*
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_DASHMATCH) {
|
||||
aString.Append(PRUnichar('|'));
|
||||
aString.Append(PRUnichar('='));
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_BEGINSMATCH) {
|
||||
aString.Append(PRUnichar('^'));
|
||||
aString.Append(PRUnichar('='));
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_ENDSMATCH) {
|
||||
aString.Append(PRUnichar('$'));
|
||||
aString.Append(PRUnichar('='));
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_CONTAINSMATCH) {
|
||||
aString.Append(PRUnichar('*'));
|
||||
aString.Append(PRUnichar('='));
|
||||
}
|
||||
// Append the value
|
||||
aString.Append(list->mValue);
|
||||
|
||||
@@ -2951,7 +2951,7 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
|
||||
} else {
|
||||
nsAttrSelector* attr = aSelector->mAttrList;
|
||||
do {
|
||||
nsAutoString value;
|
||||
nsAutoString value, partValue;
|
||||
nsresult attrState = data.mContent->GetAttribute(attr->mNameSpace, attr->mAttr, value);
|
||||
if (NS_FAILED(attrState) || (NS_CONTENT_ATTR_NOT_THERE == attrState)) {
|
||||
result = PR_FALSE;
|
||||
@@ -2974,6 +2974,27 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
|
||||
case NS_ATTR_FUNC_DASHMATCH:
|
||||
result = ValueDashMatch(value, attr->mValue, isCaseSensitive);
|
||||
break;
|
||||
case NS_ATTR_FUNC_ENDSMATCH:
|
||||
value.Right(partValue, attr->mValue.Length());
|
||||
if (isCaseSensitive) {
|
||||
result = partValue.Equals(attr->mValue);
|
||||
}
|
||||
else {
|
||||
result = partValue.EqualsIgnoreCase(attr->mValue);
|
||||
}
|
||||
break;
|
||||
case NS_ATTR_FUNC_BEGINSMATCH:
|
||||
value.Left(partValue, attr->mValue.Length());
|
||||
if (isCaseSensitive) {
|
||||
result = partValue.Equals(attr->mValue);
|
||||
}
|
||||
else {
|
||||
result = partValue.EqualsIgnoreCase(attr->mValue);
|
||||
}
|
||||
break;
|
||||
case NS_ATTR_FUNC_CONTAINSMATCH:
|
||||
result = (-1 != value.Find(attr->mValue, isCaseSensitive));
|
||||
break;
|
||||
}
|
||||
}
|
||||
attr = attr->mNext;
|
||||
|
||||
@@ -51,6 +51,9 @@ public:
|
||||
#define NS_ATTR_FUNC_EQUALS 1 // [attr=value]
|
||||
#define NS_ATTR_FUNC_INCLUDES 2 // [attr~=value] (space separated)
|
||||
#define NS_ATTR_FUNC_DASHMATCH 3 // [attr|=value] ('-' truncated)
|
||||
#define NS_ATTR_FUNC_BEGINSMATCH 4 // [attr^=value] (begins with)
|
||||
#define NS_ATTR_FUNC_ENDSMATCH 5 // [attr$=value] (ends with)
|
||||
#define NS_ATTR_FUNC_CONTAINSMATCH 6 // [attr*=value] (contains substring)
|
||||
|
||||
struct nsAttrSelector {
|
||||
public:
|
||||
|
||||
@@ -1855,7 +1855,10 @@ PRBool CSSParserImpl::ParseSelector(PRInt32& aErrorCode,
|
||||
}
|
||||
if ((eCSSToken_Symbol == mToken.mType) ||
|
||||
(eCSSToken_Includes == mToken.mType) ||
|
||||
(eCSSToken_Dashmatch == mToken.mType)) {
|
||||
(eCSSToken_Dashmatch == mToken.mType) ||
|
||||
(eCSSToken_Beginsmatch == mToken.mType) ||
|
||||
(eCSSToken_Endsmatch == mToken.mType) ||
|
||||
(eCSSToken_Containsmatch == mToken.mType)) {
|
||||
mToken.AppendToString(aSource);
|
||||
PRUint8 func;
|
||||
if (eCSSToken_Includes == mToken.mType) {
|
||||
@@ -1864,6 +1867,15 @@ PRBool CSSParserImpl::ParseSelector(PRInt32& aErrorCode,
|
||||
else if (eCSSToken_Dashmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_DASHMATCH;
|
||||
}
|
||||
else if (eCSSToken_Beginsmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_BEGINSMATCH;
|
||||
}
|
||||
else if (eCSSToken_Endsmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_ENDSMATCH;
|
||||
}
|
||||
else if (eCSSToken_Containsmatch == mToken.mType) {
|
||||
func = NS_ATTR_FUNC_CONTAINSMATCH;
|
||||
}
|
||||
else if (']' == mToken.mSymbol) {
|
||||
dataMask |= SEL_MASK_ATTRIB;
|
||||
aSelector.AddAttribute(nameSpaceID, attr);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman <glazman@netscape.com>
|
||||
*/
|
||||
#include "nsCSSScanner.h"
|
||||
#include "nsIInputStream.h"
|
||||
@@ -501,10 +502,25 @@ PRBool nsCSSScanner::Next(PRInt32& aErrorCode, nsCSSToken& aToken)
|
||||
}
|
||||
|
||||
// INCLUDES ("~=") and DASHMATCH ("|=")
|
||||
if (( ch == '|' ) || ( ch == '~')) {
|
||||
if (( ch == '|' ) || ( ch == '~' ) || ( ch == '^' ) ||
|
||||
( ch == '$' ) || ( ch == '*' )) {
|
||||
PRInt32 nextChar = Read(aErrorCode);
|
||||
if ( nextChar == '=' ) {
|
||||
aToken.mType = (ch == '~') ? eCSSToken_Includes : eCSSToken_Dashmatch;
|
||||
if (ch == '~') {
|
||||
aToken.mType = eCSSToken_Includes;
|
||||
}
|
||||
else if (ch == '|') {
|
||||
aToken.mType = eCSSToken_Dashmatch;
|
||||
}
|
||||
else if (ch == '^') {
|
||||
aToken.mType = eCSSToken_Beginsmatch;
|
||||
}
|
||||
else if (ch == '$') {
|
||||
aToken.mType = eCSSToken_Endsmatch;
|
||||
}
|
||||
else if (ch == '*') {
|
||||
aToken.mType = eCSSToken_Containsmatch;
|
||||
}
|
||||
return PR_TRUE;
|
||||
} else {
|
||||
Pushback(nextChar);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Glazman <glazman@netscape.com>
|
||||
*/
|
||||
#ifndef nsCSSScanner_h___
|
||||
#define nsCSSScanner_h___
|
||||
@@ -67,7 +68,10 @@ enum nsCSSTokenType {
|
||||
eCSSToken_HTMLComment = 12, // "<!--" or "-->"
|
||||
|
||||
eCSSToken_Includes = 13, // "~="
|
||||
eCSSToken_Dashmatch = 14 // "|="
|
||||
eCSSToken_Dashmatch = 14, // "|="
|
||||
eCSSToken_Beginsmatch = 15, // "^="
|
||||
eCSSToken_Endsmatch = 16, // "$="
|
||||
eCSSToken_Containsmatch = 17 // "*="
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -732,6 +732,15 @@ nsresult nsCSSSelector::ToString( nsAWritableString& aString, nsICSSStyleSheet*
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_DASHMATCH) {
|
||||
aString.Append(PRUnichar('|'));
|
||||
aString.Append(PRUnichar('='));
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_BEGINSMATCH) {
|
||||
aString.Append(PRUnichar('^'));
|
||||
aString.Append(PRUnichar('='));
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_ENDSMATCH) {
|
||||
aString.Append(PRUnichar('$'));
|
||||
aString.Append(PRUnichar('='));
|
||||
} else if (list->mFunction == NS_ATTR_FUNC_CONTAINSMATCH) {
|
||||
aString.Append(PRUnichar('*'));
|
||||
aString.Append(PRUnichar('='));
|
||||
}
|
||||
// Append the value
|
||||
aString.Append(list->mValue);
|
||||
|
||||
@@ -2951,7 +2951,7 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
|
||||
} else {
|
||||
nsAttrSelector* attr = aSelector->mAttrList;
|
||||
do {
|
||||
nsAutoString value;
|
||||
nsAutoString value, partValue;
|
||||
nsresult attrState = data.mContent->GetAttribute(attr->mNameSpace, attr->mAttr, value);
|
||||
if (NS_FAILED(attrState) || (NS_CONTENT_ATTR_NOT_THERE == attrState)) {
|
||||
result = PR_FALSE;
|
||||
@@ -2974,6 +2974,27 @@ static PRBool SelectorMatches(SelectorMatchesData &data,
|
||||
case NS_ATTR_FUNC_DASHMATCH:
|
||||
result = ValueDashMatch(value, attr->mValue, isCaseSensitive);
|
||||
break;
|
||||
case NS_ATTR_FUNC_ENDSMATCH:
|
||||
value.Right(partValue, attr->mValue.Length());
|
||||
if (isCaseSensitive) {
|
||||
result = partValue.Equals(attr->mValue);
|
||||
}
|
||||
else {
|
||||
result = partValue.EqualsIgnoreCase(attr->mValue);
|
||||
}
|
||||
break;
|
||||
case NS_ATTR_FUNC_BEGINSMATCH:
|
||||
value.Left(partValue, attr->mValue.Length());
|
||||
if (isCaseSensitive) {
|
||||
result = partValue.Equals(attr->mValue);
|
||||
}
|
||||
else {
|
||||
result = partValue.EqualsIgnoreCase(attr->mValue);
|
||||
}
|
||||
break;
|
||||
case NS_ATTR_FUNC_CONTAINSMATCH:
|
||||
result = (-1 != value.Find(attr->mValue, isCaseSensitive));
|
||||
break;
|
||||
}
|
||||
}
|
||||
attr = attr->mNext;
|
||||
|
||||
@@ -51,6 +51,9 @@ public:
|
||||
#define NS_ATTR_FUNC_EQUALS 1 // [attr=value]
|
||||
#define NS_ATTR_FUNC_INCLUDES 2 // [attr~=value] (space separated)
|
||||
#define NS_ATTR_FUNC_DASHMATCH 3 // [attr|=value] ('-' truncated)
|
||||
#define NS_ATTR_FUNC_BEGINSMATCH 4 // [attr^=value] (begins with)
|
||||
#define NS_ATTR_FUNC_ENDSMATCH 5 // [attr$=value] (ends with)
|
||||
#define NS_ATTR_FUNC_CONTAINSMATCH 6 // [attr*=value] (contains substring)
|
||||
|
||||
struct nsAttrSelector {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user