📄 dom_elementimpl.cpp
字号:
if (oldDisplay != m_style->display()) { detach(); attach(); } if( m_render && m_style ) m_render->setStyle(m_style); NodeImpl *n; for (n = _first; n; n = n->nextSibling()) n->recalcStyle();}void ElementImpl::setFocus(bool received){ NodeBaseImpl::setFocus(received); applyChanges(true, false);}void ElementImpl::setActive(bool down){ NodeBaseImpl::setActive(down); applyChanges(true, false);}khtml::FindSelectionResult ElementImpl::findSelectionNode( int _x, int _y, int _tx, int _ty, DOM::Node & node, int & offset ){ //kdDebug(6030) << "ElementImpl::findSelectionNode " << this << " _x=" << _x << " _y=" << _y // << " _tx=" << _tx << " _ty=" << _ty << endl; // ######### Duplicated code from mouseEvent // TODO put the code above (getting _tx,_ty) in a common place and call it from here if (!m_render) return SelectionPointAfter; RenderObject *p = m_render->parent(); while( p && p->isAnonymousBox() ) {// kdDebug( 6030 ) << "parent is anonymous!" << endl; // we need to add the offset of the anonymous box _tx += p->xPos(); _ty += p->yPos(); p = p->parent(); } if(!m_render->isInline() || !m_render->firstChild() || m_render->isFloating() ) { m_render->absolutePosition(_tx, _ty); } int off=0, lastOffset=0; DOM::Node nod; DOM::Node lastNode; NodeImpl *child = firstChild(); while(child != 0) { khtml::FindSelectionResult pos = child->findSelectionNode(_x, _y, _tx, _ty, nod, off); //kdDebug(6030) << this << " child->findSelectionNode returned " << pos << endl; if ( pos == SelectionPointInside ) // perfect match { node = nod; offset = off; //kdDebug(6030) << "ElementImpl::findSelectionNode " << this << " match offset=" << offset << endl; return SelectionPointInside; } else if ( pos == SelectionPointBefore ) { //x,y is before this element -> stop here if ( !lastNode.isNull() ) { node = lastNode; offset = lastOffset; //kdDebug(6030) << "ElementImpl::findSelectionNode " << this << " before this child -> returning offset=" << offset << endl; return SelectionPointInside; } else { //kdDebug(6030) << "ElementImpl::findSelectionNode " << this << " before us -> returning -2" << endl; return SelectionPointBefore; } } // SelectionPointAfter -> keep going if ( !nod.isNull() ) { lastNode = nod; lastOffset = off; } child = child->nextSibling(); } node = lastNode; offset = lastOffset; return SelectionPointAfter;}bool ElementImpl::isSelectable() const{ return false;}// DOM Section 1.1.1bool ElementImpl::childAllowed( NodeImpl *newChild ){ if (!childTypeAllowed(newChild->nodeType())) return false; // ### check xml element allowedness according to DTD if (id() && newChild->id()) // if one if these is 0 then it is an xml element and we allow it anyway return checkChild(id(), newChild->id()); else return true;}bool ElementImpl::childTypeAllowed( unsigned short type ){ switch (type) { case Node::ELEMENT_NODE: case Node::TEXT_NODE: case Node::COMMENT_NODE: case Node::PROCESSING_INSTRUCTION_NODE: case Node::CDATA_SECTION_NODE: case Node::ENTITY_REFERENCE_NODE: return true; break; default: return false; }}void ElementImpl::createDecl( ){ m_styleDecls = new CSSStyleDeclarationImpl(0); m_styleDecls->ref(); m_styleDecls->setParent(ownerDocument()->elementSheet()); m_styleDecls->setNode(this); m_styleDecls->setStrictParsing( ownerDocument()->parseMode() == DocumentImpl::Strict );}void ElementImpl::dispatchAttrRemovalEvent(NodeImpl *attr){ if (!getDocument()->hasListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER)) return; int exceptioncode; AttrImpl *att = static_cast<AttrImpl*>(attr); dispatchEvent(new MutationEventImpl(EventImpl::DOMATTRMODIFIED_EVENT,true,false,attr,att->value(), att->value(),att->name(),MutationEvent::REMOVAL),exceptioncode);}void ElementImpl::dispatchAttrAdditionEvent(NodeImpl *attr){ if (!getDocument()->hasListenerType(DocumentImpl::DOMATTRMODIFIED_LISTENER)) return; int exceptioncode; AttrImpl *att = static_cast<AttrImpl*>(attr); dispatchEvent(new MutationEventImpl(EventImpl::DOMATTRMODIFIED_EVENT,true,false,attr,att->value(), att->value(),att->name(),MutationEvent::ADDITION),exceptioncode);}// -------------------------------------------------------------------------XMLElementImpl::XMLElementImpl(DocumentPtr *doc, DOMStringImpl *_name) : ElementImpl(doc){ m_name = _name; if (m_name) m_name->ref(); m_namespaceURI = 0; m_id = ownerDocument()->elementId(_name);}XMLElementImpl::XMLElementImpl(DocumentPtr *doc, DOMStringImpl *_name, DOMStringImpl *_namespaceURI) : ElementImpl(doc){ m_name = _name; if (m_name) m_name->ref(); m_namespaceURI = _namespaceURI; if (m_namespaceURI) m_namespaceURI->ref(); m_id = ownerDocument()->elementId(_name);}XMLElementImpl::~XMLElementImpl(){ if (m_name) m_name->deref(); if (m_namespaceURI) m_namespaceURI->deref();}const DOMString XMLElementImpl::nodeName() const{ return m_name;}DOMString XMLElementImpl::namespaceURI() const{ return m_namespaceURI;}bool XMLElementImpl::isXMLElementNode() const{ return true;}// -------------------------------------------------------------------------NamedAttrMapImpl::NamedAttrMapImpl(ElementImpl *e) : element(e){ attrs = 0; len = 0;}NamedAttrMapImpl::~NamedAttrMapImpl(){ clearAttrs();}NamedAttrMapImpl &NamedAttrMapImpl::operator =(const NamedAttrMapImpl &other){ // clone all attributes in the other map, but attach to our element if (!element) return *this; clearAttrs(); len = other.len; attrs = new AttrImpl* [len]; uint i; // first initialize attrs vector, then call parseAttribute on it // this allows parseAttribute to use getAttribute for (i = 0; i < len; i++) { int exceptioncode; // ### propogate attrs[i] = static_cast<AttrImpl*>(other.attrs[i]->cloneNode(true,exceptioncode)); attrs[i]->_element = element; attrs[i]->ref(); } for(i = 0; i < len; i++) element->parseAttribute(attrs[i]); element->setChanged(true); return *this;}unsigned long NamedAttrMapImpl::length(int &/*exceptioncode*/) const{ return length();}unsigned long NamedAttrMapImpl::length() const{ return len;}NodeImpl *NamedAttrMapImpl::getNamedItem ( const DOMString &name, int &/*exceptioncode*/ ) const{ return getNamedItem(name);}NodeImpl *NamedAttrMapImpl::getNamedItem ( const DOMString &name ) const{ uint i; for (i = 0; i < len; i++) { if (!strcasecmp(attrs[i]->name(),name)) return attrs[i]; } return 0;}AttrImpl *NamedAttrMapImpl::getIdItem ( int id ) const{ uint i; for (i = 0; i < len; i++) { if (attrs[i]->attrId == id) return attrs[i]; } return 0;}Node NamedAttrMapImpl::setNamedItem ( const Node &arg, int &exceptioncode ){ // ### check for invalid chars in name ? // ### check same document exceptioncode = 0; if (!element) { exceptioncode = DOMException::NOT_FOUND_ERR; return 0; } element->checkReadOnly(); if (arg.nodeType() != Node::ATTRIBUTE_NODE) { exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; return 0; } AttrImpl *attr = static_cast<AttrImpl*>(arg.handle()); if (attr->_element) { exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR; return 0; } uint i; for (i = 0; i < len; i++) { // ### for XML attributes are case sensitive (?) - check this elsewhere also if (!strcasecmp(attrs[i]->name(),attr->name())) { // attribute with this id already in list Attr oldAttr = attrs[i]; attrs[i]->_element = 0; attrs[i]->deref(); attrs[i] = attr; attrs[i]->ref(); attr->_element = element; element->parseAttribute(attr); element->setChanged(true); element->dispatchAttrRemovalEvent(oldAttr.handle()); element->dispatchAttrAdditionEvent(attrs[i]); element->dispatchSubtreeModifiedEvent(); return oldAttr; } } // attribute with this name not yet in list AttrImpl **newAttrs = new AttrImpl* [len+1]; if (attrs) { for (i = 0; i < len; i++) newAttrs[i] = attrs[i]; delete [] attrs; } attrs = newAttrs; attrs[len] = attr; attr->ref(); len++; attr->_element = element; element->parseAttribute(attr); element->setChanged(true); element->dispatchAttrAdditionEvent(attr); element->dispatchSubtreeModifiedEvent(); return 0;}Attr NamedAttrMapImpl::setIdItem ( AttrImpl *attr, int &exceptioncode ){ exceptioncode = 0; if (!element) { exceptioncode = DOMException::NOT_FOUND_ERR; return 0; } element->checkReadOnly(); if (attr->_element) { exceptioncode = DOMException::INUSE_ATTRIBUTE_ERR; return 0; } uint i; for (i = 0; i < len; i++) { if (attrs[i]->attrId == attr->attrId) { // attribute with this id already in list Attr oldAttr = attrs[i]; attrs[i]->_element = 0; attrs[i]->deref(); attrs[i] = attr; attrs[i]->ref(); attr->_element = element; element->parseAttribute(attr); element->setChanged(true); element->dispatchAttrRemovalEvent(oldAttr.handle()); element->dispatchAttrAdditionEvent(attrs[i]); element->dispatchSubtreeModifiedEvent(); return oldAttr; // ### check this gets deleted if ref = 0 and it's not assigned to anything } } // attribute with this id not yet in list AttrImpl **newAttrs = new AttrImpl* [len+1]; if (attrs) { for (i = 0; i < len; i++) newAttrs[i] = attrs[i]; delete [] attrs; } attrs = newAttrs; attrs[len] = attr; attr->ref(); len++; attr->_element = element; element->parseAttribute(attr); element->setChanged(true); element->dispatchAttrAdditionEvent(attr); element->dispatchSubtreeModifiedEvent(); return 0;}Node NamedAttrMapImpl::removeNamedItem ( const DOMString &name, int &exceptioncode ){ if (element) element->checkReadOnly(); if (!attrs) { exceptioncode = DOMException::NOT_FOUND_ERR; return 0; } uint i; int found = -1; for (i = 0; i < len && found < 0; i++) { if (!strcasecmp(attrs[i]->name(),name)) found = i; } if (found < 0) { exceptioncode = DOMException::NOT_FOUND_ERR; return 0; } Attr ret = attrs[found]; attrs[found]->_element = 0; attrs[found]->deref(); if (len == 1) { delete [] attrs; attrs = 0; len = 0; } else { AttrImpl **newAttrs = new AttrImpl* [len-1]; for (i = 0; i < uint(found); i++) newAttrs[i] = attrs[i]; len--; for (; i < len; i++) newAttrs[i] = attrs[i+1]; delete [] attrs; attrs = newAttrs; } DOMString nullStr; AttrImpl a(name,nullStr,element->docPtr()); element->parseAttribute(&a); element->setChanged(true); element->dispatchAttrRemovalEvent(ret.handle()); element->dispatchSubtreeModifiedEvent(); return ret;}Attr NamedAttrMapImpl::removeIdItem ( int id ){ if (!attrs) return 0; uint i; int found = -1; for (i = 0; i < len && found < 0; i++) { if (attrs[i]->attrId == id) found = i; } if (found < 0) return 0; Attr ret = attrs[found]; attrs[found]->_element = 0; attrs[found]->deref(); if (len == 1) { delete [] attrs; attrs = 0; len = 0; } else { AttrImpl **newAttrs = new AttrImpl* [len-1]; for (i = 0; i < uint(found); i++) newAttrs[i] = attrs[i]; len--; for (; i < len; i++) newAttrs[i] = attrs[i+1]; delete [] attrs; attrs = newAttrs; } DOMString nullStr; AttrImpl a(id,nullStr,element->docPtr()); element->parseAttribute(&a); element->setChanged(true); element->dispatchAttrRemovalEvent(ret.handle()); element->dispatchSubtreeModifiedEvent(); return ret;}NodeImpl *NamedAttrMapImpl::item ( unsigned long index, int &/*exceptioncode*/ ) const{ return item(index);}NodeImpl *NamedAttrMapImpl::item ( unsigned long index ) const{ if (index >= len) return 0; else return attrs[index];}void NamedAttrMapImpl::clearAttrs(){ if (attrs) { uint i; for (i = 0; i < len; i++) { attrs[i]->_element = 0; attrs[i]->deref(); } delete [] attrs; attrs = 0; } len = 0;}void NamedAttrMapImpl::insertAttr( AttrImpl *a ){ // only add if not already there if( !a->attrId || !getIdItem(a->attrId)) { AttrImpl** nList = new AttrImpl* [ len+1 ]; if(attrs) { for(uint i = 0; i < len; i++) nList[i] = attrs[i]; delete [] attrs; } attrs = nList; attrs[len++] = a; a->ref(); }}Attr NamedAttrMapImpl::removeAttr( AttrImpl *oldAttr, int &exceptioncode ){ exceptioncode = 0; uint i; for (i = 0; i < len; i++) { if (attrs[i] == oldAttr) { Attr ret = attrs[i]; attrs[i]->_element = 0; attrs[i]->deref(); if (len == 1) { delete [] attrs; attrs = 0; len = 0; } else { AttrImpl **newAttrs = new AttrImpl* [len-1]; uint ni; for (ni = 0; ni < i; ni++) newAttrs[ni] = attrs[ni]; len--; for (; ni < len; ni++) newAttrs[ni] = attrs[ni+1]; delete attrs; attrs = newAttrs; } AttrImpl a = oldAttr->attrId ? AttrImpl(oldAttr->attrId,"",element->docPtr()) : AttrImpl(oldAttr->name(),"",element->docPtr()); element->parseAttribute(&a); element->setChanged(true); element->dispatchAttrRemovalEvent(ret.handle()); element->dispatchSubtreeModifiedEvent(); return ret; } } exceptioncode = DOMException::NOT_FOUND_ERR; return 0;}void NamedAttrMapImpl::detachFromElement(){ // we allow a NamedAttrMapImpl w/o an element in case someone still has a reference // to if after the element gets deleted - but the map is now invalid element = 0; clearAttrs();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -