Make getElementsByAttribute be an nsContentList so that it's got that live

DOMNodeList goodness that all nodelists should have.  Change some JS to not
break, and some other JS to be a little more efficient with the new world of
lazy listness.  Bug 240186, r=neil on the JS changes, r=jst on the content
changes, sr=jst
This commit is contained in:
bzbarsky%mit.edu 2004-04-15 01:51:32 +00:00
Родитель 77610945e2
Коммит 846feff665
37 изменённых файлов: 236 добавлений и 299 удалений

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

@ -412,7 +412,7 @@ function lazyAppendFontNames( i )
else
{
var dataEls = selectElement.listElement.getElementsByAttribute( "value", dataVal );
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
selectedItem = dataEls.item(0) ? dataEls[0] : defaultItem;
}
}
else
@ -424,7 +424,7 @@ function lazyAppendFontNames( i )
var dataEls = selectElement.listElement.getElementsByAttribute( "value", selectVal );
// we need to honor name-list in case name is unavailable
if (!dataEls.length) {
if (!dataEls.item(0)) {
var fontListPrefString = "font.name-list." + fontTypes[i] + "." + languageList.value;
var nameList = gPrefWindow.pref.CopyUnicharPref( fontListPrefString );
var fontNames = nameList.split(",");
@ -433,11 +433,11 @@ function lazyAppendFontNames( i )
for (j = 0; j < fontNames.length; j++) {
selectVal = fontNames[j].replace(stripWhitespace, "$1");
dataEls = selectElement.listElement.getElementsByAttribute("value", selectVal);
if (dataEls.length)
if (dataEls.item(0))
break; // exit loop if we find one
}
}
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
selectedItem = dataEls.item(0) ? dataEls[0] : defaultItem;
}
catch(e) {
selectedItem = defaultItem;
@ -477,7 +477,7 @@ function saveState()
function minSizeSelect(size)
{
var items = minSize.getElementsByAttribute( "value", size );
if (items.length > 0)
if (items.item(0))
minSize.selectedItem = items[0];
else if (size < 6)
minSizeSelect(6);
@ -595,7 +595,7 @@ function setResolution( resolution )
var userResolution = document.getElementById( "userResolution" );
var items = screenResolution.getElementsByAttribute( "value", resolution );
if (items.length)
if (items.item(0))
{
// If it's one of the hard-coded values, we'll select it directly
screenResolution.selectedItem = items[0];

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

@ -200,7 +200,7 @@ function removeAlarmBox( Event )
//if there's no more events left, close the dialog
EventAlarmBoxes = document.getElementsByAttribute( "eventbox", "true" );
if( EventAlarmBoxes.length > 0 )
if( EventAlarmBoxes.item(0) )
{
//there are still boxes left.
return( false );

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

@ -127,8 +127,8 @@ DayView.prototype.refreshEvents = function dayview_refreshEvents( ) {
allDayBox.removeChild( allDayBox.firstChild );
// remove eventboxes
for( var i = 0; i < eventBoxList.length; i++ ) {
eventBox = eventBoxList[ i ];
while (eventBoxList.item(0)) {
eventBox = eventBoxList[0];
eventBox.parentNode.removeChild( eventBox );
}

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

@ -230,9 +230,9 @@ MonthView.prototype.refreshEvents = function monthView_refreshEvents( )
var eventBox = null;
for( var eventBoxIndex = 0; eventBoxIndex < eventBoxList.length; ++eventBoxIndex )
while ( eventBoxList.item(0) ) {
{
eventBox = eventBoxList[ eventBoxIndex ];
eventBox = eventBoxList[ 0 ];
eventBox.parentNode.removeChild( eventBox );
}
@ -637,9 +637,9 @@ MonthView.prototype.clearSelectedDate = function monthView_clearSelectedDate( )
{
var SelectedBoxes = document.getElementsByAttribute( "monthselected", "true" );
for( var i = 0; i < SelectedBoxes.length; i++ )
while( SelectedBoxes.item(0) )
{
SelectedBoxes[i].removeAttribute( "monthselected" );
SelectedBoxes[0].removeAttribute( "monthselected" );
}
}
@ -652,9 +652,9 @@ MonthView.prototype.clearSelectedBoxes = function monthView_clearSelectedBoxes(
{
var SelectedBoxes = document.getElementsByAttribute( "eventselected", "true" );
for( var i = 0; i < SelectedBoxes.length; i++ )
while( SelectedBoxes.item(0) )
{
SelectedBoxes[i].removeAttribute( "eventselected" );
SelectedBoxes[0].removeAttribute( "eventselected" );
}
}
@ -666,11 +666,11 @@ MonthView.prototype.clearSelectedBoxes = function monthView_clearSelectedBoxes(
MonthView.prototype.hiliteTodaysDate = function monthView_hiliteTodaysDate( )
{
// Clear the old selection if there was one
var TodayBox = document.getElementsByAttribute( "today", "true" );
var TodayBoxes = document.getElementsByAttribute( "today", "true" );
for( var i = 0; i < TodayBox.length; i++ )
while( TodayBoxes.item(0) )
{
TodayBox[i].removeAttribute( "today" );
TodayBoxes[0].removeAttribute( "today" );
}
//highlight today.
@ -872,9 +872,9 @@ MonthView.prototype.clearSelectedEvent = function monthView_clearSelectedEvent(
debug("clearSelectedEvent");
var ArrayOfBoxes = document.getElementsByAttribute( "eventselected", "true" );
for( i = 0; i < ArrayOfBoxes.length; i++ )
while( ArrayOfBoxes.item(0) )
{
ArrayOfBoxes[i].removeAttribute( "eventselected" );
ArrayOfBoxes[0].removeAttribute( "eventselected" );
}
}

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

@ -234,9 +234,9 @@ MultiweekView.prototype.refreshEvents = function multiweekView_refreshEvents( )
var eventBox = null;
for( var eventBoxIndex = 0; eventBoxIndex < eventBoxList.length; ++eventBoxIndex )
while( eventBoxList.item(0) )
{
eventBox = eventBoxList[ eventBoxIndex ];
eventBox = eventBoxList[ 0 ];
eventBox.parentNode.removeChild( eventBox );
}
@ -246,9 +246,9 @@ MultiweekView.prototype.refreshEvents = function multiweekView_refreshEvents( )
// remove old todo boxes
var toDoBoxList = document.getElementsByAttribute( "todobox", "multiweekview" );
for( var toDoBoxIndex = 0; toDoBoxIndex < toDoBoxList.length; ++toDoBoxIndex )
while( toDoBoxList.item(0) )
{
eventBox = toDoBoxList[ toDoBoxIndex ];
eventBox = toDoBoxList[ 0 ];
eventBox.parentNode.removeChild( eventBox );
}
@ -763,9 +763,9 @@ MultiweekView.prototype.clearSelectedDate = function multiweekView_clearSelected
{
var SelectedBoxes = document.getElementsByAttribute( "multiweekselected", "true" );
for( var i = 0; i < SelectedBoxes.length; i++ )
while( SelectedBoxes.item(0) )
{
SelectedBoxes[i].removeAttribute( "multiweekselected" );
SelectedBoxes[0].removeAttribute( "multiweekselected" );
}
}
@ -778,11 +778,11 @@ MultiweekView.prototype.clearSelectedDate = function multiweekView_clearSelected
MultiweekView.prototype.hiliteTodaysDate = function multiweekView_hiliteTodaysDate( )
{
// Clear the old selection if there was one
var TodayBox = document.getElementsByAttribute( "today", "true" );
var TodayBoxes = document.getElementsByAttribute( "today", "true" );
for( var i = 0; i < TodayBox.length; i++ )
while( TodayBoxes.item(0) )
{
TodayBox[i].removeAttribute( "today" );
TodayBoxes[0].removeAttribute( "today" );
}
//highlight today.
@ -931,9 +931,9 @@ MultiweekView.prototype.clearSelectedEvent = function multiweekView_clearSelecte
var ArrayOfBoxes = document.getElementsByAttribute( "eventselected", "true" );
for( i = 0; i < ArrayOfBoxes.length; i++ )
while( ArrayOfBoxes.item(0) )
{
ArrayOfBoxes[i].removeAttribute( "eventselected" );
ArrayOfBoxes[0].removeAttribute( "eventselected" );
}
}

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

@ -151,9 +151,9 @@ WeekView.prototype.refreshEvents = function( )
var eventBoxList = document.getElementsByAttribute( "eventbox", "weekview" );
for( var eventBoxIndex = 0; eventBoxIndex < eventBoxList.length; ++eventBoxIndex )
while( eventBoxList.item(0) )
{
var eventBox = eventBoxList[ eventBoxIndex ];
var eventBox = eventBoxList[ 0 ];
eventBox.parentNode.removeChild( eventBox );
}
@ -774,9 +774,9 @@ WeekView.prototype.hiliteTodaysDate = function( )
{
//clear out the old today boxes.
var OldTodayArray = document.getElementsByAttribute( "today", "true" );
for ( var i = 0; i < OldTodayArray.length; i++ )
while ( OldTodayArray.item(0) )
{
OldTodayArray[i].removeAttribute( "today" );
OldTodayArray[0].removeAttribute( "today" );
}
@ -821,9 +821,9 @@ WeekView.prototype.clearSelectedEvent = function( )
//Event = gCalendarWindow.getSelectedEvent();
var ArrayOfBoxes = document.getElementsByAttribute( "eventselected", "true" );
for( var i = 0; i < ArrayOfBoxes.length; i++ )
while( ArrayOfBoxes.item(0) )
{
ArrayOfBoxes[i].removeAttribute( "eventselected" );
ArrayOfBoxes[0].removeAttribute( "eventselected" );
}
}
@ -855,9 +855,9 @@ WeekView.prototype.clearSelectedDate = function( )
{
var SelectedBoxes = document.getElementsByAttribute( "weekselected", "true" );
for( var i = 0; i < SelectedBoxes.length; i++ )
while( SelectedBoxes.item(0) )
{
SelectedBoxes[i].removeAttribute( "weekselected" );
SelectedBoxes[0].removeAttribute( "weekselected" );
}
}

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

@ -41,7 +41,6 @@
#include "nsIDOMNode.h"
#include "nsIDOM3Node.h"
#include "nsIDocument.h"
#include "nsINameSpaceManager.h"
#include "nsGenericElement.h"
#include "nsContentUtils.h"
@ -348,10 +347,13 @@ nsContentList::nsContentList(nsIDocument *aDocument,
nsContentListMatchFunc aFunc,
const nsAString& aData,
nsIContent* aRootContent,
PRBool aDeep)
PRBool aDeep,
nsIAtom* aMatchAtom,
PRInt32 aMatchNameSpaceId)
: nsBaseContentList(),
nsContentListKey(aDocument, nsnull, kNameSpaceID_Unknown, aRootContent),
nsContentListKey(aDocument, aMatchAtom, aMatchNameSpaceId, aRootContent),
mFunc(aFunc),
mData(&EmptyString()),
mMatchAll(PR_FALSE),
mState(LIST_DIRTY),
mDeep(aDeep)
@ -361,9 +363,6 @@ nsContentList::nsContentList(nsIDocument *aDocument,
mData = new nsString(aData);
// If this fails, fail silently
}
else {
mData = nsnull;
}
Init(aDocument);
}
@ -387,7 +386,10 @@ nsContentList::~nsContentList()
mDocument->RemoveObserver(this);
}
delete mData;
if (mData && mData != &EmptyString()) {
// We actually allocated mData ourselves
delete mData;
}
}
@ -523,6 +525,30 @@ nsContentList::NamedItem(const nsAString& aName, nsIDOMNode** aReturn)
return NS_OK;
}
void
nsContentList::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRInt32 aModType)
{
if (!mFunc || mState == LIST_DIRTY) {
// Either we're already dirty or this notification doesn't affect
// whether we might match aContent.
return;
}
if (MayContainRelevantNodes(aContent->GetParent())) {
if (Match(aContent)) {
// We may now match a new node. Just dirty ourselves.
mState = LIST_DIRTY;
} else {
// We no longer match aContent. Remove it from our list. If
// it's already not there, this is a no-op, which is fine.
// Either way, no change of mState is required here.
mElements.RemoveElement(aContent);
}
}
}
void
nsContentList::ContentAppended(nsIDocument *aDocument, nsIContent* aContainer,
PRInt32 aNewIndexInContainer)
@ -660,6 +686,10 @@ nsContentList::Match(nsIContent *aContent)
if (!aContent)
return PR_FALSE;
if (mFunc) {
return (*mFunc)(aContent, mMatchNameSpaceId, mMatchAtom, *mData);
}
if (mMatchAtom) {
if (!aContent->IsContentOfType(nsIContent::eELEMENT)) {
return PR_FALSE;
@ -675,9 +705,6 @@ nsContentList::Match(nsIContent *aContent)
return ((mMatchAll && ni->NamespaceEquals(mMatchNameSpaceId)) ||
ni->Equals(mMatchAtom, mMatchNameSpaceId));
}
else if (mFunc) {
return (*mFunc)(aContent, mData);
}
return PR_FALSE;
}
@ -904,6 +931,11 @@ nsContentList::DisconnectFromDocument()
void
nsContentList::RemoveFromHashtable()
{
if (mFunc) {
// This can't be in the table anyway
return;
}
if (!gContentListHashTable.ops)
return;

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

@ -46,9 +46,16 @@
#include "nsStubDocumentObserver.h"
#include "nsIContentList.h"
#include "nsIAtom.h"
#include "nsINameSpaceManager.h"
// This is a callback function type that can be used to implement an
// arbitrary matching algorithm. aContent is the content that may
// match the list, while aNamespaceID, aAtom, and aData are whatever
// was passed to the list's constructor.
typedef PRBool (*nsContentListMatchFunc)(nsIContent* aContent,
nsString* aData);
PRInt32 aNamespaceID,
nsIAtom* aAtom,
const nsAString& aData);
class nsIDocument;
class nsIDOMHTMLFormElement;
@ -167,7 +174,9 @@ public:
nsContentListMatchFunc aFunc,
const nsAString& aData,
nsIContent* aRootContent = nsnull,
PRBool aDeep = PR_TRUE);
PRBool aDeep = PR_TRUE,
nsIAtom* aMatchAtom = nsnull,
PRInt32 aMatchNameSpaceId = kNameSpaceID_None);
virtual ~nsContentList();
// nsIDOMHTMLCollection
@ -182,6 +191,9 @@ public:
virtual void RootDestroyed();
// nsIDocumentObserver
virtual void AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRInt32 aModType);
virtual void ContentAppended(nsIDocument *aDocument, nsIContent* aContainer,
PRInt32 aNewIndexInContainer);
virtual void ContentInserted(nsIDocument *aDocument, nsIContent* aContainer,
@ -263,7 +275,6 @@ protected:
/**
* @param aContainer a content node which could be a descendant of
* mRootContent
* @return PR_TRUE if mRootContent is null, PR_FALSE if aContainer
* is null, PR_TRUE if aContainer is a descendant of mRootContent
* (though if mDeep is false, only aContainer == mRootContent
@ -295,7 +306,7 @@ protected:
/**
* Closure data to pass to mFunc when we call it
*/
nsString* mData;
const nsAFlatString* mData;
/**
* True if we are looking for elements named "*"
*/

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

@ -303,7 +303,8 @@ nsHTMLTableRowElement::GetSectionRowIndex(PRInt32* aValue)
}
PR_STATIC_CALLBACK(PRBool)
IsCell(nsIContent *aContent, nsString* aData)
IsCell(nsIContent *aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData)
{
nsIAtom* tag = aContent->Tag();

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

@ -1836,7 +1836,8 @@ GetHTMLDocumentNamespace(nsIContent *aContent)
}
PRBool
nsHTMLDocument::MatchLinks(nsIContent *aContent, nsString* aData)
nsHTMLDocument::MatchLinks(nsIContent *aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData)
{
nsINodeInfo *ni = aContent->GetNodeInfo();
@ -1856,7 +1857,7 @@ NS_IMETHODIMP
nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
{
if (!mLinks) {
mLinks = new nsContentList(this, MatchLinks, nsString());
mLinks = new nsContentList(this, MatchLinks, EmptyString());
if (!mLinks) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -1869,7 +1870,8 @@ nsHTMLDocument::GetLinks(nsIDOMHTMLCollection** aLinks)
}
PRBool
nsHTMLDocument::MatchAnchors(nsIContent *aContent, nsString* aData)
nsHTMLDocument::MatchAnchors(nsIContent *aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData)
{
nsINodeInfo *ni = aContent->GetNodeInfo();
@ -1888,7 +1890,7 @@ NS_IMETHODIMP
nsHTMLDocument::GetAnchors(nsIDOMHTMLCollection** aAnchors)
{
if (!mAnchors) {
mAnchors = new nsContentList(this, MatchAnchors, nsString());
mAnchors = new nsContentList(this, MatchAnchors, EmptyString());
if (!mAnchors) {
return NS_ERROR_OUT_OF_MEMORY;
}
@ -2459,32 +2461,28 @@ nsHTMLDocument::GetElementsByTagNameNS(const nsAString& aNamespaceURI,
}
PRBool
nsHTMLDocument::MatchNameAttribute(nsIContent* aContent, nsString* aData)
nsHTMLDocument::MatchNameAttribute(nsIContent* aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData)
{
// Most elements don't have a name attribute, so lets call the
// faster HasAttr() method before we create a string object and call
// GetAttr().
if (!aContent->HasAttr(kNameSpaceID_None, nsHTMLAtoms::name) || !aData) {
NS_PRECONDITION(aContent, "Must have content node to work with!");
// Getting attrs is expensive, so use HasAttr() first.
if (!aContent->HasAttr(kNameSpaceID_None, nsHTMLAtoms::name)) {
return PR_FALSE;
}
nsAutoString name;
nsAutoString value;
nsresult rv = aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, value);
nsresult rv = aContent->GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, name);
if (NS_SUCCEEDED(rv) && name.Equals(*aData)) {
return PR_TRUE;
}
return PR_FALSE;
return NS_SUCCEEDED(rv) && value.Equals(aData);
}
NS_IMETHODIMP
nsHTMLDocument::GetElementsByName(const nsAString& aElementName,
nsIDOMNodeList** aReturn)
{
nsContentList* elements = new nsContentList(this, MatchNameAttribute,
nsContentList* elements = new nsContentList(this,
MatchNameAttribute,
aElementName);
NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
@ -2513,7 +2511,8 @@ nsHTMLDocument::GetNumFormsSynchronous()
}
PRBool
nsHTMLDocument::MatchFormControls(nsIContent* aContent, nsString* aData)
nsHTMLDocument::MatchFormControls(nsIContent* aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData)
{
return aContent->IsContentOfType(nsIContent::eHTML_FORM_CONTROL);
}

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

@ -226,11 +226,14 @@ protected:
virtual nsIStyleSheet* InternalGetStyleSheetAt(PRInt32 aIndex) const;
virtual PRInt32 InternalGetNumberOfStyleSheets() const;
static PRBool MatchLinks(nsIContent *aContent, nsString* aData);
static PRBool MatchAnchors(nsIContent *aContent, nsString* aData);
static PRBool MatchLayers(nsIContent *aContent, nsString* aData);
static PRBool MatchNameAttribute(nsIContent* aContent, nsString* aData);
static PRBool MatchFormControls(nsIContent* aContent, nsString* aData);
static PRBool MatchLinks(nsIContent *aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData);
static PRBool MatchAnchors(nsIContent *aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData);
static PRBool MatchNameAttribute(nsIContent* aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData);
static PRBool MatchFormControls(nsIContent* aContent, PRInt32 aNamespaceID,
nsIAtom* aAtom, const nsAString& aData);
static nsresult GetSourceDocumentURI(nsIURI** sourceURI);

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

@ -1310,17 +1310,20 @@ nsXULElement::GetElementsByAttribute(const nsAString& aAttribute,
const nsAString& aValue,
nsIDOMNodeList** aReturn)
{
// XXX This should use nsContentList, but that does not support
// _two_ strings being passed to the match func. Ah, the ability
// to create real closures, where art thou?
nsRDFDOMNodeList* elements = new nsRDFDOMNodeList();
NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(elements);
nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
GetElementsByAttribute(this, aAttribute, aValue, elements);
nsCOMPtr<nsIContentList> list =
new nsContentList(GetDocument(),
nsXULDocument::MatchAttribute,
aValue,
this,
PR_TRUE,
attrAtom,
kNameSpaceID_None);
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
*aReturn = elements;
return NS_OK;
return CallQueryInterface(list, aReturn);
}
@ -3011,65 +3014,6 @@ nsXULElement::EnsureContentsGenerated(void) const
return NS_OK;
}
nsresult
nsXULElement::GetElementsByAttribute(nsIDOMNode* aNode,
const nsAString& aAttribute,
const nsAString& aValue,
nsRDFDOMNodeList* aElements)
{
nsresult rv;
nsCOMPtr<nsIDOMNodeList> children;
if (NS_FAILED(rv = aNode->GetChildNodes( getter_AddRefs(children) ))) {
NS_ERROR("unable to get node's children");
return rv;
}
// no kids: terminate the recursion
if (! children)
return NS_OK;
PRUint32 length;
if (NS_FAILED(children->GetLength(&length))) {
NS_ERROR("unable to get node list's length");
return rv;
}
for (PRUint32 i = 0; i < length; ++i) {
nsCOMPtr<nsIDOMNode> child;
if (NS_FAILED(rv = children->Item(i, getter_AddRefs(child) ))) {
NS_ERROR("unable to get child from list");
return rv;
}
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(child);
if (!element)
continue;
nsAutoString attrValue;
if (NS_FAILED(rv = element->GetAttribute(aAttribute, attrValue))) {
NS_ERROR("unable to get attribute value");
return rv;
}
if ((attrValue.Equals(aValue)) || (!attrValue.IsEmpty() && aValue.Equals(NS_LITERAL_STRING("*")))) {
if (NS_FAILED(rv = aElements->AppendNode(child))) {
NS_ERROR("unable to append element to node list");
return rv;
}
}
// Now recursively look for children
if (NS_FAILED(rv = GetElementsByAttribute(child, aAttribute, aValue, aElements))) {
NS_ERROR("unable to recursively get elements by attribute");
return rv;
}
}
return NS_OK;
}
// nsIStyledContent Implementation
NS_IMETHODIMP
nsXULElement::GetID(nsIAtom** aResult) const

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

@ -557,13 +557,6 @@ protected:
static nsresult
ExecuteJSCode(nsIDOMElement* anElement, nsEvent* aEvent);
// Static helpers
static nsresult
GetElementsByAttribute(nsIDOMNode* aNode,
const nsAString& aAttributeName,
const nsAString& aAttributeValue,
nsRDFDOMNodeList* aElements);
static PRBool IsAncestor(nsIDOMNode* aParentNode, nsIDOMNode* aChildNode);
// Helper routine that crawls a parent chain looking for a tree element.

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

@ -1411,24 +1411,19 @@ nsXULDocument::GetElementsByAttribute(const nsAString& aAttribute,
const nsAString& aValue,
nsIDOMNodeList** aReturn)
{
// XXX This should use nsContentList, but that does not support
// _two_ strings being passed to the match func. Ah, the ability
// to create real closures, where art thou?
nsRDFDOMNodeList* elements = new nsRDFDOMNodeList();
NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
NS_ADDREF(elements);
nsCOMPtr<nsIAtom> attrAtom(do_GetAtom(aAttribute));
NS_ENSURE_TRUE(attrAtom, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIDOMNode> domRoot = do_QueryInterface(mRootContent);
NS_ASSERTION(domRoot, "no doc root");
nsCOMPtr<nsIContentList> list = new nsContentList(this,
MatchAttribute,
aValue,
nsnull,
PR_TRUE,
attrAtom,
kNameSpaceID_None);
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = NS_OK;
if (domRoot) {
rv = GetElementsByAttribute(domRoot, aAttribute, aValue, elements);
}
*aReturn = elements;
return rv;
return CallQueryInterface(list, aReturn);
}
@ -2187,67 +2182,31 @@ nsXULDocument::StartLayout(void)
}
nsresult
nsXULDocument::GetElementsByAttribute(nsIDOMNode* aNode,
const nsAString& aAttribute,
const nsAString& aValue,
nsRDFDOMNodeList* aElements)
/* static */
PRBool
nsXULDocument::MatchAttribute(nsIContent* aContent,
PRInt32 aNamespaceID,
nsIAtom* aAttrName,
const nsAString& aAttrValue)
{
nsresult rv;
nsCOMPtr<nsIDOMElement> element;
element = do_QueryInterface(aNode);
if (!element)
return NS_OK;
nsAutoString attrValue;
if (NS_FAILED(rv = element->GetAttribute(aAttribute, attrValue))) {
NS_ERROR("unable to get attribute value");
return rv;
NS_PRECONDITION(aContent, "Must have content node to work with!");
// Getting attrs is expensive, so use HasAttr() first.
if (!aContent->HasAttr(aNamespaceID, aAttrName)) {
return PR_FALSE;
}
if ((attrValue.Equals(aValue)) ||
(!attrValue.IsEmpty() && aValue.Equals(NS_LITERAL_STRING("*")))) {
if (NS_FAILED(rv = aElements->AppendNode(aNode))) {
NS_ERROR("unable to append element to node list");
return rv;
}
if (aAttrValue == NS_LITERAL_STRING("*")) {
// Wildcard. We already know we have this attr, so we match
return PR_TRUE;
}
nsCOMPtr<nsIDOMNodeList> children;
if (NS_FAILED(rv = aNode->GetChildNodes( getter_AddRefs(children) ))) {
NS_ERROR("unable to get node's children");
return rv;
}
nsAutoString value;
nsresult rv = aContent->GetAttr(aNamespaceID, aAttrName, value);
// no kids: terminate the recursion
if (! children)
return NS_OK;
PRUint32 length;
if (NS_FAILED(children->GetLength(&length))) {
NS_ERROR("unable to get node list's length");
return rv;
}
for (PRUint32 i = 0; i < length; ++i) {
nsCOMPtr<nsIDOMNode> child;
if (NS_FAILED(rv = children->Item(i, getter_AddRefs(child) ))) {
NS_ERROR("unable to get child from list");
return rv;
}
if (NS_FAILED(rv = GetElementsByAttribute(child, aAttribute, aValue,
aElements))) {
NS_ERROR("unable to recursively get elements by attribute");
return rv;
}
}
return NS_OK;
return NS_SUCCEEDED(rv) && value.Equals(aAttrValue);
}
nsresult
nsXULDocument::PrepareToLoad(nsISupports* aContainer,
const char* aCommand,

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

@ -164,6 +164,12 @@ public:
// nsIDOMNSDocument
NS_IMETHOD GetContentType(nsAString& aContentType);
static PRBool
MatchAttribute(nsIContent* aContent,
PRInt32 aNameSpaceID,
nsIAtom* aAttrName,
const nsAString& aValue);
protected:
// Implementation methods
friend nsresult
@ -186,12 +192,6 @@ protected:
nsIContent* aElement,
void* aClosure);
static nsresult
GetElementsByAttribute(nsIDOMNode* aNode,
const nsAString& aAttribute,
const nsAString& aValue,
nsRDFDOMNodeList* aElements);
void SetIsPopup(PRBool isPopup) { mIsPopup = isPopup; };
nsresult PrepareToLoad(nsISupports* aContainer,

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

@ -41,18 +41,18 @@
var regionName = contentList.getAttribute("prefvalue");
var regionElements = contentList.getElementsByAttribute("value", regionName);
if (regionElements.length) {
contentList.selectItem(regionElements[0]);
if (regionElements.item(0)) {
contentList.selectItem(regionElements.item(0));
} else {
contentList.selectedIndex = 0;
}
var languageList = document.getElementById( "languagePackList" );
var languageName = languageList.getAttribute("prefvalue");
var languageElements =languageList.getElementsByAttribute("value", languageName);
var languageElements = languageList.getElementsByAttribute("value", languageName);
if (languageElements.length) {
languageList.selectItem(languageElements[0]);
if (languageElements.item(0)) {
languageList.selectItem(languageElements.item(0));
} else {
languageList.selectedIndex = 0;
}
@ -105,7 +105,7 @@
faslFile.remove(false);
} catch(e) {}
}
return true;
return true;
}
function SelectPack(listbox, button)
@ -150,8 +150,8 @@
var listSelection = list.getElementsByAttribute("value", list.getAttribute("prefvalue"));
//find and select the list item corresponding to the current chrome provider
if (listSelection.length)
list.selectedItem = listSelection[0];
if (listSelection.item(0))
list.selectedItem = listSelection.item(0);
else
list.selectedIndex = 0;
}

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

@ -317,9 +317,10 @@ function viewRefreshCustomMailViews(aCurrentViewValue)
// remove any existing entries...
var menupopupNode = document.getElementById('viewMessageViewPopup');
var userDefinedItems = menupopupNode.getElementsByAttribute("userdefined","true");
for (var i=0; i<userDefinedItems.length; i++)
for (var i=0; userDefinedItems.item(i); )
{
menupopupNode.removeChild(userDefinedItems[i]);
if (!menupopupNode.removeChild(userDefinedItems[i]))
++i;
}
// now rebuild the list

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

@ -372,7 +372,7 @@ function lazyAppendFontNames( i )
else
{
var dataEls = selectElement.listElement.getElementsByAttribute( "value", dataVal );
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
selectedItem = dataEls.item(0) ? dataEls[0] : defaultItem;
}
}
else
@ -384,7 +384,7 @@ function lazyAppendFontNames( i )
var dataEls = selectElement.listElement.getElementsByAttribute( "value", selectVal );
// we need to honor name-list in case name is unavailable
if (!dataEls.length) {
if (!dataEls.item(0)) {
var fontListPrefString = "font.name-list." + fontTypes[i] + "." + languageList.value;
var nameList = parent.hPrefWindow.pref.CopyUnicharPref( fontListPrefString );
var fontNames = nameList.split(",");
@ -393,11 +393,11 @@ function lazyAppendFontNames( i )
for (j = 0; j < fontNames.length; j++) {
selectVal = fontNames[j].replace(stripWhitespace, "$1");
dataEls = selectElement.listElement.getElementsByAttribute("value", selectVal);
if (dataEls.length)
if (dataEls.item(0))
break; // exit loop if we find one
}
}
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
selectedItem = dataEls.item(0) ? dataEls[0] : defaultItem;
}
catch(e) {
selectedItem = defaultItem;
@ -536,7 +536,7 @@ function saveState()
function minSizeSelect(size)
{
var items = minSize.getElementsByAttribute( "value", size );
if (items.length > 0)
if (items.item(0))
minSize.selectedItem = items[0];
else if (size < 6)
minSizeSelect(6);
@ -644,7 +644,7 @@ function setResolution( resolution )
var userResolution = document.getElementById( "userResolution" );
var items = screenResolution.getElementsByAttribute( "value", resolution );
if (items.length)
if (items.item(0))
{
// If it's one of the hard-coded values, we'll select it directly
screenResolution.selectedItem = items[0];

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

@ -434,7 +434,7 @@ function ReloadSmtpPanel()
if (smtpAuthMethod.getAttribute("value") == "1")
smtpUseUsername.checked = true;
var elements = smtpTrySSL.getElementsByAttribute("value", defaultServer.trySSL);
if (elements.length == 0)
if (!elements.item(0))
elements = smtpTrySSL.getElementsByAttribute("value", "1");
smtpTrySSL.selectedItem = elements[0];
}

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

@ -75,7 +75,7 @@ function initSmtpSettings(server) {
gSmtpAuthMethod.setAttribute("value", server.authMethod);
var elements = gSmtpTrySSL.getElementsByAttribute("value", server.trySSL);
if (elements.length == 0)
if (!elements.item(0))
elements = gSmtpTrySSL.getElementsByAttribute("value", "1");
gSmtpTrySSL.selectedItem = elements[0];
} else {

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

@ -1046,7 +1046,7 @@
<![CDATA[
var menulist = document.getAnonymousNodes(this)[0];
var dataItems = menulist.getElementsByAttribute("value", val);
if (dataItems.length > 0)
if (dataItems.item(0))
menulist.selectedItem = dataItems[0];
// now notify targets of new parent's value
@ -1303,7 +1303,7 @@
if (this.internalOperator != Components.interfaces.nsMsgSearchOp.IsntInAB &&
this.internalOperator != Components.interfaces.nsMsgSearchOp.IsInAB) {
var abs = children[4].getElementsByAttribute("value", "moz-abmdbdirectory://abook.mab");
if (abs.length > 0)
if (abs.item(0))
children[4].selectedItem = abs[0];
this.setAttribute("selectedIndex", "4");
}
@ -1358,7 +1358,7 @@
{
var children = document.getAnonymousNodes(this);
var abs = children[5].getElementsByAttribute("value", "1");
if (abs.length > 0)
if (abs.item(0))
children[5].selectedItem = abs[0];
this.setAttribute("selectedIndex", "5");
}
@ -1388,13 +1388,13 @@
if (attrib == nsMsgSearchAttrib.Priority) {
var matchingPriority =
children[1].getElementsByAttribute("value", val.priority);
if (matchingPriority.length > 0)
if (matchingPriority.item(0))
children[1].selectedItem = matchingPriority[0];
}
else if (attrib == nsMsgSearchAttrib.MsgStatus) {
var matchingStatus =
children[2].getElementsByAttribute("value", val.status);
if (matchingStatus.length > 0)
if (matchingStatus.item(0))
children[2].selectedItem = matchingStatus[0];
}
else if (attrib == nsMsgSearchAttrib.AgeInDays)
@ -1406,7 +1406,7 @@
if (this.internalOperator == Components.interfaces.nsMsgSearchOp.IsntInAB ||
this.internalOperator == Components.interfaces.nsMsgSearchOp.IsInAB) {
var abs = children[4].getElementsByAttribute("value", val.str);
if (abs.length > 0)
if (abs.item(0))
children[4].selectedItem = abs[0];
}
else
@ -1415,19 +1415,19 @@
else if (attrib == nsMsgSearchAttrib.Label)
{
var labelVal = children[5].getElementsByAttribute("value", val.label);
if (labelVal.length > 0)
if (labelVal.item(0))
children[5].selectedItem = labelVal[0];
}
else if (attrib == nsMsgSearchAttrib.JunkStatus) {
var junkStatus =
children[6].getElementsByAttribute("value", val.junkStatus);
if (junkStatus.length > 0)
if (junkStatus.item(0))
children[6].selectedItem = junkStatus[0];
}
else if (attrib == nsMsgSearchAttrib.HasAttachmentStatus) {
var hasAttachmentStatus =
children[7].getElementsByAttribute("value", val.hasAttachmentStatus);
if (hasAttachmentStatus.length > 0)
if (hasAttachmentStatus.item(0))
children[7].selectedItem = hasAttachmentStatus[0];
}
else

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

@ -310,11 +310,10 @@ function initializeDialog(filter)
{
gChangePriorityCheckbox.checked = true;
// initialize priority
var selectedPriority = gActionPriority.getElementsByAttribute("value", filterAction.priority);
var selectedPriority = gActionPriority.getElementsByAttribute("value", filterAction.priority).item(0);
if (selectedPriority && selectedPriority.length > 0)
if (selectedPriority)
{
selectedPriority = selectedPriority[0];
gActionPriority.selectedItem = selectedPriority;
}
}
@ -322,10 +321,9 @@ function initializeDialog(filter)
{
gLabelCheckbox.checked = true;
// initialize label
var selectedLabel = gActionLabel.getElementsByAttribute("value", filterAction.label);
if (selectedLabel && selectedLabel.length > 0)
var selectedLabel = gActionLabel.getElementsByAttribute("value", filterAction.label).item(0);
if (selectedLabel)
{
selectedLabel = selectedLabel[0];
gActionLabel.selectedItem = selectedLabel;
}
}
@ -333,11 +331,10 @@ function initializeDialog(filter)
{
gChangeJunkScoreCheckbox.checked = true;
// initialize junk score
var selectedJunkScore = gActionJunkScore.getElementsByAttribute("value", filterAction.junkScore);
var selectedJunkScore = gActionJunkScore.getElementsByAttribute("value", filterAction.junkScore).item(0);
if (selectedJunkScore && selectedJunkScore.length > 0)
if (selectedJunkScore)
{
selectedJunkScore = selectedJunkScore[0];
gActionJunkScore.selectedItem = selectedJunkScore;
}
}

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

@ -50,7 +50,7 @@ function SelectListItem(listRef, itemValue)
if (itemValue) {
var elements = listRef.getElementsByAttribute("value", itemValue);
selectedItem = elements.length ? elements[0] : null;
selectedItem = elements.item(0);
}
if (selectedItem)

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

@ -262,7 +262,7 @@
if (kids[i].getAttribute(aAttr) == aVal)
return kids[i];
var kids2 = kids[i].getElementsByAttribute(aAttr, aVal);
if (kids2.length > 0)
if (kids2.item(0))
return kids2[0];
}
return null;

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

@ -335,13 +335,13 @@ function onConfigLoad()
}
var descending = document.getElementsByAttribute("sortDirection", "descending");
if (descending.length) {
if (descending.item(0)) {
gSortedColumn = descending[0].id;
gSortDirection = -1;
}
else {
var ascending = document.getElementsByAttribute("sortDirection", "ascending");
if (ascending.length)
if (ascending.item(0))
gSortedColumn = ascending[0].id;
else
document.getElementById(gSortedColumn).setAttribute("sortDirection", "ascending");

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

@ -167,7 +167,7 @@
}
}
var cells = this.mBox.getElementsByAttribute("color", val);
if (cells.length > 0) {
if (cells.item(0)) {
this.selectCell(cells[0]);
this.hoverCell(this.mSelectedCell);
}
@ -479,7 +479,7 @@
var results;
for (var i = 0; i < nodes.length; i++) {
results = nodes[i].getElementsByAttribute("anonid", aValue);
if (results.length > 0)
if (results.item(0))
return results[0];
}
return null;

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

@ -158,7 +158,7 @@
<setter>
<![CDATA[
var kids = this.getElementsByAttribute("value", val);
if (kids && kids.length)
if (kids && kids.item(0))
this.selectItem(kids[0]);
return val;
]]>

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

@ -57,10 +57,10 @@
if (popup) {
var arr = popup.getElementsByAttribute('selected', 'true');
if (!arr.length && this.value)
if (!arr.item(0) && this.value)
arr = popup.getElementsByAttribute('value', this.value);
if (arr.length)
if (arr.item(0))
this.selectedItem = arr[0];
else
this.selectedIndex = 0;
@ -77,7 +77,7 @@
if (popup)
arr = popup.getElementsByAttribute('value', val);
if (arr && arr.length)
if (arr && arr.item(0))
this.selectedItem = arr[0];
else
this.setAttribute('value', val);
@ -287,7 +287,7 @@
if (popup)
arr = popup.getElementsByAttribute('label', this.inputField.value);
if (arr && arr.length)
if (arr && arr.item(0))
this.setSelectionInternal(arr[0]);
else
this.setSelectionInternal(null);

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

@ -116,7 +116,7 @@
<body>
<![CDATA[
var btns = this.getElementsByAttribute("dlgtype", aDlgType);
return btns.length > 0 ? btns[0] : document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aDlgType);
return btns.item(0) ? btns[0] : document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aDlgType);
]]>
</body>
</method>
@ -182,7 +182,7 @@
<parameter name="aPageId"/>
<body><![CDATA[
var els = this.getElementsByAttribute("pageid", aPageId);
return els.length > 0 ? els[0] : null;
return els.item(0);
]]></body>
</method>

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

@ -361,7 +361,7 @@ function lazyAppendFontNames( i )
else
{
var dataEls = selectElement.listElement.getElementsByAttribute( "value", dataVal );
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
selectedItem = dataEls.item(0) ? dataEls.item(0) : defaultItem;
}
}
else
@ -373,7 +373,7 @@ function lazyAppendFontNames( i )
var dataEls = selectElement.listElement.getElementsByAttribute( "value", selectVal );
// we need to honor name-list in case name is unavailable
if (!dataEls.length) {
if (!dataEls.item(0)) {
var fontListPrefString = "font.name-list." + fontTypes[i] + "." + languageList.value;
var nameList = parent.hPrefWindow.pref.getComplexValue( fontListPrefString, Components.interfaces.nsISupportsString ).data;
var fontNames = nameList.split(",");
@ -382,11 +382,11 @@ function lazyAppendFontNames( i )
for (j = 0; j < fontNames.length; j++) {
selectVal = fontNames[j].replace(stripWhitespace, "$1");
dataEls = selectElement.listElement.getElementsByAttribute("value", selectVal);
if (dataEls.length)
if (dataEls.item(0))
break; // exit loop if we find one
}
}
selectedItem = dataEls.length ? dataEls[0] : defaultItem;
selectedItem = dataEls.item(0) ? dataEls.item(0) : defaultItem;
}
catch(e) {
selectedItem = defaultItem;
@ -515,7 +515,7 @@ function saveState()
function minSizeSelect(size)
{
var items = minSize.getElementsByAttribute( "value", size );
if (items.length > 0)
if (items.item(0))
minSize.selectedItem = items[0];
else if (size < 6)
minSizeSelect(6);
@ -623,7 +623,7 @@ function setResolution( resolution )
var userResolution = document.getElementById( "userResolution" );
var items = screenResolution.getElementsByAttribute( "value", resolution );
if (items.length)
if (items.item(0))
{
// If it's one of the hard-coded values, we'll select it directly
screenResolution.selectedItem = items[0];

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

@ -37,7 +37,7 @@ function checkEngine()
var strDefaultSearchEngineName = parent.hPrefWindow.getPref("localizedstring", "browser.search.defaultenginename");
var engineListSelection = engineList.getElementsByAttribute( "label", strDefaultSearchEngineName );
var selectedItem = engineListSelection.length ? engineListSelection[0] : null;
var selectedItem = engineListSelection.item(0);
if (selectedItem)
{

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

@ -494,7 +494,7 @@ function NewCategory()
// try and select the new category
var categoryList = document.getElementById( "categoryList" );
var select_list = categoryList.getElementsByAttribute("id", categoryID);
if (select_list && select_list.length > 0)
if (select_list && select_list.item(0))
{
categoryList.selectedItem = select_list[0];
chooseCategory(categoryList.selectedItem);

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

@ -167,7 +167,7 @@
}
}
var cells = this.mBox.getElementsByAttribute("color", val);
if (cells.length > 0) {
if (cells.item(0)) {
this.selectCell(cells[0]);
this.hoverCell(this.mSelectedCell);
}

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

@ -154,7 +154,7 @@
<setter>
<![CDATA[
var kids = this.getElementsByAttribute("value", val);
if (kids && kids.length)
if (kids && kids.item(0))
this.selectItem(kids[0]);
return val;
]]>

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

@ -49,10 +49,10 @@
if (popup) {
var arr = popup.getElementsByAttribute('selected', 'true');
if (!arr.length && this.value)
if (!arr.item(0) && this.value)
arr = popup.getElementsByAttribute('value', this.value);
if (arr.length)
if (arr.item(0))
this.selectedItem = arr[0];
else
this.selectedIndex = 0;
@ -69,7 +69,7 @@
if (popup)
arr = popup.getElementsByAttribute('value', val);
if (arr && arr.length)
if (arr && arr.item(0))
this.selectedItem = arr[0];
else
this.setAttribute('value', val);
@ -279,10 +279,7 @@
if (popup)
arr = popup.getElementsByAttribute('label', this.inputField.value);
if (arr && arr.length)
this.setSelectionInternal(arr[0]);
else
this.setSelectionInternal(null);
this.setSelectionInternal(arr ? arr.item(0) : null);
]]>
</body>
</method>

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

@ -118,7 +118,7 @@
<body>
<![CDATA[
var btns = this.getElementsByAttribute("dlgtype", aDlgType);
return btns.length > 0 ? btns[0] : document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aDlgType);
return btns.item(0) ? btns[0] : document.getAnonymousElementByAttribute(this._wizardButtons, "dlgtype", aDlgType);
]]>
</body>
</method>
@ -184,7 +184,7 @@
<parameter name="aPageId"/>
<body><![CDATA[
var els = this.getElementsByAttribute("pageid", aPageId);
return els.length > 0 ? els[0] : null;
return els.item(0);
]]></body>
</method>

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

@ -320,13 +320,13 @@ function onConfigLoad()
}
var descending = document.getElementsByAttribute("sortDirection", "descending");
if (descending.length) {
if (descending.item(0)) {
gSortedColumn = descending[0].id;
gSortDirection = -1;
}
else {
var ascending = document.getElementsByAttribute("sortDirection", "ascending");
if (ascending.length)
if (ascending.item(0))
gSortedColumn = ascending[0].id;
else
document.getElementById(gSortedColumn).setAttribute("sortDirection", "ascending");