virtual DOMNode_implT* cloneNode(bool /*deep*/) const { AttrImpl* a = dynamic_cast<AttrImpl*>(NodeT::ownerDoc_->createAttribute(*name_)); cloneChildren(a); a->setSpecified(getSpecified()); return a; } // cloneNode
DOMString ElementImpl::openTagStartToString() const { DOMString result = DOMString("<") + tagName(); NamedAttrMapImpl *attrMap = attributes(true); if (attrMap) { unsigned long numAttrs = attrMap->length(); for (unsigned long i = 0; i < numAttrs; i++) { result += " "; AttributeImpl *attribute = attrMap->attributeItem(i); AttrImpl *attr = attribute->attrImpl(); if (attr) { result += attr->toString(); } else { result += getDocument()->attrName(attribute->id()); if (!attribute->value().isNull()) { result += "=\""; // FIXME: substitute entities for any instances of " or ' result += attribute->value(); result += "\""; } } } } return result; }
AttrImpl *NodeIDMap::find(const DOMString &id) { // // Get the hashcode for the supplied string. // unsigned int initalHash = XMLString::hashN(id.rawBuffer(), id.length(), fSize-1, fMemoryManager); initalHash++; unsigned int currentHash = initalHash; // // Loop looking for a slot pointing to an attr with this id. // while (true) { AttrImpl *tableSlot = fTable[currentHash]; if (tableSlot == 0) { // There is no matching entry in the table return 0; } if ((tableSlot != (AttrImpl *)-1) && tableSlot->getValue().equals(id)) return tableSlot; currentHash += initalHash; // rehash if (currentHash >= fSize) currentHash = currentHash % fSize; } return 0; // Never gets here, but keeps some compilers happy. };
Node NamedAttrMapImpl::setNamedItem ( NodeImpl* arg, int &exceptioncode ) { if (!element) { exceptioncode = DOMException::NOT_FOUND_ERR; return 0; } // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. if (isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return 0; } // WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map. if (arg->getDocument() != element->getDocument()) { exceptioncode = DOMException::WRONG_DOCUMENT_ERR; return 0; } // Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node if (!arg->isAttributeNode()) { exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; return 0; } AttrImpl *attr = static_cast<AttrImpl*>(arg); AttributeImpl* a = attr->attrImpl(); AttributeImpl* old = getAttributeItem(a->id()); if (old == a) return arg; // we know about it already // INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object. // The DOM user must explicitly clone Attr nodes to re-use them in other elements. if (attr->ownerElement()) { exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR; return 0; } if (a->id() == ATTR_ID) { element->updateId(old ? old->value() : nullAtom, a->value()); } // ### slightly inefficient - resizes attribute array twice. Node r; if (old) { if (!old->attrImpl()) old->allocateImpl(element); r = old->_impl; removeAttribute(a->id()); } addAttribute(a); return r; }
DOMString ElementImpl::openTagStartToString(bool expandurls) const { DOMString result = DOMString("<") + tagName(); NamedAttrMapImpl *attrMap = attributes(true); if(attrMap) { unsigned long numAttrs = attrMap->length(); for(unsigned long i = 0; i < numAttrs; i++) { result += " "; AttributeImpl *attribute = attrMap->attrAt(i); AttrImpl *attr = attribute->attr(); if(attr) { result += attr->toString(); } else { result += getDocument()->getName(NodeImpl::AttributeId, attribute->id()); if(!attribute->value().isNull()) { result += "=\""; // FIXME: substitute entities for any instances of " or ' // Expand out all urls, i.e. the src and href attributes if(expandurls && (attribute->id() == ATTR_SRC || attribute->id() == ATTR_HREF)) if(getDocument()) { // We need to sanitize the urls - strip out the passwords. // FIXME: are src= and href= the only places that might have a password and need to be sanitized? KURL safeURL(getDocument()->completeURL(attribute->value().string())); safeURL.setPass(QString::null); result += safeURL.htmlURL(); } else { kdWarning() << "getDocument() returned false"; result += attribute->value(); } else result += attribute->value(); result += "\""; } } } } return result; }
AttrImpl::AttrImpl(const AttrImpl &other, bool deep) : NodeImpl(other) { name = other.name.clone(); isSpecified(other.isSpecified()); /* We must initialize the void* value to null in *all* cases. Failing to do * so would cause, in case of assignment to a DOMString later, its content * to be derefenced as a DOMString, which would lead the ref count code to * be called on something that is not actually a DOMString... Really bad * things would then happen!!! */ value.child = null; hasStringValue(other.hasStringValue()); if (other.isIdAttr()) { isIdAttr(true); this->getOwnerDocument()->getNodeIDMap()->add(this); } // take care of case where there are kids if (!hasStringValue()) { cloneChildren(other); } else { if(other.value.str == null) { if(value.str != null) { *(value.str) = null; delete value.str; value.str = null; } } else { // get the address of the value field of this as a DOMString* DOMString *x = (value.str == null ?(value.str = new (getOwnerDocument()->getMemoryManager()) DOMString()) :value.str ); // and the address of the value field of other as a DOMString* DOMString *y = other.value.str; // We can now safely do the cloning and assignement, both operands // being a DOMString their ref counts will be updated appropriately *x = y->clone(); } } };
QString NodeImpl::recursive_toHTML( ) const { QString me; // Copy who I am into the htmlText string if ( nodeType() == Node::TEXT_NODE ) me = nodeValue().string(); else { // If I am an element, not a text me = QChar('<') + nodeName().string(); // print attributes if( nodeType() == Node::ELEMENT_NODE ) { ElementImpl *el = const_cast<ElementImpl*>(static_cast<const ElementImpl *>(this)); AttrImpl *attr; int exceptioncode; NamedNodeMapImpl *attrs = el->attributes(); unsigned long lmap = attrs->length(exceptioncode); for( unsigned int j=0; j<lmap; j++ ) { attr = static_cast<AttrImpl*>(attrs->item(j,exceptioncode)); me += " " + attr->name().string() + "=\"" + attr->value().string() + "\""; } } // print ending bracket of start tag if( firstChild() == 0 ) // if element has no endtag me += " />"; else // if element has endtag me += ">"; } NodeImpl* n; if( (n = firstChild()) ) { // print firstChild me += n->recursive_toHTML( ); // Print my ending tag if ( nodeType() != Node::TEXT_NODE ) me += "</" + nodeName().string() + ">"; } // print next sibling if( (n = nextSibling()) ) me += n->recursive_toHTML( ); return me; }
AttrImpl *AttributeImpl::createAttr(ElementImpl *element, DocumentImpl *docPtr) { if(m_attrId) { AttrImpl *attr = new AttrImpl(element, docPtr, m_attrId, m_data.value); if(!attr) return 0; attr->setHTMLCompat(docPtr->htmlMode() != DocumentImpl::XHtml); m_data.value->deref(); m_data.attr = attr; m_data.attr->ref(); m_attrId = 0; /* "has implementation" flag */ } return m_data.attr; }
NodeImpl *AttrMapImpl::removeNamedItemNS(const DOMString &namespaceURI, const DOMString &localName) { NodeImpl* removed = NamedNodeMapImpl::removeNamedItemNS(namespaceURI, localName); // Replace it if it had a default value // (DOM spec level 2 - Element Interface) if (hasDefaults() && (removed != null)) { AttrMapImpl* defAttrs = ((ElementImpl*)ownerNode)->getDefaultAttributes(); AttrImpl* attr = (AttrImpl*)(defAttrs->getNamedItemNS(namespaceURI, localName)); if (attr != null) { AttrImpl* newAttr = (AttrImpl*)attr->cloneNode(true); setNamedItem(newAttr); } } return removed; }
void NodeImpl::printTree(int indent) { QString ind; QString s; ind.fill(' ', indent); // ### find out why this isn't working if(isElementNode()) { s = ind + "<" + nodeName().string(); ElementImpl *el = const_cast<ElementImpl*>(static_cast<const ElementImpl *>(this)); AttrImpl *attr; int exceptioncode; NamedNodeMapImpl *attrs = el->attributes(); unsigned long lmap = attrs->length(exceptioncode); for( unsigned int j=0; j<lmap; j++ ) { attr = static_cast<AttrImpl*>(attrs->item(j,exceptioncode)); s += " " + attr->name().string() + "=\"" + attr->value().string() + "\""; } if(!firstChild()) s += " />"; else s += ">"; } else s = ind + "'" + nodeValue().string() + "'"; kdDebug() << s << endl; NodeImpl *child = firstChild(); while( child ) { child->printTree(indent+2); child = child->nextSibling(); } if(isElementNode() && firstChild()) kdDebug() << ind << "</" << nodeName().string() << ">" << endl; }
NodeImpl *AttrImpl::cloneNode(bool /*deep*/) { AttrImpl *attr = new AttrImpl(0, docPtr(), m_attrId, m_value, m_prefix); attr->setHTMLCompat(m_htmlCompat); return attr; }
Node NamedAttrMapImpl::setNamedItem(NodeImpl *arg, bool nsAware, DOMStringImpl *qName, int &exceptioncode) { if(!m_element) { exceptioncode = DOMException::NOT_FOUND_ERR; return 0; } // NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. if(isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return 0; } // WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map. if(arg->getDocument() != m_element->getDocument()) { exceptioncode = DOMException::WRONG_DOCUMENT_ERR; return 0; } // HIERARCHY_REQUEST_ERR: Raised if an attempt is made to add a node doesn't belong in this NamedNodeMap if(!arg->isAttributeNode()) { exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; return 0; } AttrImpl *attr = static_cast< AttrImpl * >(arg); // INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object. // The DOM user must explicitly clone Attr nodes to re-use them in other elements. if(attr->ownerElement() && attr->ownerElement() != m_element) { exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR; return 0; } if(attr->ownerElement() == m_element) { // Already have this attribute. // DOMTS core-1 test "hc_elementreplaceattributewithself" says we should return it. return attr; } unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; NodeImpl::Id id = (attr->id() & mask); for(unsigned long i = 0; i < m_attrCount; i++) { if((m_attrs[i].id() & mask) == id) { // if we are called with a qualified name, filter out NS-aware elements with non-matching name. if(qName && (namespacePart(m_attrs[i].id()) != defaultNamespace) && strcasecmp(m_attrs[i].name(), DOMString(qName))) continue; // Attribute exists; replace it if(id == ATTR_ID) m_element->updateId(m_attrs[i].val(), attr->val()); Node replaced = m_attrs[i].createAttr(m_element, m_element->docPtr()); m_attrs[i].free(); m_attrs[i].m_attrId = 0; /* "has implementation" flag */ m_attrs[i].m_data.attr = attr; m_attrs[i].m_data.attr->ref(); attr->setElement(m_element); m_element->parseAttribute(&m_attrs[i]); m_element->attributeChanged(m_attrs[i].id()); // ### dispatch mutation events return replaced; } } // No existing attribute; add to list m_attrCount++; m_attrs = (AttributeImpl *)realloc(m_attrs, m_attrCount * sizeof(AttributeImpl)); m_attrs[m_attrCount - 1].m_attrId = 0; /* "has implementation" flag */ m_attrs[m_attrCount - 1].m_data.attr = attr; m_attrs[m_attrCount - 1].m_data.attr->ref(); attr->setElement(m_element); if(id == ATTR_ID) m_element->updateId(0, attr->val()); m_element->parseAttribute(&m_attrs[m_attrCount - 1]); m_element->attributeChanged(m_attrs[m_attrCount - 1].id()); // ### dispatch mutation events return 0; }