📄 dom_nodeimpl.cpp
字号:
if (evtId == EventImpl::UNKNOWN_EVENT) return; // shouldn't happen int exceptioncode = 0; int pageX = _mouse->x(); int pageY = _mouse->y(); int clientX = pageX; int clientY = pageY; if ( getDocument()->view() ) getDocument()->view()->viewportToContents( clientX, clientY, pageX, pageY ); int screenX = _mouse->globalX(); int screenY = _mouse->globalY(); int button = -1; switch (_mouse->button()) { case Qt::LeftButton: button = 0; break; case Qt::MidButton: button = 1; break; case Qt::RightButton: button = 2; break; default: break; } bool ctrlKey = (_mouse->state() & Qt::ControlButton); bool altKey = (_mouse->state() & Qt::AltButton); bool shiftKey = (_mouse->state() & Qt::ShiftButton); bool metaKey = false; // ### qt support? EventImpl* const evt = new MouseEventImpl(evtId,true,cancelable,getDocument()->defaultView(), detail,screenX,screenY,clientX,clientY,pageX,pageY,ctrlKey,altKey,shiftKey,metaKey, button,0); evt->ref(); dispatchEvent(evt,exceptioncode,true); evt->deref();}void NodeImpl::dispatchUIEvent(int _id, int detail){ assert (!( (_id != EventImpl::DOMFOCUSIN_EVENT && _id != EventImpl::DOMFOCUSOUT_EVENT && _id != EventImpl::DOMACTIVATE_EVENT))); bool cancelable = false; if (_id == EventImpl::DOMACTIVATE_EVENT) cancelable = true; int exceptioncode = 0; UIEventImpl* const evt = new UIEventImpl(static_cast<EventImpl::EventId>(_id),true, cancelable,getDocument()->defaultView(),detail); evt->ref(); dispatchEvent(evt,exceptioncode,true); evt->deref();}void NodeImpl::dispatchSubtreeModifiedEvent(){ childrenChanged(); getDocument()->incDOMTreeVersion(); if (!getDocument()->hasListenerType(DocumentImpl::DOMSUBTREEMODIFIED_LISTENER)) return; int exceptioncode = 0; MutationEventImpl* const evt = new MutationEventImpl(EventImpl::DOMSUBTREEMODIFIED_EVENT,true, false,0,DOMString(),DOMString(),DOMString(),0); evt->ref(); dispatchEvent(evt,exceptioncode,true); evt->deref();}bool NodeImpl::dispatchKeyEvent(QKeyEvent *key, bool keypress){ int exceptioncode = 0; //kdDebug(6010) << "DOM::NodeImpl: dispatching keyboard event" << endl; TextEventImpl* const keyEventImpl = new TextEventImpl(key, keypress, getDocument()->defaultView()); keyEventImpl->ref(); dispatchEvent(keyEventImpl,exceptioncode,true); bool r = keyEventImpl->defaultHandled() || keyEventImpl->defaultPrevented(); keyEventImpl->deref(); return r;}void NodeImpl::handleLocalEvents(EventImpl *evt, bool useCapture){ if (!m_regdListeners.listeners) return; Event ev = evt; // removeEventListener (e.g. called from a JS event listener) might // invalidate the item after the current iterator (which "it" is pointing to). // So we make a copy of the list. QValueList<RegisteredEventListener> listeners = *m_regdListeners.listeners; QValueList<RegisteredEventListener>::iterator it; for (it = listeners.begin(); it != listeners.end(); ++it) { //Check whether this got removed...KDE4: use Java-style iterators if (!m_regdListeners.stillContainsListener(*it)) continue; RegisteredEventListener& current = (*it); if (current.id == evt->id() && current.useCapture == useCapture) current.listener->handleEvent(ev); // ECMA legacy hack if (current.useCapture == useCapture && evt->id() == EventImpl::CLICK_EVENT) { MouseEventImpl* me = static_cast<MouseEventImpl*>(evt); if (me->button() == 0) { // To find whether to call onclick or ondblclick, we can't // * use me->detail(), it's 2 when clicking twice w/o moving, even very slowly // * use me->qEvent(), it's not available when using initMouseEvent/dispatchEvent // So we currently store a bool in MouseEventImpl. If anyone needs to trigger // dblclicks from the DOM API, we'll need a timer here (well in the doc). if ( ( !me->isDoubleClick() && current.id == EventImpl::KHTML_ECMA_CLICK_EVENT) || ( me->isDoubleClick() && current.id == EventImpl::KHTML_ECMA_DBLCLICK_EVENT) ) current.listener->handleEvent(ev); } } }}void NodeImpl::defaultEventHandler(EventImpl *){}unsigned long NodeImpl::childNodeCount(){ return 0;}NodeImpl *NodeImpl::childNode(unsigned long /*index*/){ return 0;}NodeImpl *NodeImpl::traverseNextNode(NodeImpl *stayWithin) const{ if (firstChild() || stayWithin == this) return firstChild(); else if (nextSibling()) return nextSibling(); else { const NodeImpl *n = this; while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin)) n = n->parentNode(); if (n) return n->nextSibling(); } return 0;}NodeImpl *NodeImpl::traversePreviousNode() const{ if (previousSibling()) { NodeImpl *n = previousSibling(); while (n->lastChild()) n = n->lastChild(); return n; } else if (parentNode()) { return parentNode(); } else { return 0; }}void NodeImpl::checkSetPrefix(const DOMString &_prefix, int &exceptioncode){ // Perform error checking as required by spec for setting Node.prefix. Used by // ElementImpl::setPrefix() and AttrImpl::setPrefix() // INVALID_CHARACTER_ERR: Raised if the specified prefix contains an illegal character. if (!Element::khtmlValidPrefix(_prefix)) { exceptioncode = DOMException::INVALID_CHARACTER_ERR; return; } // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. if (isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return; } // NAMESPACE_ERR: - Raised if the specified prefix is malformed // - if the namespaceURI of this node is null, // - if the specified prefix is "xml" and the namespaceURI of this node is different from // "http://www.w3.org/XML/1998/namespace", // - if this node is an attribute and the specified prefix is "xmlns" and // the namespaceURI of this node is different from "http://www.w3.org/2000/xmlns/", // - or if this node is an attribute and the qualifiedName of this node is "xmlns" [Namespaces]. if (Element::khtmlMalformedPrefix(_prefix) || (!(id() & NodeImpl_IdNSMask) && id() > ID_LAST_TAG) || (_prefix == "xml" && namespaceURI() != "http://www.w3.org/XML/1998/namespace")) { exceptioncode = DOMException::NAMESPACE_ERR; return; }}void NodeImpl::checkAddChild(NodeImpl *newChild, int &exceptioncode){ // Perform error checking as required by spec for adding a new child. Used by // appendChild(), replaceChild() and insertBefore() // Not mentioned in spec: throw NOT_FOUND_ERR if newChild is null if (!newChild) { exceptioncode = DOMException::NOT_FOUND_ERR; return; } // NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly if (isReadOnly()) { exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR; return; } // WRONG_DOCUMENT_ERR: Raised if newChild was created from a different document than the one that // created this node. // We assume that if newChild is a DocumentFragment, all children are created from the same document // as the fragment itself (otherwise they could not have been added as children) if (newChild->getDocument() != getDocument()) { exceptioncode = DOMException::WRONG_DOCUMENT_ERR; return; } // HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not allow children of the type of the // newChild node, or if the node to append is one of this node's ancestors. // check for ancestor/same node if (isAncestor(newChild)) { exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; return; } // check node allowed if (newChild->nodeType() == Node::DOCUMENT_FRAGMENT_NODE) { // newChild is a DocumentFragment... check all its children instead of newChild itself NodeImpl *child; for (child = newChild->firstChild(); child; child = child->nextSibling()) { if (!childAllowed(child)) { exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; return; } } } else { // newChild is not a DocumentFragment... check if it's allowed directly if(!childAllowed(newChild)) { exceptioncode = DOMException::HIERARCHY_REQUEST_ERR; return; } }}bool NodeImpl::isAncestor( NodeImpl *other ){ // Return true if other is the same as this node or an ancestor of it, otherwise false NodeImpl *n; for (n = this; n; n = n->parentNode()) { if (n == other) return true; } return false;}bool NodeImpl::childAllowed( NodeImpl *newChild ){ return childTypeAllowed(newChild->nodeType());}NodeImpl::StyleChange NodeImpl::diff( khtml::RenderStyle *s1, khtml::RenderStyle *s2 ) const{ StyleChange ch = NoInherit; if ( !s1 || !s2 ) ch = Inherit; else if ( *s1 == *s2 ) ch = NoChange; else if ( s1->inheritedNotEqual( s2 ) ) ch = Inherit; return ch;}void NodeImpl::close(){ closeRenderer(); m_closed = true;}void NodeImpl::closeRenderer(){ // It's important that we close the renderer, even if it hasn't been // created yet. This happens even more because of the FOUC fixes we did // at Apple, which prevent renderers from being created until the stylesheets // are all loaded. If the renderer is not here to be closed, we set a flag, // then close it later when it's attached. assert(!m_rendererNeedsClose); if (m_render) m_render->close(); else m_rendererNeedsClose = true;}void NodeImpl::attach(){ assert(!attached()); assert(!m_render || (m_render->style() && m_render->parent())); if (m_render && m_rendererNeedsClose) { m_render->close(); m_rendererNeedsClose = false; } getDocument()->incDOMTreeVersion(); m_attached = true;}void NodeImpl::detach(){// assert(m_attached); if ( m_render ) m_render->detach(); m_render = 0; getDocument()->incDOMTreeVersion(); m_attached = false;}bool NodeImpl::maintainsState(){ return false;}QString NodeImpl::state(){ return QString::null;}void NodeImpl::restoreState(const QString &/*state*/){}void NodeImpl::insertedIntoDocument(){ setInDocument(true);}void NodeImpl::removedFromDocument(){ setInDocument(false);}void NodeImpl::childrenChanged(){ if (parentNode()) parentNode()->childrenChanged();}bool NodeImpl::isReadOnly(){ // Entity & Entity Reference nodes and their descendants are read-only NodeImpl *n = this; while (n) { if (n->nodeType() == Node::ENTITY_NODE || n->nodeType() == Node::ENTITY_REFERENCE_NODE) return true; n = n->parentNode(); } return false;}RenderObject * NodeImpl::previousRenderer(){ for (NodeImpl *n = previousSibling(); n; n = n->previousSibling()) { if (n->renderer()) return n->renderer(); } return 0;}RenderObject * NodeImpl::nextRenderer(){ for (NodeImpl *n = nextSibling(); n; n = n->nextSibling()) { if (n->renderer()) return n->renderer(); } return 0;}void NodeImpl::createRendererIfNeeded(){#ifdef APPLE_CHANGES if (!getDocument()->shouldCreateRenderers()) return;#endif assert(!attached()); assert(!m_render); NodeImpl *parent = parentNode(); assert(parent); RenderObject *parentRenderer = parent->renderer(); if (parentRenderer && parentRenderer->childAllowed()) { RenderStyle *style = styleForRenderer(parentRenderer); style->ref(); if (rendererIsNeeded(style)) { m_render = createRenderer(getDocument()->renderArena(), style); m_render->setStyle(style); parentRenderer->addChild(m_render, nextRenderer()); } style->deref(); }}RenderStyle *NodeImpl::styleForRenderer(RenderObject *parent){ return parent->style();}bool NodeImpl::rendererIsNeeded(RenderStyle *style){ return (getDocument()->documentElement() == this) || (style->display() != NONE);}RenderObject *NodeImpl::createRenderer(RenderArena* /*arena*/, RenderStyle* /*style*/){ assert(false); return 0;}bool NodeImpl::contentEditable() const{ RenderObject *r = renderer(); if (!r) return false; return r->style()->userInput() == UI_ENABLED;}long NodeImpl::minOffset() const{ // Arrgh! You'd think *every* offset starts at zero, but loo, // therefore we need this method return renderer() ? renderer()->minOffset() : 0;}long NodeImpl::maxOffset() const{ return const_cast<NodeImpl *>(this)->childNodeCount();// return renderer() ? renderer()->maxOffset() : 1;}//-------------------------------------------------------------------------NodeBaseImpl::~NodeBaseImpl(){ //kdDebug( 6020 ) << "NodeBaseImpl destructor" << endl; // we have to tell all children, that the parent has died... NodeImpl *n; NodeImpl *next; for( n = _first; n != 0; n = next ) { next = n->nextSibling(); n->setPreviousSibling(0); n->setNextSibling(0); n->setParent(0); if ( !n->refCount() ) delete n; }}NodeImpl *NodeBaseImpl::firstChild() const{ return _first;}NodeImpl *NodeBaseImpl::lastChild() const{ return _last;}NodeImpl *NodeBaseImpl::insertBefore ( NodeImpl *newChild, NodeImpl *refChild, int &exceptioncode ){ exceptioncode = 0; // insertBefore(...,null) is equivalent to appendChild() if(!refChild) return appendChild(newChild, exceptioncode); // Make sure adding the new child is ok checkAddChild(newChild, exceptioncode); if (exceptioncode) return 0; // NOT_FOUND_ERR: Raised if refChild is not a child of this node if (refChild->parentNode() != this) { exceptioncode = DOMException::NOT_FOUND_ERR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -