[prev in list] [next in list] [prev in thread] [next in thread]
List: kfm-devel
Subject: Re: [PATCH] various nodeAtPoint() fixes
From: Germain Garand <germain () ebooksfrance ! com>
Date: 2002-07-15 6:04:53
[Download RAW message or body]
Le Samedi 13 Juillet 2002 19:19, Dirk Mueller a écrit :
[..]
> > - 1°: relative coordinates change don't propagate recursively to
> > childrens. (I posted this last week on kfm-devel but noone replied so
> > it's still pending)
>
> Yes, this was partly intended. I think I remember an interaction with
> absolute positioned containers in relative positioned parents.
I've tried to do something like that here :
http://www.phoenix-library.org/germain/testcases/bug_khtml_abs_child_in_rel_parent.html
Oddly enough, in such a case, the absolute translation is not rendered, but
nodeAtPoint() still think the link is were it should be : in the small golden
box.
>
> Personally i think khtml is behaving correct in this case, although it is
> very annoying for the example page you mentioned (I've spend some hours on
> that page already)
>
Frankly I think not... I've been haunted all the WE by that...
I'll elaborate, still on the http://www.w3.org/Style/CSS/ example :
When you hover the invisibly covered part of "What's New ?", the innermost
node is indeed, formally, <P>.
But how is it that the tree walking continues and finally elects "What's New"
as a good candidate for the hand cursor ?
From the formal point of view, the search should stop at <P>...
A striking illustration of that is when you hover "nearby" in the fixed menu.
Should we really get "What's New"'s hand cursor ?
What I want to advocate here is : there is a need to distinguish between two
kind of inner nodes :
- formal ones ("P" is indeed the innermost node, may it be invisible or
opaque) [owner: innerNode]
- visual ones ( for human sight, the innermost node is the "A" tag. If "P" was
overriding something on "A", it would be "P") [owner: visualNode]
In fact, khtml already does this distinction with URLElement, since it can be
different from the innerNode (too bad it's only for URLs).
I've implemented roughly such a mechanism in the attached patch,
and it looks promizing...
For instance, try comparing the behaviour on this slightly modified version :
http://www.phoenix-library.org/germain/testcases/www.w3.org/Style/CSS/
Anyway, feel free to have a look or simply throw it to the overcrowded Hell of
Lame ! ;-)
Germain
["render_object.patch" (text/x-diff)]
Index: render_object.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_object.h,v
retrieving revision 1.127
diff -u -p -r1.127 render_object.h
--- render_object.h 2002/06/16 15:23:47 1.127
+++ render_object.h 2002/07/15 05:53:25
@@ -281,19 +281,22 @@ public:
friend class DOM::HTMLAreaElementImpl;
public:
NodeInfo(bool readonly, bool active)
- : m_innerNode(0), m_innerURLElement(0), m_readonly(readonly), \
m_active(active) + : m_innerNode(0), m_visualNode(0), \
m_innerURLElement(0), m_readonly(readonly), m_active(active) { }
DOM::NodeImpl* innerNode() const { return m_innerNode; }
+ DOM::NodeImpl* visualNode() const { return m_visualNode; }
DOM::NodeImpl* URLElement() const { return m_innerURLElement; }
bool readonly() const { return m_readonly; }
bool active() const { return m_active; }
private:
void setInnerNode(DOM::NodeImpl* n) { m_innerNode = n; }
+ void setVisualNode(DOM::NodeImpl* n) { m_visualNode = n; }
void setURLElement(DOM::NodeImpl* n) { m_innerURLElement = n; }
-
+
DOM::NodeImpl* m_innerNode;
+ DOM::NodeImpl* m_visualNode;
DOM::NodeImpl* m_innerURLElement;
bool m_readonly;
bool m_active;
Index: render_object.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_object.cpp,v
retrieving revision 1.177
diff -u -p -r1.177 render_object.cpp
--- render_object.cpp 2002/06/16 15:23:47 1.177
+++ render_object.cpp 2002/07/15 05:53:25
@@ -837,24 +837,40 @@ bool RenderObject::nodeAtPoint(NodeInfo&
bool inside = (style()->visibility() != HIDDEN && ((_y >= ty) && (_y < \
ty + height()) &&
(_x >= tx) && (_x < tx + width()))) || isBody() || \
isHtml();
- bool inner = !info.innerNode();
-
+
// ### table should have its own, more performant method
if (overhangingContents() || isInline() || isRoot() || isTableRow() || \
isTableSection() || inside || mouseInside() ) {
for (RenderObject* child = lastChild(); child; child = \
child->previousSibling())
- if (!child->isPositioned() && child->nodeAtPoint(info, _x, _y, \
_tx+xPos(), _ty+yPos())) + if (!child->isPositioned() && \
child->nodeAtPoint(info, _x, _y, tx, ty)) inside = true;
}
if (inside && element()) {
- if (!info.innerNode())
+ if (!info.innerNode()){
+ kdDebug() << "iNode: "<< information() << endl;
info.setInnerNode(element());
-
- if (!info.URLElement()) {
+ }
+ if ( !info.visualNode() &&
+ ( isRoot() || element()->hasAnchor() ||
+ ( style() &&
+ ( style()->hasHover() || (info.active() && \
style()->hasActive()) || + style()->hasBorder() ||
+ ( container() && container()->style() &&
+ ( container()->style()->backgroundColor() != \
style()->backgroundColor() || + \
container()->style()->backgroundImage() != style()->backgroundImage() + \
) + )
+ )
+ )
+ )
+ ) {
+ info.setVisualNode(element());
+ kdDebug() << "vNode: "<< information() << endl;
RenderObject* p = this;
while (p) {
if (p->element() && p->element()->hasAnchor()) {
info.setURLElement(p->element());
+ kdDebug() << "URL: " << information() << endl;
break;
}
if (!isSpecial()) break;
@@ -866,14 +882,23 @@ bool RenderObject::nodeAtPoint(NodeInfo&
if (!info.readonly()) {
// lets see if we need a new style
bool oldinside = mouseInside();
- setMouseInside(inside && inner);
+ setMouseInside(false);
if (element()) {
bool oldactive = element()->active();
- if (oldactive != (inside && info.active() && element() == \
info.innerNode()))
- element()->setActive(inside && info.active() && element() \
== info.innerNode()); + if (oldactive != (inside && \
info.active() && element() == info.visualNode())) + \
element()->setActive(inside && info.active() && element() == \
info.visualNode()); if ( ((oldinside != mouseInside()) && \
style()->hasHover()) ||
((oldactive != element()->active()) && \
style()->hasActive())) element()->setChanged();
+ }
+ if(isRoot() && info.visualNode()) {
+ RenderObject* p = info.visualNode()->renderer();
+ while(p && !p->isRoot()){
+ p->setMouseInside(true);
+ if (p->style() && p->style()->hasHover())
+ element()->setChanged();
+ p = p->parent();
+ }
}
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic