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; }
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; }