Reviewed by Eric Seidel.
[WebKit-https.git] / WebCore / dom / OptionElement.cpp
index ba5ded7..eeeac93 100644 (file)
 #include "config.h"
 #include "OptionElement.h"
 
 #include "config.h"
 #include "OptionElement.h"
 
+#include "Document.h"
 #include "Element.h"
 #include "HTMLNames.h"
 #include "HTMLOptionElement.h"
 #include "Element.h"
 #include "HTMLNames.h"
 #include "HTMLOptionElement.h"
+#include "OptionGroupElement.h"
+#include "ScriptElement.h"
 #include <wtf/Assertions.h>
 
 // FIXME: Activate code once WMLOptionElement is available
 #include <wtf/Assertions.h>
 
 // FIXME: Activate code once WMLOptionElement is available
 
 namespace WebCore {
 
 
 namespace WebCore {
 
+void OptionElement::setSelectedState(OptionElementData& data, bool selected)
+{
+    if (data.selected() == selected)
+        return;
+
+    data.setSelected(selected);
+    data.element()->setChanged();
+}
+
+String OptionElement::collectOptionText(const OptionElementData& data, Document* document)
+{
+    String text;
+
+    // WinIE does not use the label attribute, so as a quirk, we ignore it.
+    if (!document->inCompatMode())
+        text = data.label();
+
+    if (text.isEmpty()) {
+        Node* n = data.element()->firstChild();
+        while (n) {
+            if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE)
+                text += n->nodeValue();
+
+            // skip script content
+            if (n->isElementNode() && toScriptElement(static_cast<Element*>(n)))
+                n = n->traverseNextSibling(data.element());
+            else
+                n = n->traverseNextNode(data.element());
+        }
+    }
+
+    text = document->displayStringModifiedByEncoding(text);
+
+    // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
+    text = text.stripWhiteSpace();
+
+    // We want to collapse our whitespace too.  This will match other browsers.
+    text = text.simplifyWhiteSpace();
+    return text;
+}
+
+String OptionElement::collectOptionTextRespectingGroupLabel(const OptionElementData& data, Document* document)
+{
+    Element* parentElement = static_cast<Element*>(data.element()->parentNode());
+    if (parentElement && optionGroupElementForElement(parentElement))
+        return "    " + collectOptionText(data, document);
+
+    return collectOptionText(data, document);
+}
+
+String OptionElement::collectOptionValue(const OptionElementData& data, Document* document)
+{
+    String value = data.value();
+    if (!value.isNull())
+        return value;
+
+    // Use the text if the value wasn't set.
+    return collectOptionText(data, document).stripWhiteSpace();
+}
+
+// OptionElementData
+OptionElementData::OptionElementData(Element* element)
+    : m_element(element)
+    , m_selected(false)
+{
+    ASSERT(m_element);
+}
+
+OptionElementData::~OptionElementData()
+{
+}
+
 OptionElement* optionElementForElement(Element* element)
 {
     if (element->isHTMLElement() && element->hasTagName(HTMLNames::optionTag))
 OptionElement* optionElementForElement(Element* element)
 {
     if (element->isHTMLElement() && element->hasTagName(HTMLNames::optionTag))