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

📄 xml_tokenizer.cpp

📁 手机浏览器源码程序,功能强大
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            m_cachedScript = m_doc->document()->docLoader()->requestScript(scriptSrc, charset);
            ++(*m_scriptsIt);
            m_cachedScript->ref(this); // will call executeScripts() again if already cached
            return;
        }
        else {
            // no src attribute - execute from contents of tag
            QString scriptCode = "";
            NodeImpl *child;
            for (child = m_scriptsIt->current()->firstChild(); child; child = child->nextSibling()) {
                if (child->nodeType() == Node::TEXT_NODE || child->nodeType() == Node::CDATA_SECTION_NODE) {
                    scriptCode += static_cast<TextImpl*>(child)->data().string();
                }
            }
            // the script cannot do document.write until we support incremental parsing
            // ### handle the case where the script deletes the node or redirects to
            // another page, etc. (also in notifyFinished())
            // ### the script may add another script node after this one which should be executed
            if (m_view) {
                m_view->part()->executeScript(scriptCode);
            }
            ++(*m_scriptsIt);
        }
    }

    // All scripts have finished executing, so calculate the style for the document and close
    // the last element
    m_doc->document()->updateStyleSelector();
}

void XMLTokenizer::notifyFinished(CachedObject *finishedObj)
{
    // This is called when a script has finished loading that was requested from executeScripts(). We execute
    // the script, and then call executeScripts() again to continue iterating through the list of scripts in
    // the document
    if (finishedObj == m_cachedScript) {
        DOMString scriptSource = m_cachedScript->script();
        m_cachedScript->deref(this);
        m_cachedScript = 0;
        m_view->part()->executeScript(scriptSource.string());
        executeScripts();
    }
}

bool XMLTokenizer::isWaitingForScripts() const
{
    return m_cachedScript != 0;
}

#ifdef KHTML_XSLT
void XMLTokenizer::setTransformSource(DocumentImpl* doc)
{
    // Time to spin up a new parse and save the xmlDocPtr.
    // Parse in a single chunk into an xmlDocPtr
    // FIXME: Hook up error handlers so that a failure to parse the main document results in
    // good error messages.
    const QChar BOM(0xFEFF);
    const unsigned char BOMHighByte = *reinterpret_cast<const unsigned char *>(&BOM);
    xmlDocPtr sourceDoc = xmlReadMemory(reinterpret_cast<const char *>(m_xmlCode.unicode()),
                                        m_xmlCode.length() * sizeof(QChar),
                                        doc->URL().ascii(),
                                        BOMHighByte == 0xFF ? "UTF-16LE" : "UTF-16BE",
                                        XML_PARSE_NOCDATA|XML_PARSE_DTDATTR|XML_PARSE_NOENT);
    doc->setTransformSource(sourceDoc);
}
#endif

Tokenizer *newXMLTokenizer(DocumentPtr *d, KHTMLView *v)
{
    return new XMLTokenizer(d, v);
}

int XMLTokenizer::lineNumber() const
{
    return m_context->input->line;
}

int XMLTokenizer::columnNumber() const
{
    return m_context->input->col;
}

void XMLTokenizer::stopParsing()
{
    xmlStopParser(m_context);
    m_parserStopped = true;
}


#if 0

bool XMLHandler::attributeDecl(const QString &/*eName*/, const QString &/*aName*/, const QString &/*type*/,
                               const QString &/*valueDefault*/, const QString &/*value*/)
{
    // qt's xml parser (as of 2.2.3) does not currently give us values for type, valueDefault and
    // value. When it does, we can store these somewhere and have default attributes on elements
    return true;
}

bool XMLHandler::externalEntityDecl(const QString &/*name*/, const QString &/*publicId*/, const QString &/*systemId*/)
{
    // ### insert these too - is there anything special we have to do here?
    return true;
}

bool XMLHandler::internalEntityDecl(const QString &name, const QString &value)
{
    EntityImpl *e = new EntityImpl(m_doc,name);
    // ### further parse entities inside the value and add them as separate nodes (or entityreferences)?
    e->addChild(m_doc->document()->createTextNode(value));
// ### FIXME
//     if (m_doc->document()->doctype())
//         static_cast<GenericRONamedNodeMapImpl*>(m_doc->document()->doctype()->entities())->addNode(e);
    return true;
}

bool XMLHandler::notationDecl(const QString &name, const QString &publicId, const QString &systemId)
{
// ### FIXME
//     if (m_doc->document()->doctype()) {
//         NotationImpl *n = new NotationImpl(m_doc,name,publicId,systemId);
//         static_cast<GenericRONamedNodeMapImpl*>(m_doc->document()->doctype()->notations())->addNode(n);
//     }
    return true;
}

#endif

// --------------------------------

XMLNamespaceStack::~XMLNamespaceStack()
{
    while (XMLNamespace *ns = m_namespaceStack.pop())
        ns->deref();
}

void XMLNamespaceStack::popNamespaces()
{
    XMLNamespace *ns = m_namespaceStack.pop();
    if (ns)
        ns->deref();
}

XMLNamespace *XMLNamespaceStack::pushNamespaces(XMLAttributes& attrs)
{
    XMLNamespace *ns = m_namespaceStack.current();
    if (!ns)
        ns = new XMLNamespace;

    // Search for any xmlns attributes.
    for (int i = 0; i < attrs.length(); i++) {
        QString qName = attrs.qName(i);
        if (qName == "xmlns")
            ns = new XMLNamespace(QString::null, attrs.value(i), ns);
        else if (qName.startsWith("xmlns:"))
            ns = new XMLNamespace(qName.right(qName.length()-6), attrs.value(i), ns);
    }

    m_namespaceStack.push(ns);
    ns->ref();
    return ns;
}

// --------------------------------

struct AttributeParseState {
    QMap<QString, QString> attributes;
    bool gotAttributes;
};

static void attributesStartElementHandler(void *userData, const xmlChar *name, const xmlChar **libxmlAttributes)
{
    if (strcmp(reinterpret_cast<const char *>(name), "attrs") != 0) {
        return;
    }

    AttributeParseState *state = static_cast<AttributeParseState *>(userData);

    state->gotAttributes = true;

    XMLAttributes attributes(reinterpret_cast<const char **>(libxmlAttributes));
    XMLNamespaceStack stack;
    attributes.split(stack.pushNamespaces(attributes));
    int length = attributes.length();
    for (int i = 0; i != length; ++i) {
        state->attributes.insert(attributes.qName(i), attributes.value(i));
    }
}

QMap<QString, QString> parseAttributes(const DOMString &string, bool &attrsOK)
{
    AttributeParseState state;
    state.gotAttributes = false;

    xmlSAXHandler sax;
    memset(&sax, 0, sizeof(sax));
    sax.startElement = attributesStartElementHandler;
    xmlParserCtxtPtr parser = createQStringParser(&sax, &state);
    parseQString(parser, "<?xml version=\"1.0\"?><attrs " + string.string() + " />");
    xmlFreeParserCtxt(parser);

    attrsOK = state.gotAttributes;
    return state.attributes;
}

// --------------------------------

XMLAttributes::XMLAttributes(const char **saxStyleAttributes)
    : _ref(0), _uris(0)
{
    int length = 0;
    if (saxStyleAttributes) {
        for (const char **p = saxStyleAttributes; *p; p += 2) {
            ++length;
        }
    }

    _length = length;
    if (!length) {
        _names = 0;
        _values = 0;
        _uris = 0;
    } else {
        _names = new QString [length];
        _values = new QString [length];
    }

    if (saxStyleAttributes) {
        int i = 0;
        for (const char **p = saxStyleAttributes; *p; p += 2) {
            _names[i] = QString::fromUtf8(p[0]);
            _values[i] = QString::fromUtf8(p[1]);
            ++i;
        }
    }
}

XMLAttributes::~XMLAttributes()
{
    if (_ref && !--*_ref) {
        delete _ref;
        _ref = 0;
    }
    if (!_ref) {
        delete [] _names;
        delete [] _values;
        delete [] _uris;
    }
}

XMLAttributes::XMLAttributes(const XMLAttributes &other)
    : _ref(other._ref)
    , _length(other._length)
    , _names(other._names)
    , _values(other._values)
    , _uris(other._uris)
{
    if (!_ref) {
        _ref = new int (2);
        other._ref = _ref;
    } else {
        ++*_ref;
    }
}

XMLAttributes &XMLAttributes::operator=(const XMLAttributes &other)
{
    if (_ref && !--*_ref) {
        delete _ref;
        _ref = 0;
    }
    if (!_ref) {
        delete [] _names;
        delete [] _values;
        delete [] _uris;
    }

    _ref = other._ref;
    _length = other._length;
    _names = other._names;
    _values = other._values;
    _uris = other._uris;

    if (!_ref) {
        _ref = new int (2);
        other._ref = _ref;
    } else {
        ++*_ref;
    }

    return *this;
}

QString XMLAttributes::localName(int index) const
{
    int colonPos = _names[index].find(':');
    if (colonPos != -1)
        // Peel off the prefix to return the localName.
        return _names[index].right(_names[index].length() - colonPos - 1);
    return _names[index];
}

QString XMLAttributes::value(const QString &name) const
{
    for (int i = 0; i != _length; ++i) {
        if (name == _names[i]) {
            return _values[i];
        }
    }
    return QString::null;
}

void XMLAttributes::split(XMLNamespace* ns)
{
    for (int i = 0; i < _length; ++i) {
        int colonPos = _names[i].find(':');
        if (colonPos != -1) {
            QString prefix = _names[i].left(colonPos);
            QString uri;
            if (prefix == "xmlns") {
                // FIXME: The URI is the xmlns namespace? I seem to recall DOM lvl 3 saying something about this.
            }
            else
                uri = ns->uriForPrefix(prefix);

            if (!uri.isEmpty()) {
                if (!_uris)
                    _uris = new QString[_length];
                _uris[i] = uri;
            }
        }
    }
}

}

#include "xml_tokenizer.moc"

⌨️ 快捷键说明

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