[webkit-changes] cvs commit: WebCore/khtml/xml dom_nodeimpl.cpp dom_nodeimpl.h

David hyatt at opensource.apple.com
Tue Sep 20 16:01:42 PDT 2005


hyatt       05/09/20 16:01:41

  Modified:    .        ChangeLog
               khtml/css html4.css
               khtml/html html_formimpl.cpp html_formimpl.h
                        htmltokenizer.cpp
               khtml/xml dom_nodeimpl.cpp dom_nodeimpl.h
  Log:
  	Meant to land this ages ago.  Make radio buttons work dynamically
  	when name and type change (make them pick up the correct new
  	group).
  
  	Also fix a bug in the tokenizer where trailing spaces/newlines at
  	the end of a document were getting lost.  Messed up .innerHTML
  	on DHTML sites.
  
          Reviewed by darin
  
          * khtml/css/html4.css:
          * khtml/html/html_formimpl.cpp:
          (DOM::HTMLFormElementImpl::radioButtonChecked):
          (DOM::HTMLGenericFormElementImpl::name):
          (DOM::HTMLInputElementImpl::name):
          (DOM::HTMLInputElementImpl::setInputType):
          (DOM::HTMLInputElementImpl::parseMappedAttribute):
          (DOM::HTMLInputElementImpl::attach):
          (DOM::HTMLInputElementImpl::preDispatchEventHandler):
          (DOM::HTMLInputElementImpl::postDispatchEventHandler):
          (DOM::HTMLIsIndexElementImpl::HTMLIsIndexElementImpl):
          * khtml/html/html_formimpl.h:
          * khtml/html/htmltokenizer.cpp:
          (khtml::HTMLTokenizer::finish):
          * khtml/xml/dom_nodeimpl.cpp:
          (DOM::NodeImpl::dispatchGenericEvent):
          * khtml/xml/dom_nodeimpl.h:
          (DOM::NodeImpl::preDispatchEventHandler):
          (DOM::NodeImpl::postDispatchEventHandler):
  
  Revision  Changes    Path
  1.140     +32 -0     WebCore/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/root/WebCore/ChangeLog,v
  retrieving revision 1.139
  retrieving revision 1.140
  diff -u -r1.139 -r1.140
  --- ChangeLog	20 Sep 2005 22:07:57 -0000	1.139
  +++ ChangeLog	20 Sep 2005 23:01:37 -0000	1.140
  @@ -1,3 +1,35 @@
  +2005-09-20  David Hyatt  <hyatt at apple.com>
  +
  +	Meant to land this ages ago.  Make radio buttons work dynamically
  +	when name and type change (make them pick up the correct new
  +	group).
  +
  +	Also fix a bug in the tokenizer where trailing spaces/newlines at
  +	the end of a document were getting lost.  Messed up .innerHTML
  +	on DHTML sites.
  +	
  +        Reviewed by darin
  +
  +        * khtml/css/html4.css:
  +        * khtml/html/html_formimpl.cpp:
  +        (DOM::HTMLFormElementImpl::radioButtonChecked):
  +        (DOM::HTMLGenericFormElementImpl::name):
  +        (DOM::HTMLInputElementImpl::name):
  +        (DOM::HTMLInputElementImpl::setInputType):
  +        (DOM::HTMLInputElementImpl::parseMappedAttribute):
  +        (DOM::HTMLInputElementImpl::attach):
  +        (DOM::HTMLInputElementImpl::preDispatchEventHandler):
  +        (DOM::HTMLInputElementImpl::postDispatchEventHandler):
  +        (DOM::HTMLIsIndexElementImpl::HTMLIsIndexElementImpl):
  +        * khtml/html/html_formimpl.h:
  +        * khtml/html/htmltokenizer.cpp:
  +        (khtml::HTMLTokenizer::finish):
  +        * khtml/xml/dom_nodeimpl.cpp:
  +        (DOM::NodeImpl::dispatchGenericEvent):
  +        * khtml/xml/dom_nodeimpl.h:
  +        (DOM::NodeImpl::preDispatchEventHandler):
  +        (DOM::NodeImpl::postDispatchEventHandler):
  +
   2005-09-20  Eric Seidel  <eseidel at apple.com>
   
           Reviewed by mjs.
  
  
  
  1.76      +1 -1      WebCore/khtml/css/html4.css
  
  Index: html4.css
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/css/html4.css,v
  retrieving revision 1.75
  retrieving revision 1.76
  diff -u -r1.75 -r1.76
  --- html4.css	30 Aug 2005 21:36:23 -0000	1.75
  +++ html4.css	20 Sep 2005 23:01:39 -0000	1.76
  @@ -273,7 +273,7 @@
       display: block;
       margin-left: 2px;
       margin-right: 2px;
  -    padding: 0.75em 0.625em;
  +    padding: 0.35em 0.75em 0.625em;
       border: 2px groove ThreeDFace
   }
   
  
  
  
  1.194     +88 -15    WebCore/khtml/html/html_formimpl.cpp
  
  Index: html_formimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/html_formimpl.cpp,v
  retrieving revision 1.193
  retrieving revision 1.194
  diff -u -r1.193 -r1.194
  --- html_formimpl.cpp	16 Sep 2005 22:42:11 -0000	1.193
  +++ html_formimpl.cpp	20 Sep 2005 23:01:39 -0000	1.194
  @@ -684,6 +684,10 @@
   
   void HTMLFormElementImpl::radioButtonChecked(HTMLInputElementImpl *caller)
   {
  +    // Without a name, there is no group.
  +    if (caller->name().isEmpty())
  +        return;
  +
       // Uncheck the currently selected item
       if (!m_selectedRadioButtons)
           m_selectedRadioButtons = new HashMap<DOMStringImpl*, HTMLInputElementImpl*, PointerHash<DOMStringImpl*> >;
  @@ -985,9 +989,6 @@
   
   DOMString HTMLGenericFormElementImpl::name() const
   {
  -    if (!m_overrideName.isNull())
  -        return m_overrideName;
  -
       DOMString n = getAttribute(nameAttr);
       return n.isNull() ? "" : n;
   }
  @@ -997,11 +998,6 @@
       setAttribute(nameAttr, value);
   }
   
  -void HTMLGenericFormElementImpl::setOverrideName(const DOMString& value)
  -{
  -    m_overrideName = value;
  -}
  -
   void HTMLGenericFormElementImpl::onSelect()
   {
       // ### make this work with new form events architecture
  @@ -1393,6 +1389,11 @@
       delete m_imageLoader;
   }
   
  +DOMString HTMLInputElementImpl::name() const
  +{
  +    return m_name.isNull() ? "" : m_name;
  +}
  +
   bool HTMLInputElementImpl::isKeyboardFocusable() const
   {
       // If the base class says we can't be focused, then we can stop now.
  @@ -1492,6 +1493,11 @@
               }
               if (wasAttached)
                   attach();
  +                
  +            // If our type morphs into a radio button and we are checked, then go ahead
  +            // and signal this to the form.
  +            if (m_type == RADIO && checked() && m_form)
  +                m_form->radioButtonChecked(this);
           }
       }
       m_haveType = true;
  @@ -1786,7 +1792,20 @@
   
   void HTMLInputElementImpl::parseMappedAttribute(MappedAttributeImpl *attr)
   {
  -    if (attr->name() == autocompleteAttr) {
  +    if (attr->name() == nameAttr) {
  +        if (m_type == RADIO && checked() && m_form) {
  +            // Remove the radio from its old group.
  +            if (m_form && m_type == RADIO && !m_name.isEmpty())
  +                m_form->removeRadioButtonGroup(m_name.impl());
  +        }
  +        
  +        // Update our cached reference to the name.
  +        m_name = attr->value();
  +        
  +        // Add it to its new group.
  +        if (m_type == RADIO && checked() && m_form)
  +            m_form->radioButtonChecked(this);
  +    } else if (attr->name() == autocompleteAttr) {
           m_autocomplete = strcasecmp( attr->value(), "off" );
       } else if (attr->name() ==  typeAttr) {
           setInputType(attr->value());
  @@ -1936,8 +1955,6 @@
                   setAttribute(valueAttr, nvalue);
           }
   
  -        m_defaultChecked = (!getAttribute(checkedAttr).isNull());
  -        
           m_inited = true;
       }
   
  @@ -2277,12 +2294,68 @@
       getDocument()->setFocusNode(this);
   }
   
  -void HTMLInputElementImpl::preDispatchEventHandler(EventImpl *evt)
  +void* HTMLInputElementImpl::preDispatchEventHandler(EventImpl *evt)
   {
  -    if (evt->isMouseEvent() && evt->type() == clickEvent && static_cast<MouseEventImpl*>(evt)->button() == 0) {
  -        if (m_type == CHECKBOX || m_type == RADIO)
  +    // preventDefault or "return false" are used to reverse the automatic checking/selection we do here.
  +    // This result gives us enough info to perform the "undo" in postDispatch of the action we take here.
  +    void* result = 0; 
  +    if ((m_type == CHECKBOX || m_type == RADIO) && evt->isMouseEvent() && evt->type() == clickEvent && 
  +        static_cast<MouseEventImpl*>(evt)->button() == 0) {
  +        if (m_type == CHECKBOX) {
  +            // As a way to store the boolean, we return our node pointer if we were checked and 0 if we were unchecked.
  +            if (checked()) {
  +                ref();
  +                result = this;
  +            }
               setChecked(!checked());
  +        } else {
  +            // For radio buttons, store the current selected radio object.
  +            if (name().isEmpty() || checked() || !form())
  +                return 0; // Unnamed radio buttons dont get checked. Checked buttons just stay checked.
  +                          // FIXME: Need to learn to work without a form.
  +
  +            // We really want radio groups to end up in sane states, i.e., to have something checked.
  +            // Therefore if nothing is currently selected, we won't allow this action to be "undone", since
  +            // we want some object in the radio group to actually get selected.
  +            HTMLInputElementImpl* currRadio = form()->checkedRadioButtonForGroup(name().impl());
  +            if (currRadio) {
  +                // We have a radio button selected that is not us.  Cache it in our result field and ref it so
  +                // that it can't be destroyed.
  +                currRadio->ref();
  +                result = currRadio;
  +            }
  +            setChecked(true);
  +        }
  +    }
  +    return result;
  +}
  +
  +void HTMLInputElementImpl::postDispatchEventHandler(EventImpl *evt, void* data)
  +{
  +    HTMLInputElementImpl* input = static_cast<HTMLInputElementImpl*>(data);
  +
  +    if ((m_type == CHECKBOX || m_type == RADIO) && evt->isMouseEvent() && evt->type() == clickEvent && 
  +        static_cast<MouseEventImpl*>(evt)->button() == 0) {
  +        if (m_type == CHECKBOX) {
  +            // Reverse the checking we did in preDispatch.
  +            if (evt->propagationStopped() || evt->defaultPrevented() || evt->defaultHandled())
  +                setChecked(input);
  +        } else if (input) {
  +            if (evt->propagationStopped() || evt->defaultPrevented() || evt->defaultHandled()) {
  +                // Restore the original selected radio button if possible.
  +                // Make sure it is still a radio button and only do the restoration if it still
  +                // belongs to our group.
  +                if (input->form() == form() && input->inputType() == RADIO && input->name() == name()) {
  +                    // Ok, the old radio button is still in our form and in our group and is still a 
  +                    // radio button, so it's safe to restore selection to it.
  +                    input->setChecked(true);
  +                }
  +            }
  +        }
       }
  +    
  +    if (input)
  +        input->deref();
   }
   
   void HTMLInputElementImpl::defaultEventHandler(EventImpl *evt)
  @@ -3747,7 +3820,7 @@
       : HTMLInputElementImpl(isindexTag, doc, f)
   {
       m_type = TEXT;
  -    setOverrideName("isindex");
  +    m_name = "isindex";
   }
   
   void HTMLIsIndexElementImpl::parseMappedAttribute(MappedAttributeImpl* attr)
  
  
  
  1.89      +6 -5      WebCore/khtml/html/html_formimpl.h
  
  Index: html_formimpl.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/html_formimpl.h,v
  retrieving revision 1.88
  retrieving revision 1.89
  diff -u -r1.88 -r1.89
  --- html_formimpl.h	16 Sep 2005 22:42:11 -0000	1.88
  +++ html_formimpl.h	20 Sep 2005 23:01:39 -0000	1.89
  @@ -202,11 +202,9 @@
   
       virtual void recalcStyle( StyleChange );
   
  -    DOMString name() const;
  +    virtual DOMString name() const;
       void setName(const DOMString& name);
   
  -    void setOverrideName(const DOMString& name);
  -
       virtual bool isGenericFormElement() const { return true; }
   
       /*
  @@ -232,7 +230,6 @@
   protected:
       HTMLFormElementImpl *getForm() const;
   
  -    DOMString m_overrideName;
       HTMLFormElementImpl *m_form;
       bool m_disabled : 1;
       bool m_readOnly: 1;
  @@ -343,6 +340,8 @@
       virtual bool isKeyboardFocusable() const;
       virtual bool isEnumeratable() const { return inputType() != IMAGE; }
   
  +    virtual DOMString name() const;
  +
       bool autoComplete() const { return m_autocomplete; }
   
       virtual bool isChecked() const { return checked(); }
  @@ -405,7 +404,8 @@
       int clickX() const { return xPos; }
       int clickY() const { return yPos; }
   
  -    virtual void preDispatchEventHandler(EventImpl *evt);
  +    virtual void* preDispatchEventHandler(EventImpl *evt);
  +    virtual void postDispatchEventHandler(EventImpl *evt, void* data);
       virtual void defaultEventHandler(EventImpl *evt);
       virtual bool isEditable();
   
  @@ -446,6 +446,7 @@
   protected:
       bool storesValueSeparateFromAttribute() const;
   
  +    AtomicString m_name;
       DOMString m_value;
       int       xPos;
       short     m_maxLen;
  
  
  
  1.114     +2 -0      WebCore/khtml/html/htmltokenizer.cpp
  
  Index: htmltokenizer.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/html/htmltokenizer.cpp,v
  retrieving revision 1.113
  retrieving revision 1.114
  diff -u -r1.113 -r1.114
  --- htmltokenizer.cpp	20 Sep 2005 07:46:54 -0000	1.113
  +++ htmltokenizer.cpp	20 Sep 2005 23:01:40 -0000	1.114
  @@ -1817,6 +1817,8 @@
       // this indicates we will not receive any more data... but if we are waiting on
       // an external script to load, we can't finish parsing until that is done
       noMoreData = true;
  +    if (pending) // Flush any remaining whitespace.
  +        addPending();
       if (!inWrite && !loadingExtScript && !m_executingScript && !onHold && !timerId)
           end(); // this actually causes us to be deleted
   }
  
  
  
  1.190     +5 -3      WebCore/khtml/xml/dom_nodeimpl.cpp
  
  Index: dom_nodeimpl.cpp
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_nodeimpl.cpp,v
  retrieving revision 1.189
  retrieving revision 1.190
  diff -u -r1.189 -r1.190
  --- dom_nodeimpl.cpp	16 Sep 2005 22:42:20 -0000	1.189
  +++ dom_nodeimpl.cpp	20 Sep 2005 23:01:41 -0000	1.190
  @@ -564,10 +564,9 @@
       
       QPtrListIterator<NodeImpl> it(nodeChain);
       
  -    // Before we begin dispatching events, give each node a chance to do some work prior
  +    // Before we begin dispatching events, give the target node a chance to do some work prior
       // to the DOM event handlers getting a crack.
  -    for (; it.current() && !evt->propagationStopped(); ++it)
  -        it.current()->preDispatchEventHandler(evt);
  +    void* data = preDispatchEventHandler(evt);
   
       // trigger any capturing event handlers on our way down
       evt->setEventPhase(Event::CAPTURING_PHASE);
  @@ -613,6 +612,9 @@
                              // anything about the default event handler phase.
   
   
  +    // Now call the post dispatch.
  +    postDispatchEventHandler(evt, data);
  +    
       if (evt->bubbles()) {
   	// now we call all default event handlers (this is not part of DOM - it is internal to khtml)
   
  
  
  
  1.102     +4 -2      WebCore/khtml/xml/dom_nodeimpl.h
  
  Index: dom_nodeimpl.h
  ===================================================================
  RCS file: /cvs/root/WebCore/khtml/xml/dom_nodeimpl.h,v
  retrieving revision 1.101
  retrieving revision 1.102
  diff -u -r1.101 -r1.102
  --- dom_nodeimpl.h	16 Sep 2005 22:42:20 -0000	1.101
  +++ dom_nodeimpl.h	20 Sep 2005 23:01:41 -0000	1.102
  @@ -290,8 +290,10 @@
   
       void handleLocalEvents(EventImpl *evt, bool useCapture);
   
  -    // A handler to do actions before an event is dispatched.
  -    virtual void preDispatchEventHandler(EventImpl *evt) {};
  +    // Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
  +    // has been dispatched.  The data pointer is handed back by the preDispatch and passed to postDispatch.
  +    virtual void* preDispatchEventHandler(EventImpl *evt) { return 0; }
  +    virtual void postDispatchEventHandler(EventImpl *evt, void* data) {}
   
       /**
        * Perform the default action for an event e.g. submitting a form
  
  
  



More information about the webkit-changes mailing list