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

📄 markup.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    // Don't add namespace attribute if it is already defined for this elem.    const AtomicString& prefix = elem->prefix();    AtomicString attr = !prefix.isEmpty() ? "xmlns:" + prefix : "xmlns";    return !elem->hasAttribute(attr);}static bool shouldAddNamespaceAttr(const Attribute* attr, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces){    // Don't add namespace attributes twice    DEFINE_STATIC_LOCAL(const AtomicString, xmlnsURI, ("http://www.w3.org/2000/xmlns/"));    DEFINE_STATIC_LOCAL(const QualifiedName, xmlnsAttr, (nullAtom, "xmlns", xmlnsURI));    if (attr->name() == xmlnsAttr) {        namespaces.set(emptyAtom.impl(), attr->value().impl());        return false;    }        QualifiedName xmlnsPrefixAttr("xmlns", attr->localName(), xmlnsURI);    if (attr->name() == xmlnsPrefixAttr) {        namespaces.set(attr->localName().impl(), attr->value().impl());        return false;    }        return true;}static void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, const AtomicString& ns, HashMap<AtomicStringImpl*, AtomicStringImpl*>& namespaces){    if (ns.isEmpty())        return;            // Use emptyAtoms's impl() for both null and empty strings since the HashMap can't handle 0 as a key    AtomicStringImpl* pre = prefix.isEmpty() ? emptyAtom.impl() : prefix.impl();    AtomicStringImpl* foundNS = namespaces.get(pre);    if (foundNS != ns.impl()) {        namespaces.set(pre, ns.impl());        DEFINE_STATIC_LOCAL(const String, xmlns, ("xmlns"));        result.append(' ');        append(result, xmlns);        if (!prefix.isEmpty()) {            result.append(':');            append(result, prefix);        }        result.append('=');        result.append('"');        appendAttributeValue(result, ns, false);        result.append('"');    }}static void appendDocumentType(Vector<UChar>& result, const DocumentType* n){    if (n->name().isEmpty())        return;    append(result, "<!DOCTYPE ");    append(result, n->name());    if (!n->publicId().isEmpty()) {        append(result, " PUBLIC \"");        append(result, n->publicId());        append(result, "\"");        if (!n->systemId().isEmpty()) {            append(result, " \"");            append(result, n->systemId());            append(result, "\"");        }    } else if (!n->systemId().isEmpty()) {        append(result, " SYSTEM \"");        append(result, n->systemId());        append(result, "\"");    }    if (!n->internalSubset().isEmpty()) {        append(result, " [");        append(result, n->internalSubset());        append(result, "]");    }    append(result, ">");}static void appendStartMarkup(Vector<UChar>& result, const Node *node, const Range *range, EAnnotateForInterchange annotate, bool convertBlocksToInlines = false, HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0){    bool documentIsHTML = node->document()->isHTMLDocument();    switch (node->nodeType()) {        case Node::TEXT_NODE: {            if (Node* parent = node->parentNode()) {                if (parent->hasTagName(scriptTag)                    || parent->hasTagName(styleTag)                    || parent->hasTagName(textareaTag)                    || parent->hasTagName(xmpTag)) {                    appendUCharRange(result, ucharRange(node, range));                    break;                }            }            if (!annotate) {                appendEscapedContent(result, ucharRange(node, range), documentIsHTML);                break;            }                        bool useRenderedText = !enclosingNodeWithTag(Position(const_cast<Node*>(node), 0), selectTag);            String markup = escapeContentText(useRenderedText ? renderedText(node, range) : stringValueForRange(node, range), false);            if (annotate)                markup = convertHTMLTextToInterchangeFormat(markup, static_cast<const Text*>(node));            append(result, markup);            break;        }        case Node::COMMENT_NODE:            // FIXME: Comment content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "-->".            append(result, "<!--");            append(result, static_cast<const Comment*>(node)->nodeValue());            append(result, "-->");            break;        case Node::DOCUMENT_NODE:        case Node::DOCUMENT_FRAGMENT_NODE:            break;        case Node::DOCUMENT_TYPE_NODE:            appendDocumentType(result, static_cast<const DocumentType*>(node));            break;        case Node::PROCESSING_INSTRUCTION_NODE: {            // FIXME: PI data is not escaped, but XMLSerializer (and possibly other callers) this should raise an exception if it includes "?>".            const ProcessingInstruction* n = static_cast<const ProcessingInstruction*>(node);            append(result, "<?");            append(result, n->target());            append(result, " ");            append(result, n->data());            append(result, "?>");            break;        }        case Node::ELEMENT_NODE: {            result.append('<');            const Element* el = static_cast<const Element*>(node);            bool convert = convertBlocksToInlines & isBlock(const_cast<Node*>(node));            append(result, el->nodeNamePreservingCase());            NamedAttrMap *attrs = el->attributes();            unsigned length = attrs->length();            if (!documentIsHTML && namespaces && shouldAddNamespaceElem(el))                appendNamespace(result, el->prefix(), el->namespaceURI(), *namespaces);            for (unsigned int i = 0; i < length; i++) {                Attribute *attr = attrs->attributeItem(i);                // We'll handle the style attribute separately, below.                if (attr->name() == styleAttr && el->isHTMLElement() && (annotate || convert))                    continue;                result.append(' ');                if (documentIsHTML)                    append(result, attr->name().localName());                else                    append(result, attr->name().toString());                result.append('=');                if (el->isURLAttribute(attr))                    appendQuotedURLAttributeValue(result, attr->value());                else {                    result.append('\"');                    appendAttributeValue(result, attr->value(), documentIsHTML);                    result.append('\"');                }                if (!documentIsHTML && namespaces && shouldAddNamespaceAttr(attr, *namespaces))                    appendNamespace(result, attr->prefix(), attr->namespaceURI(), *namespaces);            }                        if (el->isHTMLElement() && (annotate || convert)) {                Element* element = const_cast<Element*>(el);                RefPtr<CSSMutableStyleDeclaration> style = static_cast<HTMLElement*>(element)->getInlineStyleDecl()->copy();                if (annotate) {                    RefPtr<CSSMutableStyleDeclaration> styleFromMatchedRules = styleFromMatchedRulesForElement(const_cast<Element*>(el));                    // Styles from the inline style declaration, held in the variable "style", take precedence                     // over those from matched rules.                    styleFromMatchedRules->merge(style.get());                    style = styleFromMatchedRules;                                        RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = computedStyle(element);                    RefPtr<CSSMutableStyleDeclaration> fromComputedStyle = CSSMutableStyleDeclaration::create();                                        {                        CSSMutableStyleDeclaration::const_iterator end = style->end();                        for (CSSMutableStyleDeclaration::const_iterator it = style->begin(); it != end; ++it) {                            const CSSProperty& property = *it;                            CSSValue* value = property.value();                            // The property value, if it's a percentage, may not reflect the actual computed value.                              // For example: style="height: 1%; overflow: visible;" in quirksmode                            // FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem                            if (value->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)                                if (static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE)                                    if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))                                        fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));                        }                    }                                        style->merge(fromComputedStyle.get());                }                if (convert)                    style->setProperty(CSSPropertyDisplay, CSSValueInline, true);                if (style->length() > 0) {                    DEFINE_STATIC_LOCAL(const String, stylePrefix, (" style=\""));                    append(result, stylePrefix);                    appendAttributeValue(result, style->cssText(), documentIsHTML);                    result.append('\"');                }            }                        if (shouldSelfClose(el)) {                if (el->isHTMLElement())                    result.append(' '); // XHTML 1.0 <-> HTML compatibility.                result.append('/');            }            result.append('>');            break;        }        case Node::CDATA_SECTION_NODE: {            // FIXME: CDATA content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "]]>".            const CDATASection* n = static_cast<const CDATASection*>(node);            append(result, "<![CDATA[");            append(result, n->data());            append(result, "]]>");            break;        }        case Node::ATTRIBUTE_NODE:        case Node::ENTITY_NODE:        case Node::ENTITY_REFERENCE_NODE:        case Node::NOTATION_NODE:        case Node::XPATH_NAMESPACE_NODE:            ASSERT_NOT_REACHED();            break;    }}static String getStartMarkup(const Node *node, const Range *range, EAnnotateForInterchange annotate, bool convertBlocksToInlines = false, HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0){    Vector<UChar> result;    appendStartMarkup(result, node, range, annotate, convertBlocksToInlines, namespaces);    return String::adopt(result);}static inline bool doesHTMLForbidEndTag(const Node *node){    if (node->isHTMLElement()) {        const HTMLElement* htmlElt = static_cast<const HTMLElement*>(node);        return (htmlElt->endTagRequirement() == TagStatusForbidden);    }    return false;}// Rules of self-closure// 1. No elements in HTML documents use the self-closing syntax.// 2. Elements w/ children never self-close because they use a separate end tag.// 3. HTML elements which do not have a "forbidden" end tag will close with a separate end tag.// 4. Other elements self-close.static inline bool shouldSelfClose(const Node *node){    if (node->document()->isHTMLDocument())        return false;    if (node->hasChildNodes())        return false;    if (node->isHTMLElement() && !doesHTMLForbidEndTag(node))        return false;    return true;}static void appendEndMarkup(Vector<UChar>& result, const Node* node){    if (!node->isElementNode() || shouldSelfClose(node) || (!node->hasChildNodes() && doesHTMLForbidEndTag(node)))        return;    result.append('<');    result.append('/');    append(result, static_cast<const Element*>(node)->nodeNamePreservingCase());    result.append('>');}static String getEndMarkup(const Node *node){    Vector<UChar> result;    appendEndMarkup(result, node);    return String::adopt(result);}static void appendMarkup(Vector<UChar>& result, Node* startNode, bool onlyIncludeChildren, Vector<Node*>* nodes, const HashMap<AtomicStringImpl*, AtomicStringImpl*>* namespaces = 0){    HashMap<AtomicStringImpl*, AtomicStringImpl*> namespaceHash;    if (namespaces)        namespaceHash = *namespaces;        if (!onlyIncludeChildren) {        if (nodes)            nodes->append(startNode);                appendStartMarkup(result,startNode, 0, DoNotAnnotateForInterchange, false, &namespaceHash);    }    // print children    if (!(startNode->document()->isHTMLDocument() && doesHTMLForbidEndTag(startNode)))        for (Node* current = startNode->firstChild(); current; current = current->nextSibling())            appendMarkup(result, current, false, nodes, &namespaceHash);        // Print my ending tag    if (!onlyIncludeChildren)        appendEndMarkup(result, startNode);}static void completeURLs(Node* node, const String& baseURL){    Vector<AttributeChange> changes;    KURL parsedBaseURL(baseURL);    Node* end = node->traverseNextSibling();    for (Node* n = node; n != end; n = n->traverseNextNode()) {        if (n->isElementNode()) {

⌨️ 快捷键说明

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