SVN commit 1200119 by orlovich: Implement the "past names map" bug-compat feature from HTML5; needed by libero.it e-mail app (the old one) CCBUG: 137348 M +17 -3 ecma/kjs_html.cpp M +27 -1 html/html_formimpl.cpp M +9 -1 html/html_formimpl.h --- trunk/KDE/kdelibs/khtml/ecma/kjs_html.cpp #1200118:1200119 @@ -1235,10 +1235,19 @@ JSValue *HTMLElement::formNameGetter(ExecState *exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot) { HTMLElement *thisObj = static_cast(slot.slotBase()); + HTMLFormElementImpl* form = static_cast(thisObj->impl()); - KJS::HTMLCollection coll(exec, static_cast(thisObj->impl())->elements()); - return coll.getNamedItems(exec, propertyName); + KJS::HTMLCollection coll(exec, form->elements()); + JSValue* result = coll.getNamedItems(exec, propertyName); + + // In case of simple result, remember in past names map + // ### our HTMLFormElementsCollection is a bit too IE-compatey rather than HTML5ey + if (DOM::NodeImpl* node = toNode(result)) { + if (node->isGenericFormElement()) + form->bindPastName(static_cast(node)); } + return result; +} //JSValue* KJS::HTMLElement::tryGet(ExecState *exec, const Identifier &propertyName) const bool KJS::HTMLElement::getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot& slot) @@ -1260,8 +1269,13 @@ JSValue *namedItems = coll.getNamedItems(exec, propertyName); if (namedItems->type() != UndefinedType) { slot.setCustom(this, formNameGetter); - return namedItems; + return true; } + + // Try with past names map + if (HTMLGenericFormElementImpl* r = form.lookupByPastName(propertyName.domString())) + return getImmediateValueSlot(this, getDOMNode(exec, r), slot); + break; } case ID_SELECT: --- trunk/KDE/kdelibs/khtml/html/html_formimpl.cpp #1200118:1200119 @@ -824,7 +824,16 @@ int i = formElements.indexOf(e); if (i != -1) formElements.removeAt(i); + + if (e->hasPastNames()) { + QMutableHashIterator it(m_pastNamesMap); + while (it.hasNext()) { + it.next(); + if (it.value() == e) + it.remove(); } + } +} void HTMLFormElementImpl::registerImgElement(HTMLImageElementImpl *e) { @@ -838,12 +847,29 @@ imgElements.removeAt(i); } +HTMLGenericFormElementImpl* HTMLFormElementImpl::lookupByPastName(const DOMString& id) +{ + return m_pastNamesMap.value(id); +} + +void HTMLFormElementImpl::bindPastName(HTMLGenericFormElementImpl* e) +{ + DOMString id = e->getAttribute(ATTR_ID); + if (!id.isEmpty()) + m_pastNamesMap.insert(id, e); + + DOMString nm = e->getAttribute(ATTR_NAME); + if (!nm.isEmpty()) + m_pastNamesMap.insert(nm, e); + e->setHasPastNames(); +} + // ------------------------------------------------------------------------- HTMLGenericFormElementImpl::HTMLGenericFormElementImpl(DocumentImpl *doc, HTMLFormElementImpl *f) : HTMLElementImpl(doc) { - m_disabled = m_readOnly = false; + m_disabled = m_readOnly = m_hasPastNames = false; m_name = 0; if (f) --- trunk/KDE/kdelibs/khtml/html/html_formimpl.h #1200118:1200119 @@ -72,6 +72,9 @@ virtual void addId(const DOMString& id); virtual void removeId(const DOMString& id); + // See "past names map" in HTML5, 4.10.3, "The form element" + HTMLGenericFormElementImpl* lookupByPastName(const DOMString& id); + void bindPastName(HTMLGenericFormElementImpl* element); long length() const; @@ -132,6 +135,8 @@ bool m_havePassword : 1; // for wallet storage DOMString m_name; // our name QMap m_walletMap; // for wallet storage + + QHash m_pastNamesMap; }; // ------------------------------------------------------------------------- @@ -174,6 +179,9 @@ virtual bool isGenericFormElement() const { return true; } virtual bool isHiddenInput() const { return false; } + bool hasPastNames() const { return m_hasPastNames; } + void setHasPastNames() { m_hasPastNames = true; } + /* * override in derived classes to get the encoded name=value pair * for submitting @@ -191,7 +199,7 @@ DOMStringImpl* m_name; HTMLFormElementImpl *m_form; - bool m_disabled, m_readOnly; + bool m_disabled, m_readOnly, m_hasPastNames; }; // -------------------------------------------------------------------------