📄 dom_elementimpl.cpp
字号:
// FIXME: the approach is flawed, better use an enum instead of bool int value; if (enabled) value = CSS_VAL_ENABLED; else { // Intelligently use "none" or "disabled", depending on the type of // element // FIXME: intelligence not impl'd yet value = CSS_VAL_NONE; // FIXME: reset caret if it is in this node or a child }/*end if*/ // FIXME: use addCSSProperty when I get permission to move it here// kdDebug(6000) << "CSS_PROP__KHTML_USER_INPUT: "<< value << endl; styleRules()->setProperty(CSS_PROP__KHTML_USER_INPUT, value, false, true); setChanged();}// -------------------------------------------------------------------------XMLElementImpl::XMLElementImpl(DocumentPtr *doc, NodeImpl::Id id) : ElementImpl(doc){ // Called from createElement(). In this case localName, prefix, and namespaceURI all need to be null. m_id = id;}XMLElementImpl::XMLElementImpl(DocumentPtr *doc, NodeImpl::Id id, DOMStringImpl *_prefix) : ElementImpl(doc){ // Called from createElementNS() m_id = id; m_prefix = _prefix; if (m_prefix) m_prefix->ref();}XMLElementImpl::~XMLElementImpl(){}DOMString XMLElementImpl::localName() const{ if ( m_htmlCompat ) return DOMString(); // was created with non-namespace-aware createElement() return getDocument()->getName(ElementId, m_id);}DOMString XMLElementImpl::tagName() const{ DOMString tn = getDocument()->getName(ElementId, id()); if (m_htmlCompat) tn = tn.upper(); if (m_prefix) return DOMString(m_prefix) + ":" + tn; return tn;}NodeImpl *XMLElementImpl::cloneNode ( bool deep ){ XMLElementImpl *clone = new XMLElementImpl(docPtr(), id(), m_prefix); finishCloneNode( clone, deep ); return clone;}// -------------------------------------------------------------------------NamedAttrMapImpl::NamedAttrMapImpl(ElementImpl *element) : m_element(element), m_attrs(0), m_attrCount(0){}NamedAttrMapImpl::~NamedAttrMapImpl(){ for (unsigned long i = 0; i < m_attrCount; i++) m_attrs[i].free(); free(m_attrs);}NodeImpl *NamedAttrMapImpl::getNamedItem ( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName ) const{ if (!m_element) return 0; unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; id = (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 && (m_attrs[i].id() & NodeImpl_IdNSMask) && strcasecmp(m_attrs[i].name(), DOMString(qName))) continue; return m_attrs[i].createAttr(m_element,m_element->docPtr()); } } return 0;}Node NamedAttrMapImpl::removeNamedItem ( NodeImpl::Id id, bool nsAware, DOMStringImpl* qName, int &exceptioncode ){ if (!m_element) { exceptioncode = DOMException::NOT_FOUND_ERR; return 0; } // NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly if (isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return 0; } unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; id = (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 && (m_attrs[i].id() & NodeImpl_IdNSMask) && strcasecmp(m_attrs[i].name(), DOMString(qName))) continue; id = m_attrs[i].id(); if (id == ATTR_ID) m_element->updateId(m_attrs[i].val(), 0); Node removed(m_attrs[i].createAttr(m_element,m_element->docPtr())); m_attrs[i].free(); memmove(m_attrs+i,m_attrs+i+1,(m_attrCount-i-1)*sizeof(AttributeImpl)); m_attrCount--; m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); m_element->parseAttribute(id,0); return removed; } } // NOT_FOUND_ERR: Raised if there is no node with the specified namespaceURI // and localName in this map. exceptioncode = DOMException::NOT_FOUND_ERR; return 0;}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 && (m_attrs[i].id() & NodeImpl_IdNSMask) && 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]); // ### 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]); // ### dispatch mutation events return 0;}NodeImpl *NamedAttrMapImpl::item ( unsigned long index ) const{ if (!m_element) return 0; if (index >= m_attrCount) return 0; else return m_attrs[index].createAttr(m_element,m_element->docPtr());}unsigned long NamedAttrMapImpl::length( ) const{ if (!m_element) return 0; return m_attrCount;}NodeImpl::Id NamedAttrMapImpl::idAt(unsigned long index) const{ assert(index <= m_attrCount); return m_attrs[index].id();}DOMStringImpl *NamedAttrMapImpl::valueAt(unsigned long index) const{ assert(index <= m_attrCount); return m_attrs[index].val();}DOMStringImpl *NamedAttrMapImpl::getValue(NodeImpl::Id id, bool nsAware, DOMStringImpl* qName) const{ unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; id = (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 && (m_attrs[i].id() & NodeImpl_IdNSMask) && strcasecmp(m_attrs[i].name(), DOMString(qName))) continue; return m_attrs[i].val(); } return 0;}void NamedAttrMapImpl::setValue(NodeImpl::Id id, DOMStringImpl *value, DOMStringImpl* qName, DOMStringImpl *prefix, bool nsAware, bool hasNS){ assert( !(qName && nsAware) ); if (!id) return; // Passing in a null value here causes the attribute to be removed. This is a khtml extension // (the spec does not specify what to do in this situation). int exceptioncode = 0; if (!value) { removeNamedItem(id, nsAware, qName, exceptioncode); return; } unsigned int mask = nsAware ? ~0L : NodeImpl_IdLocalMask; NodeImpl::Id mid = (id & mask); // Check for an existing attribute. for (unsigned long i = 0; i < m_attrCount; i++) { if ((m_attrs[i].id() & mask) == mid) { // if we are called with a qualified name, filter out NS-aware elements with non-matching name. if (qName && (m_attrs[i].id() & NodeImpl_IdNSMask) && strcasecmp(m_attrs[i].name(), DOMString(qName))) continue; if (prefix) m_attrs[i].attr()->setPrefix(prefix,exceptioncode); m_attrs[i].setValue(value,m_element); // ### dispatch mutation events return; } } // No existing matching attribute; add a new one m_attrCount++; m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); if (!nsAware) { // Called from setAttribute()... we only have a name m_attrs[m_attrCount-1].m_attrId = id; m_attrs[m_attrCount-1].m_data.value = value; m_attrs[m_attrCount-1].m_data.value->ref(); } else { // Called from setAttributeNS()... need to create a full AttrImpl here if(!m_element) return; m_attrs[m_attrCount-1].m_data.attr = new AttrImpl(m_element,m_element->docPtr(), id, value, prefix); m_attrs[m_attrCount-1].m_attrId = 0; /* "has implementation" flag */ m_attrs[m_attrCount-1].m_data.attr->ref(); m_attrs[m_attrCount-1].m_data.attr->setHTMLCompat( !hasNS && m_element->getDocument()->htmlMode() != DocumentImpl::XHtml ); } if (m_element) { if (id == ATTR_ID) m_element->updateId(0, value); m_element->parseAttribute(&m_attrs[m_attrCount-1]); } // ### dispatch mutation events}Attr NamedAttrMapImpl::removeAttr(AttrImpl *attr){ for (unsigned long i = 0; i < m_attrCount; i++) { if (m_attrs[i].attr() == attr) { NodeImpl::Id id = m_attrs[i].id(); if (id == ATTR_ID) m_element->updateId(attr->val(), 0); Node removed(m_attrs[i].createAttr(m_element,m_element->docPtr())); m_attrs[i].free(); memmove(m_attrs+i,m_attrs+i+1,(m_attrCount-i-1)*sizeof(AttributeImpl)); m_attrCount--; m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); m_element->parseAttribute(id,0); // ### dispatch mutation events return removed; } } return 0;}NodeImpl::Id NamedAttrMapImpl::mapId(DOMStringImpl* namespaceURI, DOMStringImpl* localName, bool readonly){ if (!m_element) return 0; return m_element->getDocument()->getId(NodeImpl::AttributeId, namespaceURI, 0, localName, readonly, true /*lookupHTML*/);}void NamedAttrMapImpl::copyAttributes(NamedAttrMapImpl *other){ assert(m_element); unsigned long i; for (i = 0; i < m_attrCount; i++) { if (m_attrs[i].id() == ATTR_ID) m_element->updateId(m_attrs[i].val(), 0); m_attrs[i].free(); } m_attrCount = other->m_attrCount; m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); for (i = 0; i < m_attrCount; i++) { m_attrs[i].m_attrId = other->m_attrs[i].m_attrId; if (m_attrs[i].m_attrId) { m_attrs[i].m_data.value = other->m_attrs[i].m_data.value; m_attrs[i].m_data.value->ref(); } else { m_attrs[i].m_data.attr = static_cast<AttrImpl*>(other->m_attrs[i].m_data.attr->cloneNode(true)); m_attrs[i].m_data.attr->ref(); m_attrs[i].m_data.attr->setElement(m_element); } if (m_attrs[i].id() == ATTR_ID) m_element->updateId(0, m_attrs[i].val()); m_element->parseAttribute(&m_attrs[i]); }}void NamedAttrMapImpl::setElement(ElementImpl *element){ assert(!m_element); m_element = element; for (unsigned long i = 0; i < m_attrCount; i++) if (m_attrs[i].attr()) m_attrs[i].attr()->setElement(element);}void NamedAttrMapImpl::detachFromElement(){ // This makes the map invalid; nothing can really be done with it now since it's not // associated with an element. But we have to keep it around in memory in case there // are still references to it. m_element = 0; for (unsigned long i = 0; i < m_attrCount; i++) m_attrs[i].free(); free(m_attrs); m_attrs = 0; m_attrCount = 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -