📄 document.cpp
字号:
ASSERT(!m_inPageCache); ASSERT(!m_savedRenderer); ASSERT(m_ranges.isEmpty()); removeAllEventListeners(); forgetAllDOMNodesForDocument(this); if (m_docChanged && changedDocuments) changedDocuments->remove(this); delete m_tokenizer; m_document.resetSkippingRef(0); delete m_styleSelector; delete m_docLoader; if (m_renderArena) { delete m_renderArena; m_renderArena = 0; }#if ENABLE(XSLT) xmlFreeDoc((xmlDocPtr)m_transformSource);#endif#if ENABLE(XBL) delete m_bindingManager;#endif deleteAllValues(m_markers); clearAXObjectCache(); m_decoder = 0; unsigned count = sizeof(m_nameCollectionInfo) / sizeof(m_nameCollectionInfo[0]); for (unsigned i = 0; i < count; i++) deleteAllValues(m_nameCollectionInfo[i]);#if ENABLE(DATABASE) if (m_databaseThread) { ASSERT(m_databaseThread->terminationRequested()); m_databaseThread = 0; }#endif if (m_styleSheets) m_styleSheets->documentDestroyed(); m_document = 0;}void Document::resetLinkColor(){ m_linkColor = Color(0, 0, 238);}void Document::resetVisitedLinkColor(){ m_visitedLinkColor = Color(85, 26, 139); }void Document::resetActiveLinkColor(){ m_activeLinkColor.setNamedColor("red");}void Document::setDocType(PassRefPtr<DocumentType> docType){ // This should never be called more than once. // Note: This is not a public DOM method and can only be called by the parser. ASSERT(!m_docType || !docType); if (m_docType && docType) return; m_docType = docType; if (m_docType) m_docType->setDocument(this); determineParseMode();}DOMImplementation* Document::implementation() const{ if (!m_implementation) m_implementation = DOMImplementation::create(); return m_implementation.get();}void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta){ ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); // Invalidate the document element we have cached in case it was replaced. m_documentElement = 0;}void Document::cacheDocumentElement() const{ ASSERT(!m_documentElement); Node* n = firstChild(); while (n && !n->isElementNode()) n = n->nextSibling(); m_documentElement = static_cast<Element*>(n);}PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionCode& ec){ if (!isValidName(name)) { ec = INVALID_CHARACTER_ERR; return 0; } if (m_isXHTML) return HTMLElementFactory::createHTMLElement(QualifiedName(nullAtom, name, xhtmlNamespaceURI), this, 0, false); return createElement(QualifiedName(nullAtom, name, nullAtom), false);}PassRefPtr<DocumentFragment> Document::createDocumentFragment(){ return new DocumentFragment(document());}PassRefPtr<Text> Document::createTextNode(const String& data){ return new Text(this, data);}PassRefPtr<Comment> Document::createComment(const String& data){ return new Comment(this, data);}PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionCode& ec){ if (isHTMLDocument()) { ec = NOT_SUPPORTED_ERR; return 0; } return new CDATASection(this, data);}PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionCode& ec){ if (!isValidName(target)) { ec = INVALID_CHARACTER_ERR; return 0; } if (isHTMLDocument()) { ec = NOT_SUPPORTED_ERR; return 0; } return new ProcessingInstruction(this, target, data);}PassRefPtr<EntityReference> Document::createEntityReference(const String& name, ExceptionCode& ec){ if (!isValidName(name)) { ec = INVALID_CHARACTER_ERR; return 0; } if (isHTMLDocument()) { ec = NOT_SUPPORTED_ERR; return 0; } return new EntityReference(this, name);}PassRefPtr<EditingText> Document::createEditingTextNode(const String& text){ return new EditingText(this, text);}PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration(){ return CSSMutableStyleDeclaration::create();}PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionCode& ec){ ec = 0; if (!importedNode#if ENABLE(SVG) && ENABLE(DASHBOARD_SUPPORT) || (importedNode->isSVGElement() && page() && page()->settings()->usesDashboardBackwardCompatibilityMode())#endif ) { ec = NOT_SUPPORTED_ERR; return 0; } switch (importedNode->nodeType()) { case TEXT_NODE: return createTextNode(importedNode->nodeValue()); case CDATA_SECTION_NODE: return createCDATASection(importedNode->nodeValue(), ec); case ENTITY_REFERENCE_NODE: return createEntityReference(importedNode->nodeName(), ec); case PROCESSING_INSTRUCTION_NODE: return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), ec); case COMMENT_NODE: return createComment(importedNode->nodeValue()); case ELEMENT_NODE: { Element* oldElement = static_cast<Element*>(importedNode); RefPtr<Element> newElement = createElementNS(oldElement->namespaceURI(), oldElement->tagQName().toString(), ec); if (ec) return 0; NamedAttrMap* attrs = oldElement->attributes(true); if (attrs) { unsigned length = attrs->length(); for (unsigned i = 0; i < length; i++) { Attribute* attr = attrs->attributeItem(i); newElement->setAttribute(attr->name(), attr->value().impl(), ec); if (ec) return 0; } } newElement->copyNonAttributeProperties(oldElement); if (deep) { for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) { RefPtr<Node> newChild = importNode(oldChild, true, ec); if (ec) return 0; newElement->appendChild(newChild.release(), ec); if (ec) return 0; } } return newElement.release(); } case ATTRIBUTE_NODE: { RefPtr<Attr> newAttr = new Attr(0, this, static_cast<Attr*>(importedNode)->attr()->clone()); newAttr->createTextChild(); return newAttr.release(); } case DOCUMENT_FRAGMENT_NODE: { DocumentFragment* oldFragment = static_cast<DocumentFragment*>(importedNode); RefPtr<DocumentFragment> newFragment = createDocumentFragment(); if (deep) { for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) { RefPtr<Node> newChild = importNode(oldChild, true, ec); if (ec) return 0; newFragment->appendChild(newChild.release(), ec); if (ec) return 0; } } return newFragment.release(); } case ENTITY_NODE: case NOTATION_NODE: // FIXME: It should be possible to import these node types, however in DOM3 the DocumentType is readonly, so there isn't much sense in doing that. // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM. case DOCUMENT_NODE: case DOCUMENT_TYPE_NODE: case XPATH_NAMESPACE_NODE: break; } ec = NOT_SUPPORTED_ERR; return 0;}PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionCode& ec){ if (!source) { ec = NOT_SUPPORTED_ERR; return 0; } if (source->isReadOnlyNode()) { ec = NO_MODIFICATION_ALLOWED_ERR; return 0; } switch (source->nodeType()) { case ENTITY_NODE: case NOTATION_NODE: case DOCUMENT_NODE: case DOCUMENT_TYPE_NODE: case XPATH_NAMESPACE_NODE: ec = NOT_SUPPORTED_ERR; return 0; case ATTRIBUTE_NODE: { Attr* attr = static_cast<Attr*>(source.get()); if (attr->ownerElement()) attr->ownerElement()->removeAttributeNode(attr, ec); attr->setSpecified(true); break; } default: if (source->parentNode()) source->parentNode()->removeChild(source.get(), ec); } for (Node* node = source.get(); node; node = node->traverseNextNode(source.get())) node->setDocument(this); return source;}bool Document::hasPrefixNamespaceMismatch(const QualifiedName& qName){ DEFINE_STATIC_LOCAL(const AtomicString, xmlnsNamespaceURI, ("http://www.w3.org/2000/xmlns/")); DEFINE_STATIC_LOCAL(const AtomicString, xmlns, ("xmlns")); DEFINE_STATIC_LOCAL(const AtomicString, xml, ("xml")); // These checks are from DOM Core Level 2, createElementNS // http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-DocCrElNS if (!qName.prefix().isEmpty() && qName.namespaceURI().isNull()) // createElementNS(null, "html:div") return true; if (qName.prefix() == xml && qName.namespaceURI() != XMLNames::xmlNamespaceURI) // createElementNS("http://www.example.com", "xml:lang") return true; // Required by DOM Level 3 Core and unspecified by DOM Level 2 Core: // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar") if ((qName.prefix() == xmlns && qName.namespaceURI() != xmlnsNamespaceURI) || (qName.prefix() != xmlns && qName.namespaceURI() == xmlnsNamespaceURI)) return true; return false;}// FIXME: This should really be in a possible ElementFactory classPassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser){ RefPtr<Element> e; // FIXME: Use registered namespaces and look up in a hash to find the right factory. if (qName.namespaceURI() == xhtmlNamespaceURI) e = HTMLElementFactory::createHTMLElement(qName, this, 0, createdByParser);#if ENABLE(SVG) else if (qName.namespaceURI() == SVGNames::svgNamespaceURI) e = SVGElementFactory::createSVGElement(qName, this, createdByParser);#endif#if ENABLE(WML) else if (qName.namespaceURI() == WMLNames::wmlNamespaceURI || isWMLDocument()) e = WMLElementFactory::createWMLElement(qName, this, createdByParser);#endif if (!e) e = new Element(qName, document()); // <image> uses imgTag so we need a special rule. ASSERT((qName.matches(imageTag) && e->tagQName().matches(imgTag) && e->tagQName().prefix() == qName.prefix()) || qName == e->tagQName()); return e.release();}PassRefPtr<Element> Document::createElementNS(const String& namespaceURI, const String& qualifiedName, ExceptionCode& ec){ String prefix, localName; if (!parseQualifiedName(qualifiedName, prefix, localName, ec)) return 0; QualifiedName qName(prefix, localName, namespaceURI); if (hasPrefixNamespaceMismatch(qName)) { ec = NAMESPACE_ERR; return 0; } return createElement(qName, false);}Element* Document::getElementById(const AtomicString& elementId) const{ if (elementId.isEmpty()) return 0; Element* element = m_elementsById.get(elementId.impl()); if (element) return element; if (m_duplicateIds.contains(elementId.impl())) { // We know there's at least one node with this id, but we don't know what the first one is. for (Node *n = traverseNextNode(); n != 0; n = n->traverseNextNode()) { if (n->isElementNode()) { element = static_cast<Element*>(n); if (element->hasID() && element->getAttribute(idAttr) == elementId) { m_duplicateIds.remove(elementId.impl()); m_elementsById.set(elementId.impl(), element); return element; } } } ASSERT_NOT_REACHED(); } return 0;}String Document::readyState() const{ if (Frame* f = frame()) { if (f->loader()->isComplete()) return "complete"; if (parsing()) return "loading"; return "loaded"; // FIXME: What does "interactive" mean? // FIXME: Missing support for "uninitialized". } return String();}String Document::encoding() const{ if (TextResourceDecoder* d = decoder()) return d->encoding().name(); return String();}String Document::defaultCharset() const{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -