[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Re: [PATCH] tracking form value changes in onclick-handlers
From:       Tobias Anton <TA () ESC-Electronics ! de>
Date:       2004-07-13 19:10:31
Message-ID: 200407132110.31587.TA () ESC-Electronics ! de
[Download RAW message or body]

On Dienstag, 13. Juli 2004 02:06, bj@altern.org wrote:
> On Monday 12 July 2004 19.52, Tobias Anton wrote:
> > I'm planning to commit a patch like this one, and then I'd like to change
> > the default event handlers of activatable elements (links, form controls
> > and labels) to react on DOMACTIVATE_EVENT instead of CLICK_EVENT, or
> > event worse, MOUSEUP_EVENTS.
> >
> > Is there anything basically wrong or can I try this approach?
>
> Many webmail have a checkbox with something like this:
>
> <form>
> <input type="checkbox" onclick="anotherform.checked=this.checked">1<br>
> <input id="anotherform" type="checkbox"
> onclick="anotherform.checked=this.checked">2
> </form>
>
> Clicking on the checkbox 1 should always set the second checkbox to the
> same value. If you process the javascript events first, the this.checked
> will return a wrong value...
>
> I don't think your patch adresses this issue.

I just made a few other tests with IE. The bottom line is:

When a click event is to be processed, the following steps happen internally:
1. the old value of the form is backed up.
2. the value is changed
3. the onclick-javascript code is called
4. if the script returns false, the old value is restored.

And:
onclick-javascript is executed after both mouse clicks and pressing space.

This behaviour is resembled by this new patch (attached).

Comments and ideas welcome.

Cheers
-- Tobias
["temp.diff" (text/x-diff)]

? temp
? testregression
Index: html/html_formimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_formimpl.cpp,v
retrieving revision 1.375
diff -u -3 -p -r1.375 html_formimpl.cpp
--- html/html_formimpl.cpp	12 Jul 2004 22:39:44 -0000	1.375
+++ html/html_formimpl.cpp	13 Jul 2004 20:09:27 -0000
@@ -850,58 +850,48 @@ void HTMLGenericFormElementImpl::default
         }
     }
 
-    if (evt->target()==this && !m_disabled)
+    if (!m_disabled)
     {
-        // Report focus in/out changes to the browser extension (editable widgets \
                only)
-        KHTMLView *view = getDocument()->view();
-        if (view && evt->id() == EventImpl::DOMFOCUSIN_EVENT && isEditable() && \
                m_render && m_render->isWidget()) {
-            KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension \
                *>(view->part()->browserExtension());
-            QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
-            if (ext)
-                ext->editableWidgetFocused(widget);
-        }
-        if (evt->id()==EventImpl::MOUSEDOWN_EVENT || \
                evt->id()==EventImpl::KEYDOWN_EVENT)
-        {
-            setActive();
-        }
-        else if (evt->id() == EventImpl::MOUSEUP_EVENT || \
                evt->id()==EventImpl::KEYUP_EVENT)
-        {
-	    if (m_active)
-	    {
-		setActive(false);
-		setFocus();
-	    }
-	    else {
-                setActive(false);
-            }
-        }
-
-	if (evt->id() == EventImpl::KHTML_KEYPRESS_EVENT) {
-	    TextEventImpl * k = static_cast<TextEventImpl *>(evt);
-	    int key = k->qKeyEvent ? k->qKeyEvent->key() : 0;
-	    if (m_render && (key == Qt::Key_Tab || key == Qt::Key_BackTab)) {
-		QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
-		if (widget)
-		    static_cast<FocusHandleWidget *>(widget)
-			->focusNextPrev(key == Qt::Key_Tab);
-	    }
-	}
-
-
-	if (view && evt->id() == EventImpl::DOMFOCUSOUT_EVENT && isEditable() && m_render \
                && m_render->isWidget()) {
-	    KHTMLPartBrowserExtension *ext = static_cast<KHTMLPartBrowserExtension \
                *>(view->part()->browserExtension());
-	    QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
-	    if (ext)
-		ext->editableWidgetBlurred(widget);
+		if (evt->target()==this)
+		{
+			// Report focus in/out changes to the browser extension (editable widgets only)
+			KHTMLView *view = getDocument()->view();
+			if (view && evt->id() == EventImpl::DOMFOCUSIN_EVENT && isEditable() && m_render \
&& m_render->isWidget()) { +				KHTMLPartBrowserExtension *ext = \
static_cast<KHTMLPartBrowserExtension *>(view->part()->browserExtension()); \
+				QWidget *widget = static_cast<RenderWidget*>(m_render)->widget(); +				if (ext)
+					ext->editableWidgetFocused(widget);
+			}
+			if (evt->id() == EventImpl::KHTML_KEYPRESS_EVENT) {
+				TextEventImpl * k = static_cast<TextEventImpl *>(evt);
+				int key = k->qKeyEvent ? k->qKeyEvent->key() : 0;
+				if (m_render && (key == Qt::Key_Tab || key == Qt::Key_BackTab)) {
+					QWidget *widget = static_cast<RenderWidget*>(m_render)->widget();
+					if (widget)
+						static_cast<FocusHandleWidget *>(widget)
+							->focusNextPrev(key == Qt::Key_Tab);
+				}
+			}
+	    
+			if (view && evt->id() == EventImpl::DOMFOCUSOUT_EVENT && isEditable() && m_render \
&& m_render->isWidget()) { +				KHTMLPartBrowserExtension *ext = \
static_cast<KHTMLPartBrowserExtension *>(view->part()->browserExtension()); \
+				QWidget *widget = static_cast<RenderWidget*>(m_render)->widget(); +				if (ext)
+					ext->editableWidgetBlurred(widget);
+		
+				// ### Don't count popup as a valid reason for losing the focus (example: \
opening the options of a select +				// combobox shouldn't emit onblur)
+			}
 
-	    // ### Don't count popup as a valid reason for losing the focus (example: \
                opening the options of a select
-	    // combobox shouldn't emit onblur)
-	}
+			if (evt->isMouseEvent() && renderer())
+				evt->setDefaultHandled();
+		}
+	
+		// don't call the base class if the form control is disabled!
+		// HTMLElementImpl doesn't know about the inactive state
+		// and will set this element focused.
+		HTMLElementImpl::defaultEventHandler(evt);
     }
-    if (evt->target() == this && evt->isMouseEvent() && renderer())
-        evt->setDefaultHandled();
-
-    HTMLElementImpl::defaultEventHandler(evt);
 }
 
 bool HTMLGenericFormElementImpl::isEditable()
@@ -959,16 +949,8 @@ void HTMLButtonElementImpl::parseAttribu
 
 void HTMLButtonElementImpl::defaultEventHandler(EventImpl *evt)
 {
-    if (m_type != BUTTON && !m_disabled) {
-	bool act = (evt->id() == EventImpl::DOMACTIVATE_EVENT);
-	if (!act && evt->id()==EventImpl::KEYUP_EVENT) {
-	    QKeyEvent *ke = static_cast<TextEventImpl *>(evt)->qKeyEvent;
-	    if (ke && active() && (ke->key() == Qt::Key_Return || ke->key() == \
                Qt::Key_Enter || ke->key() == Qt::Key_Space))
-		act = true;
-	}
-	if (act)
-	    activate();
-    }
+    if (evt->target() == this && m_type != BUTTON && !m_disabled && evt->id() == \
EventImpl::DOMACTIVATE_EVENT) +	activate();
     HTMLGenericFormElementImpl::defaultEventHandler(evt);
 }
 
@@ -1476,58 +1458,56 @@ void HTMLInputElementImpl::focus()
     getDocument()->setFocusNode(this);
 }
 
+void HTMLInputElementImpl::handleLocalEvents(EventImpl *evt, bool useCapture)
+{
+	if (!useCapture && evt->id()==EventImpl::KHTML_ECMA_CLICK_EVENT && (m_type == \
CHECKBOX || m_type == RADIO)) +	{
+		kdDebug ( 6000 ) << "ecma click on " << (m_type == CHECKBOX?"checkbox":"radio") << \
endl; +		bool oldvalue = checked();
+		setChecked(m_type==RADIO?true:!oldvalue);
+		HTMLGenericFormElementImpl::handleLocalEvents(evt, useCapture);
+		if (evt->defaultPrevented())
+			setChecked(oldvalue);
+	}
+	else HTMLGenericFormElementImpl::handleLocalEvents(evt, useCapture);
+}
+
 void HTMLInputElementImpl::defaultEventHandler(EventImpl *evt)
 {
     if ( !m_disabled )
     {
-
-        if (evt->isMouseEvent()) {
-	    MouseEventImpl *me = static_cast<MouseEventImpl*>(evt);
-            if ((m_type == RADIO || m_type == CHECKBOX)
-		&& me->id() == EventImpl::MOUSEUP_EVENT && me->detail() > 0) {
-		// click will follow
-		setChecked(m_type == RADIO ? true : !checked());
-	    }
-            if (evt->id() == EventImpl::CLICK_EVENT && m_type == IMAGE && m_render) \
                {
-		// record the mouse position for when we get the DOMActivate event
-		int offsetX, offsetY;
-		m_render->absolutePosition(offsetX,offsetY);
-		xPos = me->clientX()-offsetX;
-		yPos = me->clientY()-offsetY;
-	    }
-	}
-
-        if (m_type == RADIO || m_type == CHECKBOX || m_type == SUBMIT || m_type == \
                RESET || m_type == BUTTON ) {
-	    bool check = false;
-	    if (active() && ( evt->id() == EventImpl::KEYUP_EVENT ||
-	                      evt->id() == EventImpl::KHTML_KEYPRESS_EVENT ) ) {
-		TextEventImpl *te = static_cast<TextEventImpl *>(evt);
-		if (te->keyVal() == ' ')
-		    check = true;
-	    }
-	    if (check) {
-	        if (evt->id() == EventImpl::KEYUP_EVENT)
-		    click();
-	        // Tell the parent that we handle this key (keyup and keydown), even though \
                only keyup activates (#70478)
-	        evt->setDefaultHandled();
-	    }
-        }
-
-
-        // DOMActivate events cause the input to be "activated" - in the case of \
                image and submit inputs, this means
-        // actually submitting the form. For reset inputs, the form is reset. These \
                events are sent when the user clicks
-        // on the element, or presses enter while it is the active element. \
                Javascript code wishing to activate the element
-        // must dispatch a DOMActivate event - a click event will not do the job.
-        if (m_type == IMAGE || m_type == SUBMIT || m_type == RESET) {
-	    bool act = (evt->id() == EventImpl::DOMACTIVATE_EVENT);
-	    if (!act && evt->id() == EventImpl::KEYUP_EVENT) {
-		QKeyEvent *ke = static_cast<TextEventImpl *>(evt)->qKeyEvent;
-		if (ke && active() && (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter \
                || ke->key() == Qt::Key_Space))
-		    act = true;
-	    }
-	    if (act)
-		activate();
-	}
+        switch ( evt->id() )
+		{
+		case EventImpl::KEYUP_EVENT:
+		case EventImpl::KHTML_KEYPRESS_EVENT:
+			if ( static_cast<TextEventImpl *>(evt)->keyVal() == ' ' && active() && (m_type == \
RADIO ||  +																					m_type == CHECKBOX || 
+																					m_type == SUBMIT || 
+																					m_type == RESET || 
+																					m_type == BUTTON ) )
+				evt->setDefaultHandled();
+
+			break;
+		case EventImpl::DOMACTIVATE_EVENT:
+			if (m_type == BUTTON || m_type == IMAGE || m_type == SUBMIT || m_type == RESET)
+			{
+				DOMActivateEventImpl *ae = static_cast<DOMActivateEventImpl*>(evt);
+				if (ae->parent() && ae->parent()->id()==EventImpl::CLICK_EVENT && m_type == \
IMAGE && m_render) +				{
+					MouseEventImpl *me = static_cast<MouseEventImpl*>(ae->parent());
+					// record the mouse position for when we get the DOMActivate event
+					int offsetX, offsetY;
+					m_render->absolutePosition(offsetX,offsetY);
+					xPos = me->clientX()-offsetX;
+					yPos = me->clientY()-offsetY;
+				}
+				activate();
+				evt->setDefaultHandled();
+			}
+			break;
+		default:
+			break;
+		};
     }
     HTMLGenericFormElementImpl::defaultEventHandler(evt);
 }
@@ -1601,26 +1581,25 @@ return newNode;
 void HTMLLabelElementImpl::defaultEventHandler(EventImpl *evt)
 {
     if ( !m_disabled ) {
-	bool act = false;
-	if ( evt->id() == EventImpl::CLICK_EVENT ) {
-	    act = true;
-	}
-	else if ( evt->id() == EventImpl::KEYUP_EVENT ||
-	                      evt->id() == EventImpl::KHTML_KEYPRESS_EVENT ) {
-	    QKeyEvent *ke = static_cast<TextEventImpl *>(evt)->qKeyEvent;
-	    if (ke && active() && (ke->key() == Qt::Key_Return || ke->key() == \
                Qt::Key_Enter || ke->key() == Qt::Key_Space))
-		act = true;
-	}
+        if (evt->id()==EventImpl::DOMACTIVATE_EVENT) {
 
-	if (act) {
-	    NodeImpl *formNode=getFormElement();
-	    if (formNode) {
-		getDocument()->setFocusNode(formNode);
-		if (formNode->id()==ID_INPUT)
-		    static_cast<DOM::HTMLInputElementImpl*>(formNode)->click();
-	    }
-	    evt->setDefaultHandled();
-	}
+            NodeImpl *formNode=getFormElement();
+            
+            if (formNode) {
+                Node guard(formNode);
+                getDocument()->setFocusNode(formNode);
+                if (formNode->isSelectable())
+                {
+                    kdDebug ( 6000 ) << " activating label's target\n";
+                    int exceptioncode = 0;
+                    DOMActivateEventImpl *ae = new \
DOMActivateEventImpl(getDocument()->defaultView(), 1, static_cast<UIEventImpl \
*>(evt)); +                    ae->ref();
+                    formNode->dispatchEvent(ae,exceptioncode,true);
+                    ae->deref();
+                }
+            }
+            evt->setDefaultHandled();
+        }
     }
     HTMLGenericFormElementImpl::defaultEventHandler(evt);
 }
Index: html/html_formimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_formimpl.h,v
retrieving revision 1.154
diff -u -3 -p -r1.154 html_formimpl.h
--- html/html_formimpl.h	12 Jul 2004 19:57:03 -0000	1.154
+++ html/html_formimpl.h	13 Jul 2004 20:09:27 -0000
@@ -273,6 +273,7 @@ public:
 
     void select();
     void click();
+    void activate();
 
     virtual void parseAttribute(AttributeImpl *attr);
 
@@ -286,11 +287,11 @@ public:
     int clickX() const { return xPos; }
     int clickY() const { return yPos; }
 
+    virtual void handleLocalEvents(EventImpl *, bool);
     virtual void defaultEventHandler(EventImpl *evt);
     virtual bool isEditable();
 
     DOMString altText() const;
-    void activate();
 
 protected:
 
Index: html/html_inlineimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/html/html_inlineimpl.cpp,v
retrieving revision 1.134
diff -u -3 -p -r1.134 html_inlineimpl.cpp
--- html/html_inlineimpl.cpp	18 Mar 2004 13:41:37 -0000	1.134
+++ html/html_inlineimpl.cpp	13 Jul 2004 20:09:27 -0000
@@ -51,43 +51,21 @@ NodeImpl::Id HTMLAnchorElementImpl::id()
 
 void HTMLAnchorElementImpl::defaultEventHandler(EventImpl *evt)
 {
-    bool keydown = evt->id() == EventImpl::KEYDOWN_EVENT;
+    if (evt->id()==EventImpl::DOMACTIVATE_EVENT)
+    {
+	DOMActivateEventImpl *ae = static_cast<DOMActivateEventImpl*>(evt);
 
-    // React on clicks and on keypresses.
-    // Don't make this KEYUP_EVENT again, it makes khtml follow links
-    // it shouldn't, when pressing Enter in the combo.
-    if ( ( (evt->id() == EventImpl::CLICK_EVENT && \
                !static_cast<MouseEventImpl*>(evt)->isDoubleClick()) ||
-         ( keydown && m_focused)) && m_hasAnchor) {
-
-        MouseEventImpl *e = 0;
-        if ( evt->id() == EventImpl::CLICK_EVENT )
-            e = static_cast<MouseEventImpl*>( evt );
-
-        TextEventImpl *k = 0;
-        if (keydown)
-            k = static_cast<TextEventImpl *>( evt );
+	MouseEventImpl *e = NULL;
+	if (ae->parent() && ae->parent()->id() == EventImpl::CLICK_EVENT)
+	    e = static_cast <MouseEventImpl *>(ae->parent());
 
-        QString utarget;
-        QString url;
         if ( e && e->button() == 2 ) {
 	    HTMLElementImpl::defaultEventHandler(evt);
 	    return;
         }
 
-        if ( k ) {
-            if (k->virtKeyVal() != TextEventImpl::DOM_VK_ENTER) {
-                if (k->qKeyEvent)
-                    k->qKeyEvent->ignore();
-                HTMLElementImpl::defaultEventHandler(evt);
-                return;
-            }
-            if (k->qKeyEvent) k->qKeyEvent->accept();
-        }
-
-        url = khtml::parseURL(getAttribute(ATTR_HREF)).string();
-
-        utarget = getAttribute(ATTR_TARGET).string();
-
+        QString utarget = getAttribute(ATTR_TARGET).string();
+        QString url = khtml::parseURL(getAttribute(ATTR_HREF)).string();
         if ( e && e->button() == 1 )
             utarget = "_blank";
 
@@ -117,45 +95,61 @@ void HTMLAnchorElementImpl::defaultEvent
                 }
             }
         }
-        if ( !evt->defaultPrevented() ) {
-            int state = 0;
-            int button = 0;
-
-            if ( e ) {
-                if ( e->ctrlKey() )
-                    state |= Qt::ControlButton;
-                if ( e->shiftKey() )
-                    state |= Qt::ShiftButton;
-                if ( e->altKey() )
-                    state |= Qt::AltButton;
-                if ( e->metaKey() )
-                    state |= Qt::MetaButton;
-
-                if ( e->button() == 0 )
-                    button = Qt::LeftButton;
-                else if ( e->button() == 1 )
-                    button = Qt::MidButton;
-                else if ( e->button() == 2 )
-                    button = Qt::RightButton;
-            }
-	    else if ( k )
-	    {
-	      if ( k->checkModifier(Qt::ShiftButton) )
+
+	TextEventImpl *k = NULL;
+	if (ae->parent() && (ae->parent()->id() == EventImpl::KEYUP_EVENT || \
ae->parent()->id() == EventImpl::KHTML_KEYPRESS_EVENT)) +	    k = static_cast \
<TextEventImpl *>(ae->parent()); +	
+	int state = 0;
+	int button = 0;
+	if ( e ) {
+	    if ( e->ctrlKey() )
+		state |= Qt::ControlButton;
+	    if ( e->shiftKey() )
+		state |= Qt::ShiftButton;
+	    if ( e->altKey() )
+		state |= Qt::AltButton;
+	    if ( e->metaKey() )
+		state |= Qt::MetaButton;
+	    
+	    if ( e->button() == 0 )
+		button = Qt::LeftButton;
+	    else if ( e->button() == 1 )
+		button = Qt::MidButton;
+	    else if ( e->button() == 2 )
+		button = Qt::RightButton;
+	}
+	else if ( k )
+	{
+	    if ( k->checkModifier(Qt::ShiftButton) )
                 state |= Qt::ShiftButton;
-	      if ( k->checkModifier(Qt::AltButton) )
+	    if ( k->checkModifier(Qt::AltButton) )
                 state |= Qt::AltButton;
-	      if ( k->checkModifier(Qt::ControlButton) )
+	    if ( k->checkModifier(Qt::ControlButton) )
                 state |= Qt::ControlButton;
-	    }
+	}
 
-	    // ### also check if focused node is editable if not in designmode,
-	    // and prevent link loading then (LS)
-	    if (getDocument()->view() && !getDocument()->designMode())
-		getDocument()->view()->part()->
-		    urlSelected( url, button, state, utarget );
-        }
-        evt->setDefaultHandled();
+	// ### also check if focused node is editable if not in designmode,
+	// and prevent link loading then (LS)
+	if (getDocument()->view() && !getDocument()->designMode())
+	    getDocument()->view()->part()->
+		urlSelected( url, button, state, utarget );
+	
+	evt->setDefaultHandled();
     }
+    else if (evt->id()==EventImpl::KEYUP_EVENT || \
evt->id()==EventImpl::KHTML_KEYPRESS_EVENT) +    {
+	TextEventImpl * k = static_cast<TextEventImpl*>(evt);
+
+	if (k->virtKeyVal() != TextEventImpl::DOM_VK_ENTER) {
+	    if (k->qKeyEvent)
+		k->qKeyEvent->ignore();
+	    HTMLElementImpl::defaultEventHandler(evt);
+	    return;
+	}
+	if (k->qKeyEvent) k->qKeyEvent->accept();
+    }
+
     HTMLElementImpl::defaultEventHandler(evt);
 }
 
Index: xml/dom2_eventsimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom2_eventsimpl.cpp,v
retrieving revision 1.46
diff -u -3 -p -r1.46 dom2_eventsimpl.cpp
--- xml/dom2_eventsimpl.cpp	24 Feb 2004 16:11:56 -0000	1.46
+++ xml/dom2_eventsimpl.cpp	13 Jul 2004 20:09:27 -0000
@@ -731,6 +731,24 @@ bool TextEventImpl::isTextEvent() const
     return true;
 }
 
+
+// -----------------------------------------------------------------------------
+
+DOMActivateEventImpl::DOMActivateEventImpl(AbstractViewImpl *viewArg,
+		     long detailArg, UIEventImpl *_parent)
+    : UIEventImpl(DOMACTIVATE_EVENT, true, true, viewArg, detailArg)
+{
+    if (_parent)
+	_parent->ref();
+    m_parent = _parent;
+}
+
+DOMActivateEventImpl::~DOMActivateEventImpl()
+{
+    if (m_parent)
+	m_parent->deref();
+}
+
 // -----------------------------------------------------------------------------
 
 MutationEventImpl::MutationEventImpl()
Index: xml/dom2_eventsimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom2_eventsimpl.h,v
retrieving revision 1.41
diff -u -3 -p -r1.41 dom2_eventsimpl.h
--- xml/dom2_eventsimpl.h	24 Feb 2004 16:11:56 -0000	1.41
+++ xml/dom2_eventsimpl.h	13 Jul 2004 20:09:27 -0000
@@ -360,6 +360,25 @@ private:
   unsigned long    m_modifier;
 };
 
+
+// the domactivate event acts like a normal UIEvent,
+// but carries the ui event that caused it in the
+// property "getParent()".
+// parent() can be 0 for activate events generated
+// by javascript code.
+
+class DOMActivateEventImpl : public UIEventImpl
+{
+public:
+    DOMActivateEventImpl(AbstractViewImpl *viewArg,
+			 long detailArg, UIEventImpl *_parent);
+    virtual ~DOMActivateEventImpl();
+    UIEventImpl *parent() const { return m_parent; }
+ private:
+    DOMActivateEventImpl() : UIEventImpl() {}
+    UIEventImpl * m_parent;
+};
+
 class MutationEventImpl : public EventImpl {
 // ### fire these during parsing (if necessary)
 public:
Index: xml/dom_nodeimpl.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom_nodeimpl.cpp,v
retrieving revision 1.236
diff -u -3 -p -r1.236 dom_nodeimpl.cpp
--- xml/dom_nodeimpl.cpp	12 Jun 2004 15:05:03 -0000	1.236
+++ xml/dom_nodeimpl.cpp	13 Jul 2004 20:09:27 -0000
@@ -414,12 +414,13 @@ void NodeImpl::dispatchGenericEvent( Eve
         nodeChain.prepend(n);
     }
 
+    QPtrListIterator<NodeImpl> it(nodeChain);
+
     // trigger any capturing event handlers on our way down
     evt->setEventPhase(Event::CAPTURING_PHASE);
-    QPtrListIterator<NodeImpl> it(nodeChain);
     for (; it.current() && it.current() != this && !evt->propagationStopped(); ++it) \
                {
-        evt->setCurrentTarget(it.current());
-        it.current()->handleLocalEvents(evt,true);
+	evt->setCurrentTarget(it.current());
+	it.current()->handleLocalEvents(evt,true);
     }
 
     // dispatch to the actual target node
@@ -427,6 +428,9 @@ void NodeImpl::dispatchGenericEvent( Eve
     if (!evt->propagationStopped()) {
         evt->setEventPhase(Event::AT_TARGET);
         evt->setCurrentTarget(it.current());
+#ifdef EVENTS_DEBUG
+	kdDebug(6000) << "handling event at "<<it.current()->nodeName().string()<<endl;
+#endif
         it.current()->handleLocalEvents(evt, true);
         if (!evt->propagationStopped())
             it.current()->handleLocalEvents(evt,false);
@@ -449,11 +453,53 @@ void NodeImpl::dispatchGenericEvent( Eve
         evt->setEventPhase(0); // I guess this is correct, the spec does not seem to \
                say
         for (it.toLast(); it.current() && it.current() != propagationSentinel &&
                  !evt->defaultPrevented() && !evt->defaultHandled(); --it)
+	{
+#ifdef EVENTS_DEBUG
+	    kdDebug(6000) << "default event handler of \
"<<it.current()->nodeName().string()<<endl; +#endif
             it.current()->defaultEventHandler(evt);
+	}
 
-        if (evt->id() == EventImpl::CLICK_EVENT && !evt->defaultPrevented() &&
-             static_cast<MouseEventImpl*>( evt )->button() == 0) // LMB click
-            dispatchUIEvent(EventImpl::DOMACTIVATE_EVENT, \
static_cast<UIEventImpl*>(evt)->detail()); +        if (!evt->defaultPrevented()) {
+	    if (evt->id() == EventImpl::CLICK_EVENT && static_cast<MouseEventImpl*>( evt \
)->isDoubleClick() && static_cast<MouseEventImpl*>( evt )->button()==0) +	    {
+		// hyper activation event resulting from e.g. double click
+
+		DOMActivateEventImpl *ae = new DOMActivateEventImpl(getDocument()->defaultView(), \
2, static_cast<UIEventImpl*>(evt)); +		int exceptioncode = 0;
+		ae->ref();
+		dispatchEvent(ae,exceptioncode,true);
+		ae->deref();		
+	    }
+	    else if ((evt->id() == EventImpl::CLICK_EVENT && static_cast<MouseEventImpl*>( \
evt )->button() == 0) || +		     (evt->id() == EventImpl::KEYUP_EVENT && \
static_cast<TextEventImpl*>( evt )->keyVal() == ' ')) +	    {
+		// simple activation event
+
+#ifdef EVENTS_DEBUG
+		kdDebug(6000) << "generating activate event on " << nodeName().string() << endl;
+#endif
+		DOMActivateEventImpl *ae = new DOMActivateEventImpl(getDocument()->defaultView(), \
1, static_cast<UIEventImpl*>(evt)); +		
+		int exceptioncode = 0;
+		ae->ref();
+		dispatchEvent(ae,exceptioncode,true);
+		ae->deref();
+	    }
+	    else if (evt->id() == EventImpl::DOMACTIVATE_EVENT)
+	    {
+		// trigger legacy onclick & ondblclick handlers after a successful activate event
+
+#ifdef EVENTS_DEBUG
+		kdDebug(6000) << "generating CLICK event on " << nodeName().string() << endl;
+#endif
+		DOMActivateEventImpl *ae = static_cast<DOMActivateEventImpl*> ( evt );
+		if (ae->detail() == 1)
+		    dispatchHTMLEvent(EventImpl::KHTML_ECMA_CLICK_EVENT, false, true);
+		else if (ae->detail() == 2)
+		    dispatchHTMLEvent(EventImpl::KHTML_ECMA_DBLCLICK_EVENT, false, true);
+	    }
+	}
     }
 
     // copy this over into a local variable, as the following deref() calls might \
cause this to be deleted. @@ -620,23 +666,30 @@ void \
                NodeImpl::handleLocalEvents(EventIm
         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);
-            // 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 *)
+void NodeImpl::defaultEventHandler(EventImpl *evt)
 {
+    if (isSelectable() && evt->target() == this)
+    {
+        if (evt->id()==EventImpl::MOUSEDOWN_EVENT || \
evt->id()==EventImpl::KEYDOWN_EVENT) +        {
+            setActive();
+        }
+        else if (evt->id() == EventImpl::MOUSEUP_EVENT || \
evt->id()==EventImpl::KEYUP_EVENT) +        {
+	    if (m_active)
+	    {
+		setActive(false);
+		setFocus();
+	    }
+	    else {
+                setActive(false);
+            }
+        }
+	evt->setDefaultHandled();
+    }
 }
 
 unsigned long NodeImpl::childNodeCount()
Index: xml/dom_nodeimpl.h
===================================================================
RCS file: /home/kde/kdelibs/khtml/xml/dom_nodeimpl.h,v
retrieving revision 1.159
diff -u -3 -p -r1.159 dom_nodeimpl.h
--- xml/dom_nodeimpl.h	12 Jun 2004 15:05:03 -0000	1.159
+++ xml/dom_nodeimpl.h	13 Jul 2004 20:09:27 -0000
@@ -238,7 +238,7 @@ public:
     // this matches the logic in KHTMLView.
     bool dispatchKeyEvent(QKeyEvent *key, bool keypress);
 
-    void handleLocalEvents(EventImpl *evt, bool useCapture);
+    virtual void handleLocalEvents(EventImpl *evt, bool useCapture);
 
     /**
      * Perform the default action for an event e.g. submitting a form



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic