[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