⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 html_miscimpl.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
字号:
/** * This file is part of the DOM implementation for KDE. * * Copyright (C) 1999 Lars Knoll (knoll@kde.org) *           (C) 1999 Antti Koivisto (koivisto@kde.org) *           (C) 2005 Maksim Orlovich (maksim@kde.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */// -------------------------------------------------------------------------#include "html/html_tableimpl.h"#include "html/html_miscimpl.h"#include "html/html_formimpl.h"#include "html/html_documentimpl.h"#include "misc/htmlhashes.h"#include "dom/dom_node.h"using namespace DOM;#include <kdebug.h>HTMLBaseFontElementImpl::HTMLBaseFontElementImpl(DocumentPtr *doc)    : HTMLElementImpl(doc){}HTMLBaseFontElementImpl::~HTMLBaseFontElementImpl(){}NodeImpl::Id HTMLBaseFontElementImpl::id() const{    return ID_BASEFONT;}// -------------------------------------------------------------------------struct CollectionCache: public NodeListImpl::Cache{    static Cache* make() { return new CollectionCache; }    QDict<QValueList<NodeImpl*> > nameCache;    CollectionCache(): nameCache(127)    {        nameCache.setAutoDelete(true);    }    virtual void clear(DocumentImpl* doc)    {        Cache::clear(doc);        //qDeletaAll here in Qt4        nameCache.clear();    }};HTMLCollectionImpl::HTMLCollectionImpl(NodeImpl *_base, int _type):    NodeListImpl(_base, _type, CollectionCache::make){    type = _type;}bool HTMLCollectionImpl::nodeMatches(NodeImpl *current, bool& deep) const{    if ( current->nodeType() != Node::ELEMENT_NODE )    {        deep = false;        return false;    }    bool check = false;    HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);    switch(type)    {    case DOC_IMAGES:        if(e->id() == ID_IMG)            check = true;        break;    case DOC_FORMS:        if(e->id() == ID_FORM)            check = true;        break;    case DOC_LAYERS:        if(e->id() == ID_LAYER || e->id() == ID_ILAYER)            check = true;        break;    case TABLE_TBODIES:        if(e->id() == ID_TBODY)            check = true;        else if(e->id() == ID_TABLE)            deep = false;        break;    case TR_CELLS:        if(e->id() == ID_TD || e->id() == ID_TH)            check = true;        else if(e->id() == ID_TABLE)            deep = false;        break;    case TABLE_ROWS:    case TSECTION_ROWS:    case TABLE_BODY_ROWS:        if(e->id() == ID_TR)            check = true;        else if(e->id() == ID_TABLE)            deep = false;        else if (type == TABLE_BODY_ROWS) {            //Avoid going inside the thead, tfoot.            const HTMLTableElementImpl* table = static_cast<const HTMLTableElementImpl*>(m_refNode);            if (e == table->tHead() || e == table->tFoot())                deep = false;        }        break;    case SELECT_OPTIONS:        if(e->id() == ID_OPTION)            check = true;        break;    case MAP_AREAS:        if(e->id() == ID_AREA)            check = true;        break;    case DOC_APPLETS:   // all OBJECT and APPLET elements        if(e->id() == ID_OBJECT || e->id() == ID_APPLET || e->id() == ID_EMBED)            check = true;        break;    case DOC_LINKS:     // all A _and_ AREA elements with a value for href        if(e->id() == ID_A || e->id() == ID_AREA)            if(!e->getAttribute(ATTR_HREF).isNull())                check = true;        break;    case DOC_ANCHORS:      // all A elements with a value for name and/or id        if(e->id() == ID_A) {            if(e->hasID() || !e->getAttribute(ATTR_NAME).isNull())                check = true;        }        break;    case DOC_ALL:      // "all" elements        check = true;        break;    case NODE_CHILDREN: // first-level children        check = true;        deep = false;        break;    default:        kdDebug( 6030 ) << "Error in HTMLCollection, wrong tagId!" << endl;    }    return check;}bool HTMLCollectionImpl::checkForNameMatch(NodeImpl *node, const DOMString &name) const{    if ( node->nodeType() != Node::ELEMENT_NODE )        return false;    HTMLElementImpl *e = static_cast<HTMLElementImpl *>(node);    //If ID matches, this is definitely a match    if (e->getAttribute(ATTR_ID) == name)        return true;    //Despite what the DOM spec says, neither IE nor Gecko actually    //care to prefer IDs. Instead, they just match everything    //that has ID or a name for nodes that have a name.    //Except for the form elements collection, Gecko always returns    //just one item. IE is more complex: its namedItem    //and call notation access return everything that matches,    //but the subscript notation is sometimes different.    //For now, we try to match IE, but without the subscript    //oddness, which I don't understand -- Maks.    bool checkName;    switch (e->id())    {        case ID_A:        case ID_APPLET:        case ID_BUTTON:        case ID_EMBED:        case ID_FORM:        case ID_IMG:        case ID_INPUT:        case ID_MAP:        case ID_META:        case ID_OBJECT:        case ID_SELECT:        case ID_TEXTAREA:            checkName = true;            break;        default:            checkName = false;    }    if (checkName)       return e->getAttribute(ATTR_NAME) == name;    else       return false;}NodeImpl *HTMLCollectionImpl::item ( unsigned long index ) const{    //Most of the time, we just go in normal document order    if (type != TABLE_ROWS)        return NodeListImpl::item(index);    //For table.rows, we first need to check header, then bodies, then footer.    //we pack any extra headers/footer with bodies. This matches IE, and     //means doing the usual thing with length is right    //### fix constness throughout instead of loosing the const    HTMLTableElementImpl* table = const_cast<HTMLTableElementImpl*>(                            static_cast<const HTMLTableElementImpl*>(m_refNode));    //Keep track of position for the namedItem code    unsigned long origIndex = index;    NodeImpl* found = 0;    if (table->tHead()) {        HTMLCollectionImpl headerRows(table->tHead(), TSECTION_ROWS);        unsigned headerLength = headerRows.length();        if (index < headerLength)            found = headerRows.item(index);        else            index -= headerLength;    }    if (!found) {        HTMLCollectionImpl bodyRows(table, TABLE_BODY_ROWS);        unsigned bodyLength = bodyRows.length();        if (index < bodyLength)            found = bodyRows.item(index);        else            index -= bodyLength;    }    if (!found && table->tFoot()) {        HTMLCollectionImpl footerRows(table->tFoot(), TSECTION_ROWS);        found = footerRows.item(index);    }    m_cache->current.node = found; //namedItem needs this.    m_cache->position     = origIndex;    return found;}NodeImpl *HTMLCollectionImpl::firstItem() const{    return item(0);}NodeImpl *HTMLCollectionImpl::nextItem() const{    //### this assumes this is called immediately after nextItem --    //it this sane?    return item(m_cache->position + 1);}NodeImpl *HTMLCollectionImpl::namedItem( const DOMString &name ) const{    //Reset the position. The invariant is that nextNamedItem will start looking    //from the current position.    firstItem();    return nextNamedItem(name);}NodeImpl *HTMLCollectionImpl::nextNamedItem( const DOMString &name ) const{    while (NodeImpl* candidate = m_cache->current.node)    {        //Always advance, for next call        nextItem();        if (checkForNameMatch(candidate, name))            return candidate;    }    return 0;}QValueList<NodeImpl*> HTMLCollectionImpl::namedItems( const DOMString &name ) const{    QString key = name.string();    //We use a work-conserving design for the name cache presently -- only    //remember stuff about elements we were asked for.    m_cache->updateNodeListInfo(m_refNode->getDocument());    CollectionCache* cache = static_cast<CollectionCache*>(m_cache);    if (QValueList<NodeImpl*>* info = cache->nameCache.find(key)) {        return *info;    }    else {        QValueList<NodeImpl*>* newInfo = new QValueList<NodeImpl*>;        NodeImpl* match = namedItem(name);        while (match) {            newInfo->append(match);            match = nextNamedItem(name);        }        cache->nameCache.insert(key, newInfo);        return *newInfo;    }}// -----------------------------------------------------------------------------HTMLFormCollectionImpl::HTMLFormCollectionImpl(NodeImpl* _base)    : HTMLCollectionImpl(_base, FORM_ELEMENTS), currentNamePos(0), currentNameImgPos(0){}NodeImpl *HTMLFormCollectionImpl::item( unsigned long index ) const{    m_cache->updateNodeListInfo(m_refNode->getDocument());    unsigned int dist = index;    unsigned int strt = 0;    if (m_cache->current.index && m_cache->position <= index)    {        dist = index - m_cache->position;        strt = m_cache->current.index;    }    QPtrList<HTMLGenericFormElementImpl>& l = static_cast<HTMLFormElementImpl*>( m_refNode )->formElements;    for (unsigned i = strt; i < l.count(); i++)    {        if (l.at( i )->isEnumeratable())        {            if (dist == 0)            {                //Found it!                m_cache->position      = index;                m_cache->current.index = i;                return l.at( i );            }            else                --dist;        }    }    return 0;}unsigned long HTMLFormCollectionImpl::length() const{    m_cache->updateNodeListInfo(m_refNode->getDocument());    if (!m_cache->hasLength)    {        m_cache->length = 0;        QPtrList<HTMLGenericFormElementImpl> l = static_cast<HTMLFormElementImpl*>( m_refNode )->formElements;        for ( unsigned i = 0; i < l.count(); i++ )            if ( l.at( i )->isEnumeratable() )                ++m_cache->length;        m_cache->hasLength = true;    }    return m_cache->length;}NodeImpl *HTMLFormCollectionImpl::namedItem( const DOMString &name ) const{    currentNamePos    = 0;    currentNameImgPos = 0;    foundInput        = false;    return nextNamedItem(name);}NodeImpl *HTMLFormCollectionImpl::nextNamedItem( const DOMString &name ) const{    QPtrList<HTMLGenericFormElementImpl>& l = static_cast<HTMLFormElementImpl*>( m_refNode )->formElements;    //Go through the list, trying to find the appropriate named form element.    for ( ; currentNamePos < l.count(); ++currentNamePos )    {        HTMLGenericFormElementImpl* el = l.at(currentNamePos);        if (el->isEnumeratable() &&             ((el->getAttribute(ATTR_ID)   == name) ||              (el->getAttribute(ATTR_NAME) == name)))        {            ++currentNamePos; //Make next call start after this            foundInput = true;//No need to look for img            return el;        }    }    //If we got this far, we may need to start looking through the images,    //but only if no input tags were matched    if (foundInput) return 0;    QPtrList<HTMLImageElementImpl>& il = static_cast<HTMLFormElementImpl*>( m_refNode )->imgElements;    for ( ; currentNameImgPos < il.count(); ++currentNameImgPos )    {        HTMLImageElementImpl* el = il.at(currentNameImgPos);        if ((el->getAttribute(ATTR_ID)   == name) ||            (el->getAttribute(ATTR_NAME) == name))        {            ++currentNameImgPos; //Make next call start after this            return el;        }    }    return 0;}// -------------------------------------------------------------------------HTMLMappedNameCollectionImpl::HTMLMappedNameCollectionImpl(NodeImpl* _base, int _type, const DOMString& _name):     HTMLCollectionImpl(_base, NodeListImpl::UNCACHEABLE), name(_name) {    type = _type; //We pass uncacheable to collection, but need our own type internally.}bool HTMLMappedNameCollectionImpl::nodeMatches(NodeImpl *current, bool& deep) const{    if ( current->nodeType() != Node::ELEMENT_NODE )    {        deep = false;        return false;    }    HTMLElementImpl *e = static_cast<HTMLElementImpl *>(current);        return matchesName(e, type, name);}bool HTMLMappedNameCollectionImpl::matchesName( ElementImpl* el, int type, const DOMString& name ){    switch (el->id())    {    case ID_IMG:    case ID_FORM:        //Under document. these require non-empty name to see the element        if (type == DOCUMENT_NAMED_ITEMS && el->getAttribute(ATTR_NAME).isNull())            return false;        //Otherwise, fallthrough    case ID_OBJECT:    case ID_EMBED:    case ID_APPLET:    case ID_LAYER:        if (el->getAttribute(ATTR_NAME) == name || el->getAttribute(ATTR_ID) == name)            return true;        else            return false;    default:        return false;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -