📄 html_miscimpl.cpp
字号:
QString idAttr = e->getAttribute(ATTR_ID).string();
QString nameAttr = e->getAttribute(ATTR_NAME).string();
if (!idAttr.isEmpty()) {
// add to id cache
QPtrVector<NodeImpl> *idVector = info->idCache.find(idAttr);
if (!idVector) {
idVector = new QPtrVector<NodeImpl>;
info->idCache.insert(idAttr, idVector);
}
appendToVector(idVector, n);
}
if (!nameAttr.isEmpty() && idAttr != nameAttr
&& (type != DOC_ALL ||
(e->id() == ID_IMG || e->id() == ID_FORM ||
e->id() == ID_APPLET || e->id() == ID_OBJECT ||
e->id() == ID_EMBED))) {
// add to name cache
QPtrVector<NodeImpl> *nameVector = info->nameCache.find(nameAttr);
if (!nameVector) {
nameVector = new QPtrVector<NodeImpl>;
info->nameCache.insert(nameAttr, nameVector);
}
appendToVector(nameVector, n);
}
}
info->hasNameCache = true;
}
QValueList<Node> HTMLCollectionImpl::namedItems(const DOMString &name) const
{
QValueList<Node> result;
if (name.isEmpty())
return result;
#if NOKIA_CHANGES
// optimisation: first find if there are some nodes already in the cache
// - this might cause some abnormal behaviors, but could achieve better
// performance because updateNameCache() is extremely slow for big collections.
// (e.g., the hugh form of www.finnair.fi).
if( info )
{
QPtrVector<NodeImpl>* ids = info->idCache.find(name.string());
QPtrVector<NodeImpl>* names = info->nameCache.find(name.string());
for (unsigned i = 0; ids && i < ids->count(); ++i) {
result.append(ids->at(i));
}
for (unsigned i = 0; names && i < names->count(); ++i) {
result.append(names->at(i));
}
if( !result.isEmpty() ) return result;
}
#endif
resetCollectionInfo();
updateNameCache();
QPtrVector<NodeImpl> *idResults = info->idCache.find(name.string());
QPtrVector<NodeImpl> *nameResults = info->nameCache.find(name.string());
for (unsigned i = 0; idResults && i < idResults->count(); ++i) {
result.append(idResults->at(i));
}
for (unsigned i = 0; nameResults && i < nameResults->count(); ++i) {
result.append(nameResults->at(i));
}
return result;
}
NodeImpl *HTMLCollectionImpl::nextNamedItem( const DOMString &name ) const
{
resetCollectionInfo();
for (NodeImpl *n = traverseNextItem(info->current ? info->current : base); n; n = traverseNextItem(n)) {
if (checkForNameMatch(n, idsDone, name, true)) {
info->current = n;
return n;
}
}
if (idsDone) {
info->current = 0;
return 0;
}
idsDone = true;
for (NodeImpl *n = traverseNextItem(info->current ? info->current : base); n; n = traverseNextItem(n)) {
if (checkForNameMatch(n, idsDone, name, true)) {
info->current = n;
return n;
}
}
return 0;
}
// -----------------------------------------------------------------------------
HTMLFormCollectionImpl::HTMLFormCollectionImpl(NodeImpl* _base)
: HTMLCollectionImpl(_base, 0)
{
HTMLFormElementImpl *formBase = static_cast<HTMLFormElementImpl*>(base);
if (!formBase->collectionInfo) {
formBase->collectionInfo = new CollectionInfo();
}
info = formBase->collectionInfo;
}
HTMLFormCollectionImpl::~HTMLFormCollectionImpl()
{
}
unsigned long HTMLFormCollectionImpl::calcLength() const
{
QPtrVector<HTMLGenericFormElementImpl> &l = static_cast<HTMLFormElementImpl*>( base )->formElements;
int len = 0;
for ( unsigned i = 0; i < l.count(); i++ )
if ( l.at( i )->isEnumeratable() )
++len;
return len;
}
NodeImpl *HTMLFormCollectionImpl::item(unsigned long index) const
{
resetCollectionInfo();
if (info->current && info->position == index) {
return info->current;
}
if (info->haslength && info->length <= index) {
return 0;
}
if (!info->current || info->position > index) {
info->current = 0;
info->position = 0;
info->elementsArrayPosition = 0;
}
QPtrVector<HTMLGenericFormElementImpl> &l = static_cast<HTMLFormElementImpl*>( base )->formElements;
unsigned currentIndex = info->position;
for (unsigned i = info->elementsArrayPosition; i < l.count(); i++) {
if (l[i]->isEnumeratable() ) {
if (index == currentIndex) {
info->position = index;
info->current = l[i];
info->elementsArrayPosition = i;
return l[i];
}
currentIndex++;
}
}
return 0;
}
NodeImpl* HTMLFormCollectionImpl::getNamedItem(NodeImpl*, int attr_id, const DOMString& name, bool caseSensitive) const
{
info->position = 0;
return getNamedFormItem( attr_id, name, 0, caseSensitive );
}
NodeImpl* HTMLFormCollectionImpl::getNamedFormItem(int attr_id, const DOMString& name, int duplicateNumber, bool caseSensitive) const
{
if(base->nodeType() == Node::ELEMENT_NODE)
{
HTMLElementImpl* baseElement = static_cast<HTMLElementImpl*>(base);
bool foundInputElements = false;
if(baseElement->id() == ID_FORM)
{
HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(baseElement);
for (unsigned i = 0; i < f->formElements.count(); ++i) {
HTMLGenericFormElementImpl* e = f->formElements[i];
if (e->isEnumeratable()) {
bool found;
if (caseSensitive)
found = e->getAttribute(attr_id) == name;
else
found = e->getAttribute(attr_id).domString().lower() == name.lower();
if (found) {
foundInputElements = true;
if (!duplicateNumber)
return e;
--duplicateNumber;
}
}
}
}
if ( !foundInputElements )
{
HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(baseElement);
for(unsigned i = 0; i < f->imgElements.count(); ++i)
{
HTMLImageElementImpl* e = f->imgElements[i];
bool found;
if (caseSensitive)
found = e->getAttribute(attr_id) == name;
else
found = e->getAttribute(attr_id).domString().lower() == name.lower();
if (found) {
if (!duplicateNumber)
return e;
--duplicateNumber;
}
}
}
}
return 0;
}
NodeImpl * HTMLFormCollectionImpl::firstItem() const
{
return item(0);
}
NodeImpl * HTMLFormCollectionImpl::nextItem() const
{
return item(info->position + 1);
}
NodeImpl * HTMLFormCollectionImpl::nextNamedItemInternal( const DOMString &name ) const
{
NodeImpl *retval = getNamedFormItem( idsDone ? ATTR_NAME : ATTR_ID, name, ++info->position, true );
if ( retval )
return retval;
if ( idsDone ) // we're done
return 0;
// After doing all ATTR_ID, do ATTR_NAME
idsDone = true;
return getNamedItem(base->firstChild(), ATTR_NAME, name, true);
}
NodeImpl *HTMLFormCollectionImpl::namedItem( const DOMString &name, bool caseSensitive ) const
{
// http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
// This method first searches for an object with a matching id
// attribute. If a match is not found, the method then searches for an
// object with a matching name attribute, but only on those elements
// that are allowed a name attribute.
resetCollectionInfo();
idsDone = false;
info->current = getNamedItem(base->firstChild(), ATTR_ID, name, true);
if(info->current)
return info->current;
idsDone = true;
info->current = getNamedItem(base->firstChild(), ATTR_NAME, name, true);
return info->current;
}
NodeImpl *HTMLFormCollectionImpl::nextNamedItem( const DOMString &name ) const
{
// nextNamedItemInternal can return an item that has both id=<name> and name=<name>
// Here, we have to filter out such cases.
NodeImpl *impl = nextNamedItemInternal( name );
if (!idsDone) // looking for id=<name> -> no filtering
return impl;
// looking for name=<name> -> filter out if id=<name>
bool ok = false;
while (impl && !ok)
{
if(impl->nodeType() == Node::ELEMENT_NODE)
{
HTMLElementImpl *e = static_cast<HTMLElementImpl *>(impl);
ok = (e->getAttribute(ATTR_ID) != name);
if (!ok)
impl = nextNamedItemInternal( name );
} else // can't happen
ok = true;
}
return impl;
}
void HTMLFormCollectionImpl::updateNameCache() const
{
if (info->hasNameCache)
return;
QDict<char> foundInputElements;
if (base->nodeType() != Node::ELEMENT_NODE ||static_cast<HTMLElementImpl*>(base)->id() != ID_FORM) {
info->hasNameCache = true;
return;
}
HTMLElementImpl* baseElement = static_cast<HTMLElementImpl*>(base);
HTMLFormElementImpl* f = static_cast<HTMLFormElementImpl*>(baseElement);
for (unsigned i = 0; i < f->formElements.count(); ++i) {
HTMLGenericFormElementImpl* e = f->formElements[i];
if (e->isEnumeratable()) {
QString idAttr = e->getAttribute(ATTR_ID).string();
QString nameAttr = e->getAttribute(ATTR_NAME).string();
if (!idAttr.isEmpty()) {
// add to id cache
QPtrVector<NodeImpl> *idVector = info->idCache.find(idAttr);
if (!idVector) {
idVector = new QPtrVector<NodeImpl>;
info->idCache.insert(idAttr, idVector);
}
appendToVector(idVector, static_cast<NodeImpl *>(e));
foundInputElements.insert(idAttr, (char *)true);
}
if (!nameAttr.isEmpty() && idAttr != nameAttr) {
// add to name cache
QPtrVector<NodeImpl> *nameVector = info->nameCache.find(nameAttr);
if (!nameVector) {
nameVector = new QPtrVector<NodeImpl>;
info->nameCache.insert(nameAttr, nameVector);
}
appendToVector(nameVector, static_cast<NodeImpl *>(e));
foundInputElements.insert(nameAttr, (char *)true);
}
}
}
for (unsigned i = 0; i < f->imgElements.count(); ++i) {
HTMLImageElementImpl* e = f->imgElements[i];
QString idAttr = e->getAttribute(ATTR_ID).string();
QString nameAttr = e->getAttribute(ATTR_NAME).string();
if (!idAttr.isEmpty() && !foundInputElements.find(idAttr)) {
// add to id cache
QPtrVector<NodeImpl> *idVector = info->idCache.find(idAttr);
if (!idVector) {
idVector = new QPtrVector<NodeImpl>;
info->idCache.insert(idAttr, idVector);
}
appendToVector(idVector, static_cast<NodeImpl *>(e));
}
if (!nameAttr.isEmpty() && idAttr != nameAttr && !foundInputElements.find(nameAttr)) {
// add to name cache
QPtrVector<NodeImpl> *nameVector = info->nameCache.find(nameAttr);
if (!nameVector) {
nameVector = new QPtrVector<NodeImpl>;
info->nameCache.insert(nameAttr, nameVector);
}
appendToVector(nameVector, static_cast<NodeImpl *>(e));
}
}
info->hasNameCache = true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -