Version: 3.5.4-2.1.fc4.kde (using KDE 3.5.4-1.1.fc4.kde, Fedora Core release 4 (Stentz)) Compiler: Target: i386-redhat-linux OS: Linux (i686) release 2.6.17-1.2142_FC4smp If you have a CSS styling of a tag that depends on the presence of an attribute that style sticks even if the attribute is removed: div.test_presence { <default-properties>; } div.test_presence[attribute] { <modified-properties> } Initially a DIV will be displayed with the default properties. Adding 'attribute' using setAttribute will display the DIV with the modified properties, but removing it again will not make the DIV change back to the default again. Adding a value to the attribute and modifying that value instead of adding/removing the attribute works however.
Created attachment 17638 [details] Test case
Created attachment 17639 [details] Test case source
SVN commit 581101 by carewolf: Call attributeChanged to changes in attr-nodes or the attrNodeMap instead of in setAttribute. This catches many more types of attribute changes. BUG:133570 M +15 -6 dom_elementimpl.cpp --- branches/KDE/3.5/kdelibs/khtml/xml/dom_elementimpl.cpp #581100:581101 @@ -175,8 +175,10 @@ m_value = v.implementation(); m_value->ref(); - if (m_element) + if (m_element) { m_element->parseAttribute(m_attrId,m_value); + m_element->attributeChanged(m_attrId); + } } void AttrImpl::setNodeValue( const DOMString &v, int &exceptioncode ) @@ -263,8 +265,10 @@ m_data.value = value; m_data.value->ref(); - if (element) + if (element) { element->parseAttribute(this); + element->attributeChanged(m_attrId); + } } else { int exceptioncode = 0; @@ -362,7 +366,6 @@ return; } attributes()->setValue(id, value.implementation(), (qName.isEmpty() ? 0: qName.implementation())); - attributeChanged(id); } void ElementImpl::setAttributeNS( const DOMString &namespaceURI, const DOMString &qualifiedName, @@ -384,14 +387,12 @@ prefix.implementation(), localName.implementation(), false, true /*lookupHTML*/); attributes()->setValue(id, value.implementation(), 0, prefix.implementation(), true /*nsAware*/, !namespaceURI.isNull() /*hasNS*/); - attributeChanged(id); } void ElementImpl::setAttribute(NodeImpl::Id id, const DOMString &value) { int exceptioncode = 0; setAttribute(id,value,DOMString(),exceptioncode); - attributeChanged(id); } void ElementImpl::setAttributeMap( NamedAttrMapImpl* list ) @@ -417,8 +418,10 @@ assert(namedAttrMap->m_element == 0); namedAttrMap->setElement(this); unsigned long len = namedAttrMap->length(); - for (unsigned long i = 0; i < len; i++) + for (unsigned long i = 0; i < len; i++) { parseAttribute(&namedAttrMap->m_attrs[i]); + attributeChanged(namedAttrMap->m_attrs[i].id()); + } } } @@ -994,6 +997,7 @@ m_attrCount--; m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); m_element->parseAttribute(id,0); + m_element->attributeChanged(id); return removed; } } @@ -1062,6 +1066,7 @@ 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; } @@ -1077,6 +1082,7 @@ 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; @@ -1184,6 +1190,7 @@ if (id == ATTR_ID) m_element->updateId(0, value); m_element->parseAttribute(&m_attrs[m_attrCount-1]); + m_element->attributeChanged(m_attrs[m_attrCount-1].id()); } // ### dispatch mutation events } @@ -1201,6 +1208,7 @@ m_attrCount--; m_attrs = (AttributeImpl*)realloc(m_attrs,m_attrCount*sizeof(AttributeImpl)); m_element->parseAttribute(id,0); + m_element->attributeChanged(id); // ### dispatch mutation events return removed; } @@ -1244,6 +1252,7 @@ if (m_attrs[i].id() == ATTR_ID) m_element->updateId(0, m_attrs[i].val()); m_element->parseAttribute(&m_attrs[i]); + m_element->attributeChanged(m_attrs[i].id()); } }