LayoutTests:
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2007 14:19:32 +0000 (14:19 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2007 14:19:32 +0000 (14:19 +0000)
        Reviewed by Adele.

        - test for http://bugs.webkit.org/show_bug.cgi?id=12595
          <rdar://problem/4722863> REGRESSION: Can't add item to cart at lnt.com
          (JS type error) (12595)

        * fast/forms/old-names-expected.txt: Added.
        * fast/forms/old-names.html: Added.

        - check in files that were somehow left out in the last check-in

        * fast/js/resources/js-test-pre.js: Improve the format of the failure message when
        both the real results and expected results are strings.
        * fast/dom/wrapper-classes-expected.txt: Changed back to use the new format.

WebCore:

        Reviewed by Adele.

        - fix http://bugs.webkit.org/show_bug.cgi?id=12595
          <rdar://problem/4722863> REGRESSION: Can't add item to cart at lnt.com
          (JS type error) (12595)

        Test: fast/forms/old-names.html

        * bindings/js/JSHTMLFormElementCustom.cpp:
        (WebCore::JSHTMLFormElement::canGetItemsForName): If the form collection has
        nothing for a given name, try the form's oldNamedElement function.
        (WebCore::JSHTMLFormElement::nameGetter): Ditto.

        * bindings/js/kjs_dom.h: Removed the DOMNamedNodesCollection. Instead we will use
        a class derived from NodeList.
        * bindings/js/kjs_dom.cpp: Ditto.

        * bindings/js/kjs_html.cpp:
        (KJS::VectorNodeList::VectorNodeList): Added. Constructor for a new class derived
        from NodeList to be used for the named items result from a collection -- uses a
        vector of node pointers.
        (KJS::VectorNodeList::length): Added.
        (KJS::VectorNodeList::item): Added.
        (KJS::JSHTMLCollection::getNamedItems): Use VectorNodeList and the existing wrapper
        for NodeList rather than a custom JavaScript class, DOMNamedNodesCollection.

        * dom/ChildNodeList.h:
        * dom/ChildNodeList.cpp:
        (WebCore::ChildNodeList::ChildNodeList): Updated to derive from TreeNodeList,
        since NodeList is now a simpler class.
        (WebCore::ChildNodeList::elementMatches): Updated for name and parameter change.

        * dom/NameNodeList.h:
        * dom/NameNodeList.cpp:
        (WebCore::NameNodeList::NameNodeList): Updated to derive from TreeNodeList,
        since NodeList is now a simpler class.
        (WebCore::NameNodeList::rootNodeAttributeChanged): Updated for name and
        parameter change.

        * dom/Node.h: Change register/unregister functions to take TreeNodeList.
        * dom/Node.cpp:
        (WebCore::TagNodeList::TagNodeList): Updated to derive from TreeNodeList,
        since NodeList is now a simpler abstract class.
        (WebCore::TagNodeList::elementMatches): Updated for name and parameter change.
        (WebCore::Node::registerNodeList): Changed type from NodeList to TreeNodeList.
        (WebCore::Node::unregisterNodeList): Ditto.

        * dom/NodeList.h: Broke NodeList into a simpler base class and a derived class
        with the machinery for iterating a tree, called TreeNodeList.
        * dom/NodeList.cpp:
        (WebCore::NodeList::~NodeList): Added.
        (WebCore::NodeList::itemWithName): Factored out of the old itemWithName.
        (WebCore::TreeNodeList::TreeNodeList): Renamed from NodeList.
        (WebCore::TreeNodeList::~TreeNodeList): Ditto.
        (WebCore::TreeNodeList::recursiveLength): Ditto.
        (WebCore::TreeNodeList::itemForwardsFromCurrent): Ditto.
        (WebCore::TreeNodeList::itemBackwardsFromCurrent): Ditto.
        (WebCore::TreeNodeList::recursiveItem): Ditto.
        (WebCore::TreeNodeList::itemWithName): Factored half of this into this function,
        the other half in NodeList::itemWithName.
        (WebCore::TreeNodeList::rootNodeAttributeChanged): Added. No longer inline.
        (WebCore::TreeNodeList::rootNodeChildrenChanged): Renamed from NodeList.

        * html/HTMLFormElement.h: Added formElementNameChanged and oldNamedElement
        fucntions, and a map called m_oldNames. Also removed m_boundary, which I
        thought I had already done.
        * html/HTMLFormElement.cpp:
        (WebCore::HTMLFormElement::HTMLFormElement): Initialize m_oldNames to 0.
        Switched the rest of the members to initialization syntax.
        (WebCore::HTMLFormElement::~HTMLFormElement): Delete m_oldNames.
        (WebCore::HTMLFormElement::formElementNameChanged): Added. Stores a reference
        to one element under each of its old names.
        (WebCore::HTMLFormElement::oldNamedElement): Added. Returns the old element
        that once had a given name.

        * html/HTMLGenericFormElement.h:
        * html/HTMLGenericFormElement.cpp:
        (WebCore::HTMLGenericFormElement::parseMappedAttribute): When the name
        attribute changes, tell the form about the old name.
        (WebCore::HTMLGenericFormElement::insertedIntoTree): When telling a form
        about an element, also store away the old name so that we can use it
        when the name changes later.

        * html/HTMLInputElement.cpp:
        (WebCore::HTMLInputElement::parseMappedAttribute): Added a call to the
        base class in the nameAttr case, so the code in HTMLGenericFormElement
        above will get called in the input element case.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@20148 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/wrapper-classes-expected.txt
LayoutTests/fast/forms/old-names-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/old-names.html [new file with mode: 0644]
LayoutTests/fast/js/resources/js-test-pre.js
WebCore/ChangeLog
WebCore/bindings/js/JSHTMLFormElementCustom.cpp
WebCore/bindings/js/kjs_dom.cpp
WebCore/bindings/js/kjs_dom.h
WebCore/bindings/js/kjs_html.cpp
WebCore/dom/ChildNodeList.cpp
WebCore/dom/ChildNodeList.h
WebCore/dom/NameNodeList.cpp
WebCore/dom/NameNodeList.h
WebCore/dom/Node.cpp
WebCore/dom/Node.h
WebCore/dom/NodeList.cpp
WebCore/dom/NodeList.h
WebCore/html/HTMLFormElement.cpp
WebCore/html/HTMLFormElement.h
WebCore/html/HTMLGenericFormElement.cpp
WebCore/html/HTMLGenericFormElement.h
WebCore/html/HTMLInputElement.cpp

index 62eeeaee2f0300d994382ccfadca3250717f71df..5ad3ef97b72119ed58d7a069df8bc93d304de69f 100644 (file)
@@ -1,3 +1,20 @@
+2007-03-13  Darin Adler  <darin@apple.com>
+
+        Reviewed by Adele.
+
+        - test for http://bugs.webkit.org/show_bug.cgi?id=12595
+          <rdar://problem/4722863> REGRESSION: Can't add item to cart at lnt.com
+          (JS type error) (12595)
+
+        * fast/forms/old-names-expected.txt: Added.
+        * fast/forms/old-names.html: Added.
+
+        - check in files that were somehow left out in the last check-in
+
+        * fast/js/resources/js-test-pre.js: Improve the format of the failure message when
+        both the real results and expected results are strings.
+        * fast/dom/wrapper-classes-expected.txt: Changed back to use the new format.
+
 2007-03-13  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Lars.
 
         * fast/dom/wrapper-classes-expected.txt: Added.
         * fast/dom/wrapper-classes.html: Added.
-        * fast/js/resources/js-test-pre.js: Improve the format of the failure message when
-        both the real results and expected results are strings.
 
 2007-03-12  Antti Koivisto  <antti@apple.com>
 
index 1eb217a11c3f62f9c8619e6e216a7a55d98c41eb..5be7822248924935ac0e20fd51bf7bc993c61ccf 100644 (file)
@@ -66,7 +66,7 @@ PASS jsWrapperClass(stylesheet) is 'CSSStyleSheet'
 PASS objCWrapperClass(stylesheet) is 'DOMCSSStyleSheet'
 PASS jsWrapperClass(stylesheet.cssRules) is 'CSSRuleList'
 PASS objCWrapperClass(stylesheet.cssRules) is 'DOMCSSRuleList'
-FAIL jsWrapperClass(stylesheet.cssRules.item(0)) should be CSSStyleRule (of type string). Was CSSRule (of type string).
+FAIL jsWrapperClass(stylesheet.cssRules.item(0)) should be CSSStyleRule. Was CSSRule.
 PASS objCWrapperClass(stylesheet.cssRules.item(0)) is 'DOMCSSStyleRule'
 PASS jsWrapperClass(stylesheet.cssRules.item(0).style) is 'CSSStyleDeclaration'
 PASS objCWrapperClass(stylesheet.cssRules.item(0).style) is 'DOMCSSStyleDeclaration'
diff --git a/LayoutTests/fast/forms/old-names-expected.txt b/LayoutTests/fast/forms/old-names-expected.txt
new file mode 100644 (file)
index 0000000..72a6008
--- /dev/null
@@ -0,0 +1,77 @@
+This tests accessing form elements by name. IE only lets you look up names under the first name the element had and does not respond to name changes. Firefox will let each element be looked up under its original name as long as no actual element has that name. This test has been written to expect the Firefox behavior. This original name quirk applies only to the syntax form.name and not to the form.elements collection.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS form.length is 2
+PASS form.original is a
+PASS form.originalB is b
+PASS form.second is undefined
+PASS form.third is undefined
+PASS form.elements.original is a
+PASS form.elements.originalB is b
+PASS form.elements.second is undefined
+PASS form.elements.third is undefined
+
+now change the form item a's name to second
+
+PASS form.length is 2
+PASS form.original is a
+PASS form.originalB is b
+PASS form.second is a
+PASS form.third is undefined
+PASS form.elements.original is undefined
+PASS form.elements.originalB is b
+PASS form.elements.second is a
+PASS form.elements.third is undefined
+
+now change the form item a's name to third
+
+PASS form.length is 2
+PASS form.original is a
+PASS form.originalB is b
+PASS form.second is a
+PASS form.third is a
+PASS form.elements.original is undefined
+PASS form.elements.originalB is b
+PASS form.elements.second is undefined
+PASS form.elements.third is a
+
+now change form item b's name to second
+
+PASS form.length is 2
+PASS form.original is a
+PASS form.originalB is b
+PASS form.second is b
+PASS form.elements.original is undefined
+PASS form.elements.originalB is undefined
+PASS form.elements.second is b
+
+now change a form item b's name to third
+
+PASS form.length is 2
+PASS form.original is a
+PASS form.originalB is b
+PASS form.second is b
+PASS form.third.length is 2
+PASS form.third.item(0) is a
+PASS form.third.item(1) is b
+PASS form.elements.original is undefined
+PASS form.elements.originalB is undefined
+PASS form.elements.second is undefined
+PASS form.elements.third.length is 2
+PASS form.elements.third.item(0) is a
+PASS form.elements.third.item(1) is b
+
+now remove element a
+
+PASS form.length is 1
+PASS form.original is a
+PASS form.originalB is b
+PASS form.second is b
+PASS form.third is b
+PASS form.elements.original is undefined
+PASS form.elements.originalB is undefined
+PASS form.elements.second is undefined
+PASS form.elements.third is b
+
diff --git a/LayoutTests/fast/forms/old-names.html b/LayoutTests/fast/forms/old-names.html
new file mode 100644 (file)
index 0000000..e8a7c0b
--- /dev/null
@@ -0,0 +1,122 @@
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+function runTest()
+{
+    description("This tests accessing form elements by name. "
+        + "IE only lets you look up names under the first name the element had and "
+        + "does not respond to name changes. Firefox will let each element be looked "
+        + "up under its original name as long as no actual element has that name. "
+        + "This test has been written to expect the Firefox behavior. "
+        + "This original name quirk applies only to the syntax form.name and not to "
+        + "the form.elements collection.");
+
+    form = document.getElementById('form');
+    a = document.getElementById('a');
+    b = document.getElementById('b');
+
+    shouldBe('form.length', '2');
+    shouldBe('form.original', 'a');
+    shouldBe('form.originalB', 'b');
+    shouldBe('form.second', 'undefined');
+    shouldBe('form.third', 'undefined');
+    shouldBe('form.elements.original', 'a');
+    shouldBe('form.elements.originalB', 'b');
+    shouldBe('form.elements.second', 'undefined');
+    shouldBe('form.elements.third', 'undefined');
+
+    debug('');
+    debug("now change the form item a's name to second");
+    debug('');
+
+    a.name="second";
+
+    shouldBe('form.length', '2');
+    shouldBe('form.original', 'a');
+    shouldBe('form.originalB', 'b');
+    shouldBe('form.second', 'a');
+    shouldBe('form.third', 'undefined');
+    shouldBe('form.elements.original', 'undefined');
+    shouldBe('form.elements.originalB', 'b');
+    shouldBe('form.elements.second', 'a');
+    shouldBe('form.elements.third', 'undefined');
+
+    debug('');
+    debug("now change the form item a's name to third");
+    debug('');
+
+    a.name="third";
+
+    shouldBe('form.length', '2');
+    shouldBe('form.original', 'a');
+    shouldBe('form.originalB', 'b');
+    shouldBe('form.second', 'a');
+    shouldBe('form.third', 'a');
+    shouldBe('form.elements.original', 'undefined');
+    shouldBe('form.elements.originalB', 'b');
+    shouldBe('form.elements.second', 'undefined');
+    shouldBe('form.elements.third', 'a');
+
+    debug('');
+    debug("now change form item b's name to second");
+    debug('');
+
+    b.name="second";
+
+    shouldBe('form.length', '2');
+    shouldBe('form.original', 'a');
+    shouldBe('form.originalB', 'b');
+    shouldBe('form.second', 'b');
+    shouldBe('form.elements.original', 'undefined');
+    shouldBe('form.elements.originalB', 'undefined');
+    shouldBe('form.elements.second', 'b');
+
+    debug('');
+    debug("now change a form item b's name to third");
+    debug('');
+
+    form.originalB.name="third";
+
+    shouldBe('form.length', '2');
+    shouldBe('form.original', 'a');
+    shouldBe('form.originalB', 'b');
+    shouldBe('form.second', 'b');
+    shouldBe('form.third.length', '2');
+    shouldBe('form.third.item(0)', 'a');
+    shouldBe('form.third.item(1)', 'b');
+    shouldBe('form.elements.original', 'undefined');
+    shouldBe('form.elements.originalB', 'undefined');
+    shouldBe('form.elements.second', 'undefined');
+    shouldBe('form.elements.third.length', '2');
+    shouldBe('form.elements.third.item(0)', 'a');
+    shouldBe('form.elements.third.item(1)', 'b');
+
+    debug('');
+    debug("now remove element a");
+    debug('');
+
+    form.removeChild(a);
+
+    shouldBe('form.length', '1');
+    shouldBe('form.original', 'a');
+    shouldBe('form.originalB', 'b');
+    shouldBe('form.second', 'b');
+    shouldBe('form.third', 'b');
+    shouldBe('form.elements.original', 'undefined');
+    shouldBe('form.elements.originalB', 'undefined');
+    shouldBe('form.elements.second', 'undefined');
+    shouldBe('form.elements.third', 'b');
+}
+</script>
+</head>
+<body onload="runTest()">
+<form id='form'>
+<input type='hidden' id='a' name='original'>
+<input type='hidden' id='b' name='originalB'>
+</form>
+<p id="description"></p>
+<div id="console"></div>
+</body>
+</html>
index e12ecbc4838b4d908a7808090830d3f89cb8f39a..e94ee0beda4f2028f4ff0f3246da69f67cee0b55 100644 (file)
@@ -52,10 +52,10 @@ function shouldBe(_a, _b)
     testFailed(_a + " should be " + _bv + ". Threw exception " + exception);
   else if (_av === _bv || (typeof(_av) == "number" && typeof(_bv) == "number" && isNaN(_av) && isNaN(_bv)))
     testPassed(_a + " is " + _b);
-  else {
-    testFailed(_a + " should be " + _bv + " (of type " + typeof _bv 
-               + "). Was " + _av + " (of type " + typeof _av + ").");
-  }
+  else if (typeof(_av) == "string" && typeof(_bv) == "string")
+    testFailed(_a + " should be " + _bv + ". Was " + _av + ".");
+  else
+    testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ").");
 }
 
 function shouldBeTrue(_a) { shouldBe(_a, "true"); }
index ae858aba3489b31c1c8927550bd2a494354e2668..8b6f0e086d5eb7574375b640ea31412a346ce0f5 100644 (file)
@@ -1,3 +1,93 @@
+2007-03-13  Darin Adler  <darin@apple.com>
+
+        Reviewed by Adele.
+
+        - fix http://bugs.webkit.org/show_bug.cgi?id=12595
+          <rdar://problem/4722863> REGRESSION: Can't add item to cart at lnt.com
+          (JS type error) (12595)
+
+        Test: fast/forms/old-names.html
+
+        * bindings/js/JSHTMLFormElementCustom.cpp:
+        (WebCore::JSHTMLFormElement::canGetItemsForName): If the form collection has
+        nothing for a given name, try the form's oldNamedElement function.
+        (WebCore::JSHTMLFormElement::nameGetter): Ditto.
+
+        * bindings/js/kjs_dom.h: Removed the DOMNamedNodesCollection. Instead we will use
+        a class derived from NodeList.
+        * bindings/js/kjs_dom.cpp: Ditto.
+
+        * bindings/js/kjs_html.cpp:
+        (KJS::VectorNodeList::VectorNodeList): Added. Constructor for a new class derived
+        from NodeList to be used for the named items result from a collection -- uses a
+        vector of node pointers.
+        (KJS::VectorNodeList::length): Added.
+        (KJS::VectorNodeList::item): Added.
+        (KJS::JSHTMLCollection::getNamedItems): Use VectorNodeList and the existing wrapper
+        for NodeList rather than a custom JavaScript class, DOMNamedNodesCollection.
+
+        * dom/ChildNodeList.h:
+        * dom/ChildNodeList.cpp:
+        (WebCore::ChildNodeList::ChildNodeList): Updated to derive from TreeNodeList,
+        since NodeList is now a simpler class.
+        (WebCore::ChildNodeList::elementMatches): Updated for name and parameter change.
+
+        * dom/NameNodeList.h:
+        * dom/NameNodeList.cpp:
+        (WebCore::NameNodeList::NameNodeList): Updated to derive from TreeNodeList,
+        since NodeList is now a simpler class.
+        (WebCore::NameNodeList::rootNodeAttributeChanged): Updated for name and
+        parameter change.
+
+        * dom/Node.h: Change register/unregister functions to take TreeNodeList.
+        * dom/Node.cpp:
+        (WebCore::TagNodeList::TagNodeList): Updated to derive from TreeNodeList,
+        since NodeList is now a simpler abstract class.
+        (WebCore::TagNodeList::elementMatches): Updated for name and parameter change.
+        (WebCore::Node::registerNodeList): Changed type from NodeList to TreeNodeList.
+        (WebCore::Node::unregisterNodeList): Ditto.
+
+        * dom/NodeList.h: Broke NodeList into a simpler base class and a derived class
+        with the machinery for iterating a tree, called TreeNodeList.
+        * dom/NodeList.cpp:
+        (WebCore::NodeList::~NodeList): Added.
+        (WebCore::NodeList::itemWithName): Factored out of the old itemWithName.
+        (WebCore::TreeNodeList::TreeNodeList): Renamed from NodeList.
+        (WebCore::TreeNodeList::~TreeNodeList): Ditto.
+        (WebCore::TreeNodeList::recursiveLength): Ditto.
+        (WebCore::TreeNodeList::itemForwardsFromCurrent): Ditto.
+        (WebCore::TreeNodeList::itemBackwardsFromCurrent): Ditto.
+        (WebCore::TreeNodeList::recursiveItem): Ditto.
+        (WebCore::TreeNodeList::itemWithName): Factored half of this into this function,
+        the other half in NodeList::itemWithName.
+        (WebCore::TreeNodeList::rootNodeAttributeChanged): Added. No longer inline.
+        (WebCore::TreeNodeList::rootNodeChildrenChanged): Renamed from NodeList.
+
+        * html/HTMLFormElement.h: Added formElementNameChanged and oldNamedElement
+        fucntions, and a map called m_oldNames. Also removed m_boundary, which I
+        thought I had already done.
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::HTMLFormElement): Initialize m_oldNames to 0.
+        Switched the rest of the members to initialization syntax.
+        (WebCore::HTMLFormElement::~HTMLFormElement): Delete m_oldNames.
+        (WebCore::HTMLFormElement::formElementNameChanged): Added. Stores a reference
+        to one element under each of its old names.
+        (WebCore::HTMLFormElement::oldNamedElement): Added. Returns the old element
+        that once had a given name.
+
+        * html/HTMLGenericFormElement.h:
+        * html/HTMLGenericFormElement.cpp:
+        (WebCore::HTMLGenericFormElement::parseMappedAttribute): When the name
+        attribute changes, tell the form about the old name.
+        (WebCore::HTMLGenericFormElement::insertedIntoTree): When telling a form
+        about an element, also store away the old name so that we can use it
+        when the name changes later.
+
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::parseMappedAttribute): Added a call to the
+        base class in the nameAttr case, so the code in HTMLGenericFormElement
+        above will get called in the input element case.
+
 2007-03-13  Antti Koivisto  <antti@apple.com>
 
         Reviewed by Alexey.
index 51df9456070ea24da6dc583beb5f29df0bb19745..d0922a0c1a51a8f12cfb2b9781e2abf2e98a8acb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,9 @@
 #include "config.h"
 #include "JSHTMLFormElement.h"
 
-#include "HTMLFormElement.h"
 #include "HTMLCollection.h"
+#include "HTMLGenericFormElement.h"
+#include "HTMLFormElement.h"
 
 using namespace KJS;
 
@@ -35,17 +36,18 @@ namespace WebCore {
 
 bool JSHTMLFormElement::canGetItemsForName(ExecState* exec, HTMLFormElement* form, const AtomicString& propertyName)
 {
-    // FIXME: ideally there should be a lighter-weight way of doing this
-    JSValue* namedItems = JSHTMLCollection(exec, form->elements().get()).getNamedItems(exec, propertyName);
-    return !namedItems->isUndefined();
+    if (!JSHTMLCollection(exec, form->elements().get()).getNamedItems(exec, propertyName)->isUndefined())
+        return true;
+    return !!form->oldNamedElement(propertyName);
 }
 
 JSValue* JSHTMLFormElement::nameGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
 {
-    JSHTMLElement* thisObj = static_cast<JSHTMLElement*>(slot.slotBase());
-    HTMLFormElement* form = static_cast<HTMLFormElement*>(thisObj->impl());
-    
-    return JSHTMLCollection(exec, form->elements().get()).getNamedItems(exec, propertyName);
+    HTMLFormElement* form = static_cast<HTMLFormElement*>(static_cast<JSHTMLElement*>(slot.slotBase())->impl());
+    JSValue* items = JSHTMLCollection(exec, form->elements().get()).getNamedItems(exec, propertyName);
+    if (!items->isUndefined())
+        return items;
+    return toJS(exec, form->oldNamedElement(propertyName));
 }
 
 }
index 81038fd90e92c57c01584a9402b9cbcd41f29a2d..df6e8b45addf9935ad880ed05819ced88f6b1d59 100644 (file)
@@ -1121,59 +1121,4 @@ JSObject* getDOMExceptionConstructor(ExecState* exec)
   return cacheGlobalObject<DOMExceptionConstructor>(exec, "[[DOMException.constructor]]");
 }
 
-// -------------------------------------------------------------------------
-
-const ClassInfo DOMNamedNodesCollection::info = { "Collection", 0, 0, 0 };
-
-// Such a collection is usually very short-lived, it only exists
-// for constructs like document.forms.<name>[1],
-// so it shouldn't be a problem that it's storing all the nodes (with the same name). (David)
-DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState* exec, const Vector<RefPtr<Node> >& nodes)
-  : m_nodes(nodes)
-{
-    setPrototype(exec->lexicalInterpreter()->builtinObjectPrototype());
-}
-
-JSValue* DOMNamedNodesCollection::lengthGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot)
-{
-  DOMNamedNodesCollection *thisObj = static_cast<DOMNamedNodesCollection*>(slot.slotBase());
-  return jsNumber(thisObj->m_nodes.size());
-}
-
-JSValue* DOMNamedNodesCollection::indexGetter(ExecState* exec, JSObject* originalObject, const Identifier& propertyName, const PropertySlot& slot)
-{
-  DOMNamedNodesCollection *thisObj = static_cast<DOMNamedNodesCollection*>(slot.slotBase());
-  return toJS(exec, thisObj->m_nodes[slot.index()].get());
-}
-
-bool DOMNamedNodesCollection::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
-  if (propertyName == lengthPropertyName) {
-    slot.setCustom(this, lengthGetter);
-    return true;
-  }
-
-  // array index ?
-  bool ok;
-  unsigned idx = propertyName.toUInt32(&ok);
-  if (ok && idx < m_nodes.size()) {
-    slot.setCustomIndex(this, idx, indexGetter);
-    return true;
-  }
-
-  // For IE compatibility, we need to be able to look up elements in a
-  // document.formName.name result by id as well as be index.
-
-  AtomicString atomicPropertyName = propertyName;
-  for (unsigned i = 0; i < m_nodes.size(); i++) {
-    Node* node = m_nodes[i].get();
-    if (node->hasAttributes() && node->attributes()->id() == atomicPropertyName) {
-      slot.setCustomIndex(this, i, indexGetter);
-      return true;
-    }
-  }
-
-  return DOMObject::getOwnPropertySlot(exec, propertyName, slot);
-}
-
 } // namespace
index c57c96ec14c53686e80ca35b044ff15ecf4a397a..7fb1b1c0d3c44527e06183cbb4409165016ff1d2 100644 (file)
@@ -142,21 +142,6 @@ namespace KJS {
   JSObject* getNodeConstructor(ExecState*);
   JSObject* getDOMExceptionConstructor(ExecState*);
 
-  // Internal class, used for the collection return by e.g. document.forms.myinput
-  // when multiple nodes have the same name.
-  class DOMNamedNodesCollection : public DOMObject {
-  public:
-    DOMNamedNodesCollection(ExecState *exec, const Vector<RefPtr<WebCore::Node> >& nodes);
-    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
-    virtual const ClassInfo* classInfo() const { return &info; }
-    static const ClassInfo info;
-private:
-    static JSValue *lengthGetter(ExecState* exec, JSObject *, const Identifier&, const PropertySlot& slot);
-    static JSValue *indexGetter(ExecState* exec, JSObject *, const Identifier&, const PropertySlot& slot);
-
-    Vector<RefPtr<WebCore::Node> > m_nodes;
-  };
-
 } // namespace
 
 #endif
index 7bf88a2ca2285688b9c349295da132a5e725ea8e..56ab4753fb8a09beb58300fa7d0979c271db121e 100644 (file)
@@ -1,8 +1,7 @@
 // -*- c-basic-offset: 4 -*-
 /*
- *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *  Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -69,6 +68,17 @@ using namespace EventNames;
 
 namespace KJS {
 
+class VectorNodeList : public NodeList {
+public:
+    VectorNodeList(const Vector<RefPtr<Node> >& nodes) : m_nodes(nodes) { }
+
+    virtual unsigned length() const { return m_nodes.size(); }
+    virtual Node* item(unsigned index) const { return index < m_nodes.size() ? m_nodes[index].get() : 0; }
+
+private:
+    Vector<RefPtr<Node> > m_nodes;
+};
+
 class HTMLElementFunction : public InternalFunctionImp {
 public:
   HTMLElementFunction(ExecState* exec, int i, int len, const Identifier& name);
@@ -1550,7 +1560,7 @@ JSValue *JSHTMLCollection::getNamedItems(ExecState* exec, const Identifier &prop
     if (namedItems.size() == 1)
         return toJS(exec, namedItems[0].get());
 
-    return new DOMNamedNodesCollection(exec, namedItems);
+    return toJS(exec, new VectorNodeList(namedItems));
 }
 
 JSValue* JSHTMLCollectionPrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const List &args)
index 604eb998a1d0b7ce4e5e91f5425488f66ee6dfe2..3f94aaf30373676d2616003ba6b83d231ec9fb33 100644 (file)
 
 #include "config.h"
 #include "ChildNodeList.h"
-#include "Node.h"
+
+#include "Element.h"
 
 using namespace WebCore;
 
 namespace WebCore {
 
-ChildNodeList::ChildNodeList( Node *n )
-    : NodeList(n)
+ChildNodeList::ChildNodeList(Node* n)
+    : TreeNodeList(n)
 {
 }
 
@@ -41,8 +42,7 @@ unsigned ChildNodeList::length() const
         return cachedLength;
 
     unsigned len = 0;
-    Node *n;
-    for(n = rootNode->firstChild(); n != 0; n = n->nextSibling())
+    for (Node* n = rootNode->firstChild(); n; n = n->nextSibling())
         len++;
 
     cachedLength = len;
@@ -51,10 +51,10 @@ unsigned ChildNodeList::length() const
     return len;
 }
 
-Node *ChildNodeList::item ( unsigned index ) const
+Node *ChildNodeList::item(unsigned index) const
 {
     unsigned int pos = 0;
-    Node *n = rootNode->firstChild();
+    Noden = rootNode->firstChild();
 
     if (isItemCacheValid) {
         if (index == lastItemOffset) {
@@ -80,9 +80,9 @@ Node *ChildNodeList::item ( unsigned index ) const
     return 0;
 }
 
-bool ChildNodeList::nodeMatches(Node *testNode) const
+bool ChildNodeList::elementMatches(Element* element) const
 {
-    return testNode->parentNode() == rootNode;
+    return element->parentNode() == rootNode;
 }
 
 }
index 56aa44740a587b3999d4dba5d55867bde9b5f63a..61d99a5344a028e66d18e02478a4e38a6386d089 100644 (file)
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-class ChildNodeList : public NodeList {
+class ChildNodeList : public TreeNodeList {
 public:
     ChildNodeList(Node*);
 
@@ -37,7 +37,7 @@ public:
     virtual Node* item(unsigned index) const;
 
 protected:
-    virtual bool nodeMatches(Node* testNode) const;
+    virtual bool elementMatches(Element*) const;
 };
 
 } // namespace WebCore
index ec4718fa188c79ab51b4d656cb198dca1042ffb6..4c4da826476dc58bebf3d67b9a5b6777aef2dec2 100644 (file)
 #include "Element.h"
 #include "HTMLNames.h"
 
-using namespace WebCore;
-
 namespace WebCore {
 
 using namespace HTMLNames;
 
-NameNodeList::NameNodeList(Node *n, const String &t)
-  : NodeList(n), nodeName(t)
+NameNodeList::NameNodeList(Node* n, const String &t)
+    : TreeNodeList(n)
+    , nodeName(t)
 {
 }
 
@@ -44,14 +43,14 @@ unsigned NameNodeList::length() const
     return recursiveLength();
 }
 
-Node *NameNodeList::item (unsigned index) const
+Node *NameNodeList::item(unsigned index) const
 {
     return recursiveItem(index);
 }
 
-bool NameNodeList::nodeMatches(Node *testNode) const
+bool NameNodeList::elementMatches(Element* element) const
 {
-    return static_cast<Element*>(testNode)->getAttribute(nameAttr) == nodeName;
+    return element->getAttribute(nameAttr) == nodeName;
 }
 
 }
index ff2676f8cefa58657624a37d31b31f6b563e8c72..97a845d23e247510dc0c671a067942b43095642f 100644 (file)
@@ -33,7 +33,7 @@ namespace WebCore {
 /**
  * NodeList which lists all Nodes in a Element with a given "name=" tag
  */
-class NameNodeList : public NodeList {
+class NameNodeList : public TreeNodeList {
 public:
     NameNodeList(Node* doc, const String& name);
 
@@ -44,10 +44,10 @@ public:
 
     // Other methods (not part of DOM)
     virtual void rootNodeChildrenChanged() { }
-    virtual void rootNodeAttributeChanged() { NodeList::rootNodeChildrenChanged(); }
+    virtual void rootNodeAttributeChanged() { TreeNodeList::rootNodeChildrenChanged(); }
 
 protected:
-    virtual bool nodeMatches(Node* testNode) const;
+    virtual bool elementMatches(Element*) const;
 
     String nodeName;
 };
index 74403a66f16e800360f30429a64513e621e5eb3c..b42bbf4c19fb35fd8c83232aba9b3f9a6649089a 100644 (file)
@@ -50,26 +50,22 @@ using namespace HTMLNames;
 /**
  * NodeList which lists all Nodes in a document with a given tag name
  */
-class TagNodeList : public NodeList
-{
+class TagNodeList : public TreeNodeList {
 public:
-    TagNodeList(Node *n, const AtomicString& namespaceURI, const AtomicString& localName);
+    TagNodeList(Node*, const AtomicString& namespaceURI, const AtomicString& localName);
 
-    // DOM methods overridden from  parent classes
     virtual unsigned length() const;
-    virtual Node *item (unsigned index) const;
-
-    // Other methods (not part of DOM)
+    virtual Node *item(unsigned index) const;
 
 protected:
-    virtual bool nodeMatches(Node *testNode) const;
+    virtual bool elementMatches(Element*) const;
 
     AtomicString m_namespaceURI;
     AtomicString m_localName;
 };
 
 TagNodeList::TagNodeList(Node *n, const AtomicString& namespaceURI, const AtomicString& localName)
-    : NodeList(n), 
+    : TreeNodeList(n), 
       m_namespaceURI(namespaceURI), 
       m_localName(localName)
 {
@@ -85,11 +81,8 @@ Node *TagNodeList::item(unsigned index) const
     return recursiveItem(index);
 }
 
-bool TagNodeList::nodeMatches(Node *testNode) const
+bool TagNodeList::elementMatches(Element* testNode) const
 {
-    if (!testNode->isElementNode())
-        return false;
-
     if (m_namespaceURI != starAtom && m_namespaceURI != testNode->namespaceURI())
         return false;
     
@@ -427,14 +420,14 @@ unsigned Node::nodeIndex() const
     return count;
 }
 
-void Node::registerNodeList(NodeList* list)
+void Node::registerNodeList(TreeNodeList* list)
 {
     if (!m_nodeLists)
         m_nodeLists = new NodeListSet;
     m_nodeLists->add(list);
 }
 
-void Node::unregisterNodeList(NodeList* list)
+void Node::unregisterNodeList(TreeNodeList* list)
 {
     if (!m_nodeLists)
         return;
index 3dfaee42e36b1c5484e1fe05b9a4f76a61e43864..873c67067e522b50ce3cb77e66819ac16eb625ee 100644 (file)
@@ -54,6 +54,7 @@ class RenderArena;
 class RenderObject;
 class RenderStyle;
 class TextStream;
+class TreeNodeList;
 
 typedef int ExceptionCode;
 
@@ -439,8 +440,8 @@ public:
     void showTreeAndMark(const Node* markedNode1, const char* markedLabel1, const Node* markedNode2 = 0, const char* markedLabel2 = 0) const;
 #endif
 
-    void registerNodeList(NodeList*);
-    void unregisterNodeList(NodeList*);
+    void registerNodeList(TreeNodeList*);
+    void unregisterNodeList(TreeNodeList*);
     void notifyNodeListsChildrenChanged();
     void notifyLocalNodeListsChildrenChanged();
     void notifyNodeListsAttributeChanged();
@@ -456,7 +457,7 @@ private: // members
     RenderObject* m_renderer;
 
 protected:
-    typedef HashSet<NodeList*> NodeListSet;
+    typedef HashSet<TreeNodeList*> NodeListSet;
     NodeListSet* m_nodeLists;
 
     short m_tabIndex;
index 2191dfd5c39bf492ee42df249ed02abef996f5e5..b0330ebe13abab7e46c5ad6388a43222a95db2bf 100644 (file)
@@ -1,10 +1,8 @@
 /**
- * This file is part of the DOM implementation for KDE.
- *
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 
 namespace WebCore {
 
-NodeList::NodeList(PassRefPtr<Node> _rootNode)
+NodeList::~NodeList()
+{
+}
+
+Node* NodeList::itemWithName(const AtomicString& name) const
+{
+    unsigned l = length();
+    for (unsigned i = 0; i < l; i++) {
+        Node* node = item(i);
+        if (node->isElementNode() && static_cast<Element*>(node)->getIDAttribute() == name)
+            return node;
+    }
+    return 0;
+}
+
+TreeNodeList::TreeNodeList(PassRefPtr<Node> _rootNode)
     : rootNode(_rootNode),
       isLengthCacheValid(false),
       isItemCacheValid(false)
@@ -38,12 +51,12 @@ NodeList::NodeList(PassRefPtr<Node> _rootNode)
     rootNode->registerNodeList(this);
 }    
 
-NodeList::~NodeList()
+TreeNodeList::~TreeNodeList()
 {
     rootNode->unregisterNodeList(this);
 }
 
-unsigned NodeList::recursiveLength(Node* start) const
+unsigned TreeNodeList::recursiveLength(Node* start) const
 {
     if (!start)
         start = rootNode.get();
@@ -55,8 +68,7 @@ unsigned NodeList::recursiveLength(Node* start) const
 
     for (Node* n = start->firstChild(); n; n = n->nextSibling())
         if (n->isElementNode()) {
-            if (nodeMatches(n))
-                len++;
+            len += elementMatches(static_cast<Element*>(n));
             len += recursiveLength(n);
         }
 
@@ -68,13 +80,13 @@ unsigned NodeList::recursiveLength(Node* start) const
     return len;
 }
 
-Node* NodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
+Node* TreeNodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
 {
     ASSERT(remainingOffset >= 0);
 
     for (Node *n = start; n; n = n->traverseNextNode(rootNode.get())) {
         if (n->isElementNode()) {
-            if (nodeMatches(n)) {
+            if (elementMatches(static_cast<Element*>(n))) {
                 if (!remainingOffset) {
                     lastItem = n;
                     lastItemOffset = offset;
@@ -89,12 +101,12 @@ Node* NodeList::itemForwardsFromCurrent(Node* start, unsigned offset, int remain
     return 0; // no matching node in this subtree
 }
 
-Node* NodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
+Node* TreeNodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, int remainingOffset) const
 {
     ASSERT(remainingOffset < 0);
     for (Node *n = start; n; n = n->traversePreviousNode(rootNode.get())) {
         if (n->isElementNode()) {
-            if (nodeMatches(n)) {
+            if (elementMatches(static_cast<Element*>(n))) {
                 if (!remainingOffset) {
                     lastItem = n;
                     lastItemOffset = offset;
@@ -109,7 +121,7 @@ Node* NodeList::itemBackwardsFromCurrent(Node* start, unsigned offset, int remai
     return 0; // no matching node in this subtree
 }
 
-Node* NodeList::recursiveItem(unsigned offset, Node* start) const
+Node* TreeNodeList::recursiveItem(unsigned offset, Node* start) const
 {
     int remainingOffset = offset;
     if (!start) {
@@ -130,12 +142,11 @@ Node* NodeList::recursiveItem(unsigned offset, Node* start) const
         return itemForwardsFromCurrent(start, offset, remainingOffset);
 }
 
-Node* NodeList::itemWithName(const AtomicString& elementId) const
+Node* TreeNodeList::itemWithName(const AtomicString& name) const
 {
     if (rootNode->isDocumentNode() || rootNode->inDocument()) {
-        Node* node = rootNode->document()->getElementById(elementId);
-
-        if (!node || !nodeMatches(node))
+        Element* node = rootNode->document()->getElementById(name);
+        if (!node || !elementMatches(node))
             return 0;
 
         for (Node* p = node->parentNode(); p; p = p->parentNode())
@@ -145,17 +156,14 @@ Node* NodeList::itemWithName(const AtomicString& elementId) const
         return 0;
     }
 
-    unsigned l = length();
-    for (unsigned i = 0; i < l; i++) {
-        Node* node = item(i);
-        if (node->isElementNode() && static_cast<Element*>(node)->getIDAttribute() == elementId)
-            return node;
-    }
+    return NodeList::itemWithName(name);
+}
 
-    return 0;
+void TreeNodeList::rootNodeAttributeChanged()
+{
 }
 
-void NodeList::rootNodeChildrenChanged()
+void TreeNodeList::rootNodeChildrenChanged()
 {
     isLengthCacheValid = false;
     isItemCacheValid = false;     
index 6c031e2cb2ffa2ebc47a0a5f7f569e9a47b3cd7d..55eb3169953e506db9b044d1390531f610f00985 100644 (file)
@@ -1,10 +1,8 @@
 /*
- * This file is part of the DOM implementation for KDE.
- *
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
 namespace WebCore {
 
 class AtomicString;
+class Element;
 class Node;
 
 class NodeList : public Shared<NodeList> {
 public:
-    NodeList(PassRefPtr<Node> rootNode);
     virtual ~NodeList();
 
-    // DOM methods & attributes for NodeList
     virtual unsigned length() const = 0;
     virtual Node* item(unsigned index) const = 0;
-    Node* itemWithName(const AtomicString&) const;
+    virtual Node* itemWithName(const AtomicString&) const;
+};
+
+// FIXME: Move this to its own source file.
+class TreeNodeList : public NodeList {
+public:
+    TreeNodeList(PassRefPtr<Node> rootNode);
+    virtual ~TreeNodeList();
+
+    virtual Node* itemWithName(const AtomicString&) const;
 
-    // Other methods (not part of DOM)
     virtual void rootNodeChildrenChanged();
-    virtual void rootNodeAttributeChanged() {}
+    virtual void rootNodeAttributeChanged();
 
 protected:
-    // helper functions for searching all ElementImpls in a tree
+    // helper functions for searching all elements in a tree
     unsigned recursiveLength(Node* start = 0) const;
-    Node* recursiveItem (unsigned offset, Node* start = 0) const;
-    virtual bool nodeMatches(Node* testNode) const = 0;
+    Node* recursiveItem(unsigned offset, Node* start = 0) const;
+    virtual bool elementMatches(Element*) const = 0;
 
     RefPtr<Node> rootNode;
     mutable int cachedLength;
index 7396cf4db3015e33c4d2d80d7aa22ecdab7a308e..43fcaa83b6424f72da142ec2a9b4b0f21883a507 100644 (file)
@@ -49,21 +49,23 @@ using namespace HTMLNames;
 
 HTMLFormElement::HTMLFormElement(Document* doc)
     : HTMLElement(formTag, doc)
+    , m_oldNames(0)
+    , collectionInfo(0)
+    , m_enctype("application/x-www-form-urlencoded")
+    , m_post(false)
+    , m_multipart(false)
+    , m_autocomplete(false)
+    , m_insubmit(false)
+    , m_doingsubmit(false)
+    , m_inreset(false)
+    , m_malformed(false)
+    , m_preserveAcrossRemove(false)
 {
-    collectionInfo = 0;
-    m_post = false;
-    m_multipart = false;
-    m_autocomplete = true;
-    m_insubmit = false;
-    m_doingsubmit = false;
-    m_inreset = false;
-    m_enctype = "application/x-www-form-urlencoded";
-    m_malformed = false;
-    m_preserveAcrossRemove = false;
 }
 
 HTMLFormElement::~HTMLFormElement()
 {
+    delete m_oldNames;
     delete collectionInfo;
     
     for (unsigned i = 0; i < formElements.size(); ++i)
@@ -272,19 +274,19 @@ PassRefPtr<FormData> HTMLFormElement::formData(const char* boundary) const
                     // include the filename
                     if (current->hasLocalName(inputTag) &&
                         static_cast<HTMLInputElement*>(current)->inputType() == HTMLInputElement::FILE) {
-                        String path = static_cast<HTMLInputElement*>(current)->value();
+                        const AtomicString& path = static_cast<HTMLInputElement*>(current)->value();
 
                         // FIXME: This won't work if the filename includes a " mark,
                         // or control characters like CR or LF. This also does strange
                         // things if the filename includes characters you can't encode
                         // in the website's character set.
                         hstr += "; filename=\"";
-                        int start = path.reverseFind('/') + 1;
+                        int start = path.domString().reverseFind('/') + 1;
                         int length = path.length() - start;
                         hstr += encoding.encode(reinterpret_cast<const UChar*>(path.characters() + start), length, true);
                         hstr += "\"";
 
-                        if (!static_cast<HTMLInputElement*>(current)->value().isEmpty()) {
+                        if (!path.isEmpty()) {
                             DeprecatedString mimeType = MimeTypeRegistry::getMIMETypeForPath(path).deprecatedString();
                             if (!mimeType.isEmpty()) {
                                 hstr += "\r\nContent-Type: ";
@@ -498,7 +500,7 @@ void HTMLFormElement::parseMappedAttribute(MappedAttribute *attr)
     else if (attr->name() == onresetAttr)
         setHTMLEventListener(resetEvent, attr);
     else if (attr->name() == nameAttr) {
-        String newNameAttr = attr->value();
+        const AtomicString& newNameAttr = attr->value();
         if (inDocument() && document()->isHTMLDocument()) {
             HTMLDocument *doc = static_cast<HTMLDocument *>(document());
             doc->removeNamedItem(oldNameAttr);
@@ -559,11 +561,30 @@ void HTMLFormElement::removeFormElement(HTMLGenericFormElement* e)
         HTMLGenericFormElement* currentCheckedRadio = document()->checkedRadioButtonForGroup(e->name().impl(), this);
         if (currentCheckedRadio == e)
             document()->removeRadioButtonGroup(e->name().impl(), this);
+        formElementNameChanged(e, e->name());
     }
     removeFromVector(formElements, e);
     document()->incDOMTreeVersion();
 }
 
+void HTMLFormElement::formElementNameChanged(HTMLGenericFormElement* element, const AtomicString& oldName)
+{
+    if (oldName.isEmpty())
+        return;
+    if (!m_oldNames)
+        m_oldNames = new OldNameMap;
+    m_oldNames->set(oldName.impl(), element);
+}
+
+HTMLGenericFormElement* HTMLFormElement::oldNamedElement(const AtomicString& oldName) const
+{
+    if (oldName.isEmpty())
+        return 0;
+    if (!m_oldNames)
+        return 0;
+    return m_oldNames->get(oldName.impl()).get();
+}
+
 bool HTMLFormElement::isURLAttribute(Attribute *attr) const
 {
     return attr->name() == actionAttr;
index d6409d4540ec18481648fccf8d9995a3ef819e83..330d31da90821da110fa37e50bc412c8a51bb4ec 100644 (file)
@@ -65,6 +65,8 @@ public:
 
     void registerFormElement(HTMLGenericFormElement*);
     void removeFormElement(HTMLGenericFormElement*);
+    void formElementNameChanged(HTMLGenericFormElement*, const AtomicString& oldName);
+
     void registerImgElement(HTMLImageElement*);
     void removeImgElement(HTMLImageElement*);
 
@@ -99,6 +101,8 @@ public:
     virtual String target() const;
     void setTarget(const String&);
 
+    HTMLGenericFormElement* oldNamedElement(const AtomicString& oldName) const;
+
     // FIXME: Change this to be private after getting rid of all the clients.
     Vector<HTMLGenericFormElement*> formElements;
 
@@ -109,13 +113,15 @@ private:
 
     friend class HTMLFormCollection;
 
+    typedef HashMap<RefPtr<AtomicStringImpl>, RefPtr<HTMLGenericFormElement> > OldNameMap;
+
+    OldNameMap* m_oldNames;
     HTMLCollection::CollectionInfo* collectionInfo;
 
     Vector<HTMLImageElement*> imgElements;
     String m_url;
     String m_target;
     String m_enctype;
-    String m_boundary;
     String m_acceptcharset;
     bool m_post : 1;
     bool m_multipart : 1;
index e9d0c10d970a1a13aa61f05c8ca3139d26342703..a0c4df063414fed97e1c3f80251280eee302ce2c 100644 (file)
@@ -1,10 +1,8 @@
 /*
- * This file is part of the DOM implementation for KDE.
- *
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
  *           (C) 2006 Alexey Proskuryakov (ap@nypop.com)
  *
  * This library is free software; you can redistribute it and/or
@@ -55,10 +53,13 @@ HTMLGenericFormElement::~HTMLGenericFormElement()
         m_form->removeFormElement(this);
 }
 
-void HTMLGenericFormElement::parseMappedAttribute(MappedAttribute *attr)
+void HTMLGenericFormElement::parseMappedAttribute(MappedAttributeattr)
 {
     if (attr->name() == nameAttr) {
-        // Do nothing.
+        if (m_form) {
+            m_form->formElementNameChanged(this, m_oldName);
+            m_oldName = name();
+        }
     } else if (attr->name() == disabledAttr) {
         bool oldDisabled = m_disabled;
         m_disabled = !attr->isNull();
@@ -100,9 +101,10 @@ void HTMLGenericFormElement::insertedIntoTree(bool deep)
         // setting a form, we will already have a non-null value for m_form, 
         // and so we don't need to do anything.
         m_form = getForm();
-        if (m_form)
+        if (m_form) {
             m_form->registerFormElement(this);
-        else
+            m_oldName = name();
+        } else
             if (isRadioButton() && !name().isEmpty() && isChecked())
                 document()->radioButtonChecked((HTMLInputElement*)this, m_form);
     }
index 4b58a12c863798bfa2c101c76aac2bf79658920a..6ae92ed58488d88c3ab10d323ac6239cd66b9b76 100644 (file)
@@ -106,7 +106,7 @@ private:
     bool m_disabled;
     bool m_readOnly;
     mutable bool m_valueMatchesRenderer;
-
+    AtomicString m_oldName;
 };
 
 } //namespace
index b1d8f046126f65a8de657d9492055b7c3b61dd6f..7e25a45feeac391bb03434d2434bc47aa276b5fa 100644 (file)
@@ -591,6 +591,7 @@ void HTMLInputElement::parseMappedAttribute(MappedAttribute *attr)
             if (checked())
                 document()->radioButtonChecked(this, form());
         }
+        HTMLGenericFormElement::parseMappedAttribute(attr);
     } else if (attr->name() == autocompleteAttr) {
         m_autocomplete = !equalIgnoringCase(attr->value(), "off");
     } else if (attr->name() == typeAttr) {