mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-05 22:05:40 +00:00
Implement an AttrValueIs method on nsIContent which can be used to quickly
check whether a given attribute has a given value. Use it in nsContentList::NamedItem. Bug 307600, r+sr=jst
This commit is contained in:
parent
524307e362
commit
81a57e27f2
50
content/base/public/nsCaseTreatment.h
Normal file
50
content/base/public/nsCaseTreatment.h
Normal file
@ -0,0 +1,50 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Boris Zbarsky <bzbarsky@mit.edu> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#ifndef nsCaseTreatment_h___
|
||||
#define nsCaseTreatment_h___
|
||||
|
||||
/**
|
||||
* This is the enum used by functions that need to be told whether to
|
||||
* do case-sensitive or case-insensitive string comparisons.
|
||||
*/
|
||||
enum nsCaseTreatment {
|
||||
eCaseMatters,
|
||||
eIgnoreCase
|
||||
};
|
||||
|
||||
#endif /* nsCaseTreatment_h___ */
|
@ -44,6 +44,7 @@
|
||||
#include "nsAString.h"
|
||||
#include "nsContentErrors.h"
|
||||
#include "nsPropertyTable.h"
|
||||
#include "nsCaseTreatment.h"
|
||||
|
||||
// Forward declarations
|
||||
class nsIAtom;
|
||||
@ -60,8 +61,8 @@ class nsIURI;
|
||||
|
||||
// IID for the nsIContent interface
|
||||
#define NS_ICONTENT_IID \
|
||||
{ 0x3fecc374, 0x2839, 0x4db3, \
|
||||
{ 0x8d, 0xe8, 0x6b, 0x76, 0xd1, 0xd8, 0xe6, 0xf6 } }
|
||||
{ 0x66b01442, 0x75ed, 0x4605, \
|
||||
{ 0x87, 0x06, 0x70, 0x22, 0x27, 0x9d, 0x19, 0x0b } }
|
||||
|
||||
/**
|
||||
* A node of content in a document's content model. This interface
|
||||
@ -327,6 +328,42 @@ public:
|
||||
*/
|
||||
virtual PRBool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const = 0;
|
||||
|
||||
/**
|
||||
* Test whether this content node's given attribute has the given value. If
|
||||
* the attribute is not set at all, this will return false.
|
||||
*
|
||||
* @param aNameSpaceID The namespace ID of the attribute. Must not
|
||||
* be kNameSpaceID_Unknown.
|
||||
* @param aName The name atom of the attribute. Must not be null.
|
||||
* @param aValue The value to compare to.
|
||||
* @param aCaseSensitive Whether to do a case-sensitive compare on the value.
|
||||
*/
|
||||
virtual PRBool AttrValueIs(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsCaseTreatment aCaseSensitive) const
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether this content node's given attribute has the given value. If
|
||||
* the attribute is not set at all, this will return false.
|
||||
*
|
||||
* @param aNameSpaceID The namespace ID of the attribute. Must not
|
||||
* be kNameSpaceID_Unknown.
|
||||
* @param aName The name atom of the attribute. Must not be null.
|
||||
* @param aValue The value to compare to. Must not be null.
|
||||
* @param aCaseSensitive Whether to do a case-sensitive compare on the value.
|
||||
*/
|
||||
virtual PRBool AttrValueIs(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
nsIAtom* aValue,
|
||||
nsCaseTreatment aCaseSensitive) const
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an attribute so that it is no longer explicitly specified.
|
||||
*
|
||||
|
@ -608,6 +608,71 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAttrValue::Equals(const nsAString& aValue,
|
||||
nsCaseTreatment aCaseSensitive) const
|
||||
{
|
||||
switch (BaseType()) {
|
||||
case eStringBase:
|
||||
{
|
||||
nsStringBuffer* str = NS_STATIC_CAST(nsStringBuffer*, GetPtr());
|
||||
if (str) {
|
||||
nsDependentString dep(NS_STATIC_CAST(PRUnichar*, str->Data()),
|
||||
str->StorageSize()/sizeof(PRUnichar) - 1);
|
||||
return aCaseSensitive == eCaseMatters ? aValue.Equals(dep) :
|
||||
aValue.Equals(dep, nsCaseInsensitiveStringComparator());
|
||||
}
|
||||
return aValue.IsEmpty();
|
||||
}
|
||||
case eAtomBase:
|
||||
// Need a way to just do case-insensitive compares on atoms..
|
||||
if (aCaseSensitive == eCaseMatters) {
|
||||
return NS_STATIC_CAST(nsIAtom*, GetPtr())->Equals(aValue);;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
nsAutoString val;
|
||||
ToString(val);
|
||||
return aCaseSensitive == eCaseMatters ? val.Equals(aValue) :
|
||||
val.Equals(aValue, nsCaseInsensitiveStringComparator());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAttrValue::Equals(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const
|
||||
{
|
||||
if (aCaseSensitive != eCaseMatters) {
|
||||
// Need a better way to handle this!
|
||||
nsAutoString value;
|
||||
aValue->ToString(value);
|
||||
return Equals(value, aCaseSensitive);
|
||||
}
|
||||
|
||||
switch (BaseType()) {
|
||||
case eStringBase:
|
||||
{
|
||||
nsStringBuffer* str = NS_STATIC_CAST(nsStringBuffer*, GetPtr());
|
||||
if (str) {
|
||||
nsDependentString dep(NS_STATIC_CAST(PRUnichar*, str->Data()),
|
||||
str->StorageSize()/sizeof(PRUnichar) - 1);
|
||||
return aValue->Equals(dep);
|
||||
}
|
||||
return aValue->EqualsUTF8(EmptyCString());
|
||||
}
|
||||
case eAtomBase:
|
||||
{
|
||||
return NS_STATIC_CAST(nsIAtom*, GetPtr()) == aValue;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
nsAutoString val;
|
||||
ToString(val);
|
||||
return aValue->Equals(val);
|
||||
}
|
||||
|
||||
void
|
||||
nsAttrValue::ParseAtom(const nsAString& aValue)
|
||||
{
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "nsStringBuffer.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCaseTreatment.h"
|
||||
|
||||
typedef unsigned long PtrBits;
|
||||
class nsAString;
|
||||
@ -155,6 +156,8 @@ public:
|
||||
|
||||
PRUint32 HashValue() const;
|
||||
PRBool Equals(const nsAttrValue& aOther) const;
|
||||
PRBool Equals(const nsAString& aValue, nsCaseTreatment aCaseSensitive) const;
|
||||
PRBool Equals(nsIAtom* aValue, nsCaseTreatment aCaseSensitive) const;
|
||||
|
||||
void ParseAtom(const nsAString& aValue);
|
||||
void ParseAtomArray(const nsAString& aValue);
|
||||
|
@ -449,20 +449,22 @@ nsContentList::NamedItem(const nsAString& aName, PRBool aDoFlush)
|
||||
|
||||
PRInt32 i, count = mElements.Count();
|
||||
|
||||
// Typically IDs are atomized and names are not
|
||||
// XXXbz this might change if we start atomizing more random attr
|
||||
// values in HTML like we do in XUL!
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
|
||||
NS_ENSURE_TRUE(name, nsnull);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nsIContent *content = NS_STATIC_CAST(nsIContent *,
|
||||
mElements.ElementAt(i));
|
||||
if (content) {
|
||||
nsAutoString name;
|
||||
// XXX Should it be an EqualsIgnoreCase?
|
||||
if (((content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name,
|
||||
name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
aName.Equals(name)) ||
|
||||
((content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::id,
|
||||
name) == NS_CONTENT_ATTR_HAS_VALUE) &&
|
||||
aName.Equals(name))) {
|
||||
return content;
|
||||
}
|
||||
// XXX Should this pass eIgnoreCase?
|
||||
if (content &&
|
||||
(content->AttrValueIs(kNameSpaceID_None, nsHTMLAtoms::name,
|
||||
aName, eCaseMatters) ||
|
||||
content->AttrValueIs(kNameSpaceID_None, nsHTMLAtoms::id,
|
||||
name, eCaseMatters))) {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3691,6 +3691,33 @@ nsGenericElement::HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const
|
||||
return mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID) >= 0;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericElement::AttrValueIs(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsCaseTreatment aCaseSensitive) const
|
||||
{
|
||||
NS_ASSERTION(aName, "Must have attr name");
|
||||
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
|
||||
|
||||
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
|
||||
return val && val->Equals(aValue, aCaseSensitive);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericElement::AttrValueIs(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aName,
|
||||
nsIAtom* aValue,
|
||||
nsCaseTreatment aCaseSensitive) const
|
||||
{
|
||||
NS_ASSERTION(aName, "Must have attr name");
|
||||
NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
|
||||
NS_ASSERTION(aValue, "Null value atom");
|
||||
|
||||
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
|
||||
return val && val->Equals(aValue, aCaseSensitive);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
PRBool aNotify)
|
||||
|
@ -414,6 +414,12 @@ public:
|
||||
virtual nsresult GetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsAString& aResult) const;
|
||||
virtual PRBool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const;
|
||||
virtual PRBool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue,
|
||||
nsCaseTreatment aCaseSensitive) const;
|
||||
virtual PRBool AttrValueIs(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aValue,
|
||||
nsCaseTreatment aCaseSensitive) const;
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
virtual nsresult GetAttrNameAt(PRUint32 aIndex, PRInt32* aNameSpaceID,
|
||||
|
Loading…
x
Reference in New Issue
Block a user