dom_nodeimpl.cpp
来自「最新Nokia手机浏览器全套源代码完美版。」· C++ 代码 · 共 2,194 行 · 第 1/5 页
CPP
2,194 行
assert(!eventDispatchForbidden());
int exceptioncode = 0;
//kdDebug(6010) << "DOM::NodeImpl: dispatching keyboard event" << endl;
KeyboardEventImpl *keyboardEventImpl = new KeyboardEventImpl(key, getDocument()->defaultView());
keyboardEventImpl->ref();
bool r = dispatchEvent(keyboardEventImpl,exceptioncode,true);
#if APPLE_CHANGES
// we want to return false if default is prevented (already taken care of)
// or if the element is default-handled by the DOM. Otherwise we let it just
// let it get handled by AppKit
if (keyboardEventImpl->defaultHandled())
#else
// the default event handler should accept() the internal QKeyEvent
// to prevent the view from further evaluating it.
if (!keyboardEventImpl->defaultPrevented() && !keyboardEventImpl->qKeyEvent->isAccepted())
#endif
r = false;
keyboardEventImpl->deref();
return r;
}
void NodeImpl::dispatchWheelEvent(QWheelEvent *e)
{
assert(!eventDispatchForbidden());
if (e->delta() == 0)
return;
DocumentImpl *doc = getDocument();
if (!doc)
return;
KHTMLView *view = getDocument()->view();
if (!view)
return;
int x;
int y;
view->viewportToContents(e->x(), e->y(), x, y);
int state = e->state();
WheelEventImpl *we = new WheelEventImpl(e->orientation() == Qt::Horizontal, e->delta(),
getDocument()->defaultView(), e->globalX(), e->globalY(), x, y,
state & Qt::ControlButton, state & Qt::AltButton, state & Qt::ShiftButton, state & Qt::MetaButton);
int exceptionCode = 0;
if (!dispatchEvent(we, exceptionCode, true))
e->accept();
}
void NodeImpl::handleLocalEvents(EventImpl *evt, bool useCapture)
{
if (!m_regdListeners)
return;
if (disabled() && evt->isMouseEvent())
return;
QPtrList<RegisteredEventListener> listenersCopy = *m_regdListeners;
QPtrListIterator<RegisteredEventListener> it(listenersCopy);
Event ev = evt;
for (; it.current(); ++it) {
if (it.current()->id == evt->id() && it.current()->useCapture == useCapture)
it.current()->listener->handleEvent(ev, false);
}
}
void NodeImpl::defaultEventHandler(EventImpl *evt)
{
}
unsigned long NodeImpl::childNodeCount() const
{
return 0;
}
NodeImpl *NodeImpl::childNode(unsigned long /*index*/)
{
return 0;
}
NodeImpl *NodeImpl::traverseNextNode(const NodeImpl *stayWithin) const
{
if (firstChild()) {
assert(!stayWithin || firstChild()->isAncestor(stayWithin));
return firstChild();
}
if (this == stayWithin)
return 0;
if (nextSibling()) {
assert(!stayWithin || nextSibling()->isAncestor(stayWithin));
return nextSibling();
}
const NodeImpl *n = this;
while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
if (n) {
assert(!stayWithin || !n->nextSibling() || n->nextSibling()->isAncestor(stayWithin));
return n->nextSibling();
}
return 0;
}
NodeImpl *NodeImpl::traverseNextSibling(const NodeImpl *stayWithin) const
{
if (this == stayWithin)
return 0;
if (nextSibling()) {
assert(!stayWithin || nextSibling()->isAncestor(stayWithin));
return nextSibling();
}
const NodeImpl *n = this;
while (n && !n->nextSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
if (n) {
assert(!stayWithin || !n->nextSibling() || n->nextSibling()->isAncestor(stayWithin));
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;
}
}
NodeImpl *NodeImpl::traversePreviousNodePostOrder(const NodeImpl *stayWithin) const
{
if (lastChild()) {
assert(!stayWithin || lastChild()->isAncestor(stayWithin));
return lastChild();
}
if (this == stayWithin)
return 0;
if (previousSibling()) {
assert(!stayWithin || previousSibling()->isAncestor(stayWithin));
return previousSibling();
}
const NodeImpl *n = this;
while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
n = n->parentNode();
if (n) {
assert(!stayWithin || !n->previousSibling() || n->previousSibling()->isAncestor(stayWithin));
return n->previousSibling();
}
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) || (namespacePart(id()) == noNamespace && id() > ID_LAST_TAG) ||
(_prefix == "xml" && DOMString(getDocument()->namespaceURI(id())) != "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;
}
bool shouldAdoptChild = false;
// 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()) {
// but if the child is not in a document yet then loosen the
// restriction, so that e.g. creating an element with the Option()
// constructor and then adding it to a different document works,
// as it does in Mozilla and Mac IE.
if (!newChild->inDocument()) {
shouldAdoptChild = true;
} else {
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 (newChild == this || isAncestor(newChild)) {
exceptioncode = DOMException::HIERARCHY_REQUEST_ERR;
return;
}
// only do this once we know there won't be an exception
if (shouldAdoptChild) {
KJS::ScriptInterpreter::updateDOMNodeDocument(newChild, newChild->getDocument(), getDocument());
newChild->setDocument(getDocument()->docPtr());
}
}
bool NodeImpl::isAncestor(const NodeImpl *other) const
{
// Return true if other is an ancestor of this, otherwise false
for (const NodeImpl *n = parentNode(); 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
{
// FIXME: The behavior of this function is just totally wrong. It doesn't handle
// explicit inheritance of non-inherited properties and so you end up not re-resolving
// style in cases where you need to.
StyleChange ch = NoInherit;
EDisplay display1 = s1 ? s1->display() : NONE;
bool fl1 = s1 ? s1->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
EDisplay display2 = s2 ? s2->display() : NONE;
bool fl2 = s2 ? s2->hasPseudoStyle(RenderStyle::FIRST_LETTER) : false;
if (display1 != display2 || fl1 != fl2)
ch = Detach;
else if ( !s1 || !s2 )
ch = Inherit;
else if ( *s1 == *s2 )
ch = NoChange;
else if ( s1->inheritedNotEqual( s2 ) )
ch = Inherit;
return ch;
}
#ifndef NDEBUG
void NodeImpl::dump(QTextStream *stream, QString ind) const
{
// ### implement dump() for all appropriate subclasses
if (m_hasId) { *stream << " hasId"; }
if (m_hasClass) { *stream << " hasClass"; }
if (m_hasStyle) { *stream << " hasStyle"; }
if (m_specified) { *stream << " specified"; }
if (m_focused) { *stream << " focused"; }
if (m_active) { *stream << " active"; }
if (m_styleElement) { *stream << " styleElement"; }
if (m_implicit) { *stream << " implicit"; }
*stream << " tabIndex=" << m_tabIndex;
if (m_regdListeners)
*stream << " #regdListeners=" << m_regdListeners->count(); // ### more detail
//*stream << endl;
NodeImpl *child = firstChild();
while( child != 0 )
{
*stream << ind << child->nodeName().string().ascii() << ": ";
child->dump(stream,ind+" ");
child = child->nextSibling();
}
}
#endif
void NodeImpl::attach()
{
assert(!attached());
assert(!m_render || (m_render->style() && m_render->parent()));
getDocument()->incDOMTreeVersion();
m_attached = true;
}
void NodeImpl::willRemove()
{
}
void NodeImpl::detach()
{
// assert(m_attached);
if (m_render)
m_render->detach();
m_render = 0;
DocumentImpl *doc = getDocument();
if (doc)
doc->incDOMTreeVersion();
m_attached = false;
}
bool NodeImpl::maintainsState()
{
return false;
}
QString NodeImpl::state()
{
return QString::null;
}
void NodeImpl::restoreState(QStringList &/*states*/)
{
}
void NodeImpl::insertedIntoDocument()
{
if (m_regdListeners && !m_regdListeners->isEmpty() && getDocument())
getDocument()->unregisterDisconnectedNodeWithEventListeners(this);
setInDocument(true);
}
void NodeImpl::removedFromDocument()
{
if (m_regdListeners && !m_regdListeners->isEmpty() && getDocument())
getDocument()->registerDisconnectedNodeWithEventListeners(this);
setInDocument(false);
}
void NodeImpl::childrenChanged()
{
}
bool NodeImpl::disabled() const
{
return false;
}
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;
}
NodeImpl *NodeImpl::previousEditable() const
{
NodeImpl *node = previousLeafNode();
while (node) {
if (node->isContentEditable())
return node;
node = node->previousLeafNode();
}
return 0;
}
NodeImpl *NodeImpl::nextEditable() const
{
NodeImpl *node = nextLeafNode();
while (node) {
if (node->isContentEditable())
return node;
node = node->nextLeafNode();
}
return 0;
}
RenderObject * NodeImpl::previousRenderer()
{
for (NodeImpl *n = previousSibling(); n; n = n->previousSibling()) {
if (n->renderer())
return n->renderer();
}
return 0;
}
RenderObject * NodeImpl::nextRenderer()
{
// Avoid an O(n^2) problem with this function by not checking for nextRenderer() when the parent element hasn't even
// been attached yet.
if (parent() && !parent()->attached())
return 0;
for (NodeImpl *n = nextSibling(); n; n = n->nextSibling()) {
if (n->renderer())
return n->renderer();
}
return 0;
}
bool NodeImpl::isAtomicNode() const
{
return !hasChildNodes() || (id() == ID_OBJECT && renderer() && renderer()->isReplaced());
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?