http://trac.webkit.org/changeset/97917
https://bugs.webkit.org/show_bug.cgi?id=70475
number of crashes on Snow Leopard/Lion tests bots
http://build.webkit.org/results/Lion%20Intel%20Release%20(Tests)/r97917%20(2020)/http/tests/inspector
/extensions-network-redirect-crash-log.txt (Requested by
loislo on #webkit).
Patch by Sheriff Bot <webkit.review.bot@gmail.com> on 2011-10-20
Source/WebCore:
* css/SelectorChecker.cpp:
(WebCore::SelectorChecker::checkOneSelector):
* dom/OptionElement.cpp:
(WebCore::OptionElement::setSelectedState):
(WebCore::OptionElement::optionIndex):
(WebCore::OptionElement::collectOptionLabelOrText):
(WebCore::OptionElement::collectOptionInnerText):
(WebCore::OptionElement::normalizeText):
(WebCore::OptionElement::collectOptionTextRespectingGroupLabel):
(WebCore::OptionElementData::OptionElementData):
(WebCore::OptionElementData::~OptionElementData):
(WebCore::toOptionElement):
(WebCore::isOptionElement):
* dom/OptionElement.h:
(WebCore::OptionElement::~OptionElement):
(WebCore::OptionElementData::value):
(WebCore::OptionElementData::setValue):
(WebCore::OptionElementData::label):
(WebCore::OptionElementData::setLabel):
(WebCore::OptionElementData::selected):
(WebCore::OptionElementData::setSelected):
* html/HTMLOptionElement.cpp:
(WebCore::HTMLOptionElement::HTMLOptionElement):
(WebCore::HTMLOptionElement::createForJSConstructor):
(WebCore::HTMLOptionElement::text):
(WebCore::HTMLOptionElement::index):
(WebCore::HTMLOptionElement::parseMappedAttribute):
(WebCore::HTMLOptionElement::value):
(WebCore::HTMLOptionElement::selected):
(WebCore::HTMLOptionElement::setSelected):
(WebCore::HTMLOptionElement::setSelectedState):
(WebCore::HTMLOptionElement::defaultSelected):
(WebCore::HTMLOptionElement::setDefaultSelected):
(WebCore::HTMLOptionElement::label):
(WebCore::HTMLOptionElement::textIndentedToRespectGroupLabel):
(WebCore::HTMLOptionElement::insertedIntoTree):
* html/HTMLOptionElement.h:
* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::nextValidIndex):
(WebCore::HTMLSelectElement::saveLastSelection):
(WebCore::HTMLSelectElement::setActiveSelectionAnchorIndex):
(WebCore::HTMLSelectElement::updateListBoxSelection):
(WebCore::HTMLSelectElement::listBoxOnChange):
(WebCore::HTMLSelectElement::recalcListItems):
(WebCore::HTMLSelectElement::selectedIndex):
(WebCore::HTMLSelectElement::setSelectedIndex):
(WebCore::HTMLSelectElement::optionToListIndex):
(WebCore::HTMLSelectElement::listToOptionIndex):
(WebCore::HTMLSelectElement::deselectItemsWithoutValidation):
(WebCore::HTMLSelectElement::saveFormControlState):
(WebCore::HTMLSelectElement::restoreFormControlState):
(WebCore::HTMLSelectElement::appendFormData):
(WebCore::HTMLSelectElement::reset):
(WebCore::HTMLSelectElement::updateSelectedState):
(WebCore::HTMLSelectElement::lastSelectedListIndex):
(WebCore::HTMLSelectElement::typeAheadFind):
(WebCore::HTMLSelectElement::accessKeySetSelectedIndex):
(WebCore::HTMLSelectElement::length):
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::copyImage):
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::updateFromElement):
(WebCore::RenderListBox::addFocusRingRects):
(WebCore::RenderListBox::paintItemForeground):
(WebCore::RenderListBox::paintItemBackground):
* rendering/RenderMenuList.cpp:
(WebCore::RenderMenuList::updateOptionsWidth):
(WebCore::RenderMenuList::setTextFromOption):
(WebCore::RenderMenuList::itemText):
(WebCore::RenderMenuList::itemIsSelected):
Source/WebKit/chromium:
* src/WebOptionElement.cpp:
(WebKit::WebOptionElement::defaultSelected):
(WebKit::WebOptionElement::setDefaultSelected):
* src/WebSearchableFormData.cpp:
(HTMLNames::IsSelectInDefaultState):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@97946
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2011-10-20 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r97917.
+ http://trac.webkit.org/changeset/97917
+ https://bugs.webkit.org/show_bug.cgi?id=70475
+
+ number of crashes on Snow Leopard/Lion tests bots
+ http://build.webkit.org/results/Lion%20Intel%20Release%20(Tests)/r97917%20(2020)/http/tests/inspector
+ /extensions-network-redirect-crash-log.txt (Requested by
+ loislo on #webkit).
+
+ * css/SelectorChecker.cpp:
+ (WebCore::SelectorChecker::checkOneSelector):
+ * dom/OptionElement.cpp:
+ (WebCore::OptionElement::setSelectedState):
+ (WebCore::OptionElement::optionIndex):
+ (WebCore::OptionElement::collectOptionLabelOrText):
+ (WebCore::OptionElement::collectOptionInnerText):
+ (WebCore::OptionElement::normalizeText):
+ (WebCore::OptionElement::collectOptionTextRespectingGroupLabel):
+ (WebCore::OptionElementData::OptionElementData):
+ (WebCore::OptionElementData::~OptionElementData):
+ (WebCore::toOptionElement):
+ (WebCore::isOptionElement):
+ * dom/OptionElement.h:
+ (WebCore::OptionElement::~OptionElement):
+ (WebCore::OptionElementData::value):
+ (WebCore::OptionElementData::setValue):
+ (WebCore::OptionElementData::label):
+ (WebCore::OptionElementData::setLabel):
+ (WebCore::OptionElementData::selected):
+ (WebCore::OptionElementData::setSelected):
+ * html/HTMLOptionElement.cpp:
+ (WebCore::HTMLOptionElement::HTMLOptionElement):
+ (WebCore::HTMLOptionElement::createForJSConstructor):
+ (WebCore::HTMLOptionElement::text):
+ (WebCore::HTMLOptionElement::index):
+ (WebCore::HTMLOptionElement::parseMappedAttribute):
+ (WebCore::HTMLOptionElement::value):
+ (WebCore::HTMLOptionElement::selected):
+ (WebCore::HTMLOptionElement::setSelected):
+ (WebCore::HTMLOptionElement::setSelectedState):
+ (WebCore::HTMLOptionElement::defaultSelected):
+ (WebCore::HTMLOptionElement::setDefaultSelected):
+ (WebCore::HTMLOptionElement::label):
+ (WebCore::HTMLOptionElement::textIndentedToRespectGroupLabel):
+ (WebCore::HTMLOptionElement::insertedIntoTree):
+ * html/HTMLOptionElement.h:
+ * html/HTMLSelectElement.cpp:
+ (WebCore::HTMLSelectElement::nextValidIndex):
+ (WebCore::HTMLSelectElement::saveLastSelection):
+ (WebCore::HTMLSelectElement::setActiveSelectionAnchorIndex):
+ (WebCore::HTMLSelectElement::updateListBoxSelection):
+ (WebCore::HTMLSelectElement::listBoxOnChange):
+ (WebCore::HTMLSelectElement::recalcListItems):
+ (WebCore::HTMLSelectElement::selectedIndex):
+ (WebCore::HTMLSelectElement::setSelectedIndex):
+ (WebCore::HTMLSelectElement::optionToListIndex):
+ (WebCore::HTMLSelectElement::listToOptionIndex):
+ (WebCore::HTMLSelectElement::deselectItemsWithoutValidation):
+ (WebCore::HTMLSelectElement::saveFormControlState):
+ (WebCore::HTMLSelectElement::restoreFormControlState):
+ (WebCore::HTMLSelectElement::appendFormData):
+ (WebCore::HTMLSelectElement::reset):
+ (WebCore::HTMLSelectElement::updateSelectedState):
+ (WebCore::HTMLSelectElement::lastSelectedListIndex):
+ (WebCore::HTMLSelectElement::typeAheadFind):
+ (WebCore::HTMLSelectElement::accessKeySetSelectedIndex):
+ (WebCore::HTMLSelectElement::length):
+ * platform/graphics/cg/ImageBufferCG.cpp:
+ (WebCore::ImageBuffer::copyImage):
+ * rendering/RenderListBox.cpp:
+ (WebCore::RenderListBox::updateFromElement):
+ (WebCore::RenderListBox::addFocusRingRects):
+ (WebCore::RenderListBox::paintItemForeground):
+ (WebCore::RenderListBox::paintItemBackground):
+ * rendering/RenderMenuList.cpp:
+ (WebCore::RenderMenuList::updateOptionsWidth):
+ (WebCore::RenderMenuList::setTextFromOption):
+ (WebCore::RenderMenuList::itemText):
+ (WebCore::RenderMenuList::itemIsSelected):
+
2011-10-20 Carol Szabo <carol@webkit.org>
Tiled Backing Store does not regenerate tiles when it should
#include "HTMLFrameElementBase.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
-#include "HTMLOptionElement.h"
#include "HTMLProgressElement.h"
#include "InspectorInstrumentation.h"
#include "NodeRenderStyle.h"
+#include "OptionElement.h"
#include "Page.h"
#include "PageGroup.h"
#include "RenderObject.h"
HTMLInputElement* inputElement = e->toInputElement();
if (inputElement && inputElement->shouldAppearChecked() && !inputElement->isIndeterminate())
return true;
- if (e->hasTagName(optionTag) && toHTMLOptionElement(e)->selected())
+
+ OptionElement* optionElement = toOptionElement(e);
+ if (optionElement && optionElement->selected())
return true;
break;
}
-// FIXME: Delete this file after updating all the project files.
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "OptionElement.h"
+
+#include "Document.h"
+#include "Element.h"
+#include "HTMLNames.h"
+#include "HTMLOptGroupElement.h"
+#include "HTMLOptionElement.h"
+#include "HTMLParserIdioms.h"
+#include "HTMLSelectElement.h"
+#include "ScriptElement.h"
+#include <wtf/Assertions.h>
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+void OptionElement::setSelectedState(OptionElementData& data, Element* element, bool selected)
+{
+ if (data.selected() == selected)
+ return;
+
+ data.setSelected(selected);
+ element->setNeedsStyleRecalc();
+}
+
+int OptionElement::optionIndex(HTMLSelectElement* selectElement, const Element* element)
+{
+ if (!selectElement)
+ return 0;
+
+ // Let's do this dynamically. Might be a bit slow, but we're sure
+ // we won't forget to update a member variable in some cases...
+ const Vector<HTMLElement*>& items = selectElement->listItems();
+ int length = items.size();
+ int optionIndex = 0;
+ for (int i = 0; i < length; ++i) {
+ if (!isOptionElement(items[i]))
+ continue;
+ if (items[i] == element)
+ return optionIndex;
+ ++optionIndex;
+ }
+
+ return 0;
+}
+
+String OptionElement::collectOptionLabelOrText(const OptionElementData& data, const Element* element)
+{
+ Document* document = element->document();
+ String text;
+
+ // WinIE does not use the label attribute, so as a quirk, we ignore it.
+ if (!document->inQuirksMode())
+ text = data.label();
+ if (text.isEmpty())
+ text = collectOptionInnerText(element);
+ return normalizeText(document, text);
+}
+
+String OptionElement::collectOptionInnerText(const Element* element)
+{
+ String text;
+ Node* n = 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(element);
+ else
+ n = n->traverseNextNode(element);
+ }
+ return text;
+}
+
+String OptionElement::normalizeText(const Document* document, const String& src)
+{
+ String text = document->displayStringModifiedByEncoding(src);
+
+ // In WinIE, leading and trailing whitespace is ignored in options and optgroups. We match this behavior.
+ text = text.stripWhiteSpace(isHTMLSpace);
+
+ // We want to collapse our whitespace too. This will match other browsers.
+ text = text.simplifyWhiteSpace(isHTMLSpace);
+
+ return text;
+}
+
+String OptionElement::collectOptionTextRespectingGroupLabel(const OptionElementData& data, const Element* element)
+{
+ Element* parentElement = static_cast<Element*>(element->parentNode());
+ if (parentElement && parentElement->hasTagName(optgroupTag))
+ return " " + collectOptionLabelOrText(data, element);
+
+ return collectOptionLabelOrText(data, element);
+}
+
+// OptionElementData
+OptionElementData::OptionElementData()
+ : m_selected(false)
+{
+}
+
+OptionElementData::~OptionElementData()
+{
+}
+
+OptionElement* toOptionElement(Element* element)
+{
+ if (element->isHTMLElement() && element->hasTagName(HTMLNames::optionTag))
+ return static_cast<HTMLOptionElement*>(element);
+ return 0;
+}
+
+bool isOptionElement(Element* element)
+{
+ return element->hasLocalName(HTMLNames::optionTag);
+}
+
+}
-// FIXME: Delete this file after updating all the project files.
-#error
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef OptionElement_h
+#define OptionElement_h
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class Element;
+class Document;
+class HTMLSelectElement;
+class OptionElementData;
+
+class OptionElement {
+public:
+ virtual ~OptionElement() { }
+
+ virtual bool disabled() const = 0;
+ virtual bool selected() = 0;
+ virtual void setSelectedState(bool) = 0;
+
+ virtual String text() const = 0;
+ virtual String textIndentedToRespectGroupLabel() const = 0;
+ virtual String value() const = 0;
+
+protected:
+ static void setSelectedState(OptionElementData&, Element*, bool selected);
+ static int optionIndex(HTMLSelectElement*, const Element*);
+ static String collectOptionLabelOrText(const OptionElementData&, const Element*);
+ static String collectOptionTextRespectingGroupLabel(const OptionElementData&, const Element*);
+ static String collectOptionValue(const OptionElementData&, const Element*);
+ static String collectOptionInnerText(const Element*);
+private:
+ static String normalizeText(const Document*, const String&);
+};
+
+// HTMLOptionElement hold this struct as member variable
+// and pass it to the static helper functions in OptionElement
+class OptionElementData {
+public:
+ OptionElementData();
+ ~OptionElementData();
+
+ String value() const { return m_value; }
+ void setValue(const String& value) { m_value = value; }
+
+ String label() const { return m_label; }
+ void setLabel(const String& label) { m_label = label; }
+
+ bool selected() const { return m_selected; }
+ void setSelected(bool selected) { m_selected = selected; }
+
+private:
+ String m_value;
+ String m_label;
+ bool m_selected;
+};
+
+OptionElement* toOptionElement(Element*);
+bool isOptionElement(Element*);
+
+}
+
+#endif
#include "NodeRenderStyle.h"
#include "NodeRenderingContext.h"
#include "RenderMenuList.h"
-#include "ScriptElement.h"
#include "Text.h"
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
-#include <wtf/text/StringBuilder.h>
namespace WebCore {
HTMLOptionElement::HTMLOptionElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
: HTMLFormControlElement(tagName, document, form)
- , m_isSelected(false)
{
ASSERT(hasTagName(optionTag));
}
if (!value.isNull())
element->setValue(value);
- if (defaultSelected)
- element->setAttribute(selectedAttr, emptyAtom);
+ element->setDefaultSelected(defaultSelected);
element->setSelected(selected);
return element.release();
String HTMLOptionElement::text() const
{
- Document* document = this->document();
- String text;
-
- // WinIE does not use the label attribute, so as a quirk, we ignore it.
- if (!document->inQuirksMode())
- text = fastGetAttribute(labelAttr);
-
- // FIXME: The following treats an element with the label attribute set to
- // the empty string the same as an element with no label attribute at all.
- // Is that correct? If it is, then should the label function work the same way?
- if (text.isEmpty())
- text = collectOptionInnerText();
-
- // FIXME: Is displayStringModifiedByEncoding helpful here?
- // If it's correct here, then isn't it needed in the value and label functions too?
- return document->displayStringModifiedByEncoding(text).stripWhiteSpace(isHTMLSpace).simplifyWhiteSpace(isHTMLSpace);
+ return OptionElement::collectOptionLabelOrText(m_data, this);
}
void HTMLOptionElement::setText(const String &text, ExceptionCode& ec)
int HTMLOptionElement::index() const
{
- // It would be faster to cache the index, but harder to get it right in all cases.
-
- HTMLSelectElement* selectElement = ownerSelectElement();
- if (!selectElement)
- return 0;
-
- int optionIndex = 0;
-
- const Vector<HTMLElement*>& items = selectElement->listItems();
- size_t length = items.size();
- for (size_t i = 0; i < length; ++i) {
- if (!items[i]->hasTagName(optionTag))
- continue;
- if (items[i] == this)
- return optionIndex;
- ++optionIndex;
- }
-
- return 0;
+ return OptionElement::optionIndex(ownerSelectElement(), this);
}
void HTMLOptionElement::parseMappedAttribute(Attribute* attr)
{
- if (attr->name() == selectedAttr) {
- // FIXME: This doesn't match what the HTML specification says.
- // The specification implies that removing the selected attribute or
- // changing the value of a selected attribute that is already present
- // has no effect on whether the element is selected. Further, it seems
- // that we need to do more than just set m_isSelected to select in that
- // case; we'd need to do the other work from the setSelected function.
- m_isSelected = !attr->isNull();
- } else
+ if (attr->name() == selectedAttr)
+ m_data.setSelected(!attr->isNull());
+ else if (attr->name() == valueAttr)
+ m_data.setValue(attr->value());
+ else if (attr->name() == labelAttr)
+ m_data.setLabel(attr->value());
+ else
HTMLFormControlElement::parseMappedAttribute(attr);
}
String HTMLOptionElement::value() const
{
- const AtomicString& value = fastGetAttribute(valueAttr);
- if (!value.isNull())
- return value;
- return collectOptionInnerText().stripWhiteSpace(isHTMLSpace).simplifyWhiteSpace(isHTMLSpace);
+ if (!m_data.value().isNull())
+ return m_data.value();
+
+ return collectOptionInnerText(this).stripWhiteSpace(isHTMLSpace).simplifyWhiteSpace(isHTMLSpace);
+
}
void HTMLOptionElement::setValue(const String& value)
{
if (HTMLSelectElement* select = ownerSelectElement())
select->updateListItemSelectedStates();
- return m_isSelected;
+ return m_data.selected();
}
void HTMLOptionElement::setSelected(bool selected)
{
- if (m_isSelected == selected)
+ if (m_data.selected() == selected)
return;
- setSelectedState(selected);
+ OptionElement::setSelectedState(m_data, this, selected);
if (HTMLSelectElement* select = ownerSelectElement())
select->setSelectedIndex(selected ? index() : -1, false);
void HTMLOptionElement::setSelectedState(bool selected)
{
- if (m_isSelected == selected)
- return;
-
- m_isSelected = selected;
- setNeedsStyleRecalc();
+ OptionElement::setSelectedState(m_data, this, selected);
}
void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
return toHTMLSelectElement(select);
}
+bool HTMLOptionElement::defaultSelected() const
+{
+ return fastHasAttribute(selectedAttr);
+}
+
+void HTMLOptionElement::setDefaultSelected(bool b)
+{
+ setAttribute(selectedAttr, b ? "" : 0);
+}
+
String HTMLOptionElement::label() const
{
- const AtomicString& label = fastGetAttribute(labelAttr);
+ String label = m_data.label();
if (!label.isNull())
- return label;
- return collectOptionInnerText().stripWhiteSpace(isHTMLSpace).simplifyWhiteSpace(isHTMLSpace);
+ return label;
+
+ label = collectOptionInnerText(this).stripWhiteSpace(isHTMLSpace);
+ label = label.simplifyWhiteSpace(isHTMLSpace);
+
+ return label;
}
void HTMLOptionElement::setLabel(const String& label)
String HTMLOptionElement::textIndentedToRespectGroupLabel() const
{
- ContainerNode* parent = parentNode();
- if (parent && parent->hasTagName(optgroupTag))
- return " " + text();
- return text();
+ return OptionElement::collectOptionTextRespectingGroupLabel(m_data, this);
}
bool HTMLOptionElement::disabled() const
{
if (HTMLSelectElement* select = ownerSelectElement()) {
select->setRecalcListItems();
- // Do not call selected() since calling updateListItemSelectedStates()
- // at this time won't do the right thing. (Why, exactly?)
- if (m_isSelected)
+ // Avoid our selected() getter since it will recalculate list items incorrectly for us.
+ if (m_data.selected())
select->setSelectedIndex(index(), false);
select->scrollToSelection();
}
HTMLFormControlElement::insertedIntoTree(deep);
}
-String HTMLOptionElement::collectOptionInnerText() const
-{
- StringBuilder text;
- for (Node* node = firstChild(); node; ) {
- if (node->isTextNode())
- text.append(node->nodeValue());
- // Text nodes inside script elements are not part of the option text.
- if (node->isElementNode() && toScriptElement(toElement(node)))
- node = node->traverseNextSibling(this);
- else
- node = node->traverseNextNode(this);
- }
- return text.toString();
-}
-
-#ifndef NDEBUG
-
-HTMLOptionElement* toHTMLOptionElement(Node* node)
-{
- ASSERT(!node || node->hasTagName(optionTag));
- return static_cast<HTMLOptionElement*>(node);
-}
-
-const HTMLOptionElement* toHTMLOptionElement(const Node* node)
-{
- ASSERT(!node || node->hasTagName(optionTag));
- return static_cast<const HTMLOptionElement*>(node);
-}
-
-#endif
-
} // namespace
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* Boston, MA 02110-1301, USA.
*
*/
-
#ifndef HTMLOptionElement_h
#define HTMLOptionElement_h
#include "HTMLFormControlElement.h"
+#include "OptionElement.h"
namespace WebCore {
class HTMLSelectElement;
-class HTMLOptionElement : public HTMLFormControlElement {
+class HTMLOptionElement : public HTMLFormControlElement, public OptionElement {
+ friend class HTMLSelectElement;
+ friend class RenderMenuList;
+
public:
static PassRefPtr<HTMLOptionElement> create(Document*, HTMLFormElement*);
static PassRefPtr<HTMLOptionElement> create(const QualifiedName&, Document*, HTMLFormElement*);
int index() const;
- String value() const;
+ virtual String value() const;
void setValue(const String&);
- bool selected();
+ virtual bool selected();
void setSelected(bool);
HTMLSelectElement* ownerSelectElement() const;
+ bool defaultSelected() const;
+ void setDefaultSelected(bool);
+
String label() const;
void setLabel(const String&);
virtual bool disabled() const;
- String textIndentedToRespectGroupLabel() const;
-
- void setSelectedState(bool);
-
private:
HTMLOptionElement(const QualifiedName&, Document*, HTMLFormElement* = 0);
virtual void parseMappedAttribute(Attribute*);
+ virtual void setSelectedState(bool);
+
+ virtual String textIndentedToRespectGroupLabel() const;
+
virtual void insertedIntoTree(bool);
virtual void accessKeyAction(bool);
virtual RenderStyle* nonRendererRenderStyle() const;
- String collectOptionInnerText() const;
-
- String m_value;
- String m_label;
- bool m_isSelected;
+ OptionElementData m_data;
RefPtr<RenderStyle> m_style;
};
-HTMLOptionElement* toHTMLOptionElement(Node*);
-const HTMLOptionElement* toHTMLOptionElement(const Node*);
-void toHTMLOptionElement(const HTMLOptionElement*); // This overload will catch anyone doing an unnecessary cast.
-
-#ifdef NDEBUG
-
-// The debug versions of these, with assertions, are not inlined.
-
-inline HTMLOptionElement* toHTMLOptionElement(Node* node)
-{
- return static_cast<HTMLOptionElement*>(node);
-}
-
-inline const HTMLOptionElement* toHTMLOptionElement(const Node* node)
-{
- return static_cast<const HTMLOptionElement*>(node);
-}
-
-#endif
-
} // namespace
#endif
static const DOMTimeStamp typeAheadTimeout = 1000;
-// FIXME: Change all the call sites to use hasTagName and toHTMLOptionElement instead.
-static inline HTMLOptionElement* toOptionElement(Element* element)
-{
- return element->hasTagName(optionTag) ? toHTMLOptionElement(element) : 0;
-}
-
HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
: HTMLFormControlElementWithState(tagName, document, form)
, m_lastCharTime(0)
int size = listItems.size();
for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex += direction) {
--skip;
- if (!listItems[listIndex]->disabled() && listItems[listIndex]->hasTagName(optionTag)) {
+ if (!listItems[listIndex]->disabled() && isOptionElement(listItems[listIndex])) {
lastGoodIndex = listIndex;
if (skip <= 0)
break;
m_lastOnChangeSelection.clear();
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- HTMLOptionElement* optionElement = toOptionElement(items[i]);
+ OptionElement* optionElement = toOptionElement(items[i]);
m_lastOnChangeSelection.append(optionElement && optionElement->selected());
}
}
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- HTMLOptionElement* optionElement = toOptionElement(items[i]);
+ OptionElement* optionElement = toOptionElement(items[i]);
m_cachedStateForActiveSelection.append(optionElement && optionElement->selected());
}
}
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- HTMLOptionElement* optionElement = toOptionElement(items[i]);
+ OptionElement* optionElement = toOptionElement(items[i]);
if (!optionElement || items[i]->disabled())
continue;
// Update m_lastOnChangeSelection and fire dispatchFormControlChangeEvent.
bool fireOnChange = false;
for (unsigned i = 0; i < items.size(); ++i) {
- HTMLOptionElement* optionElement = toOptionElement(items[i]);
+ OptionElement* optionElement = toOptionElement(items[i]);
bool selected = optionElement && optionElement->selected();
if (selected != m_lastOnChangeSelection[i])
fireOnChange = true;
m_shouldRecalcListItems = false;
- HTMLOptionElement* foundSelected = 0;
+ OptionElement* foundSelected = 0;
for (Node* currentNode = this->firstChild(); currentNode;) {
if (!currentNode->isHTMLElement()) {
currentNode = currentNode->traverseNextSibling(this);
}
}
- if (HTMLOptionElement* optionElement = toOptionElement(current)) {
+ if (OptionElement* optionElement = toOptionElement(current)) {
m_listItems.append(current);
if (updateSelectedStates && !m_multiple) {
// Return the number of the first option selected.
const Vector<HTMLElement*>& items = listItems();
for (size_t i = 0; i < items.size(); ++i) {
- if (HTMLOptionElement* optionElement = toOptionElement(items[i])) {
+ if (OptionElement* optionElement = toOptionElement(items[i])) {
if (optionElement->selected())
return index;
++index;
int listIndex = optionToListIndex(optionIndex);
Element* excludeElement = 0;
- if (HTMLOptionElement* optionElement = (listIndex >= 0 ? toOptionElement(items[listIndex]) : 0)) {
+ if (OptionElement* optionElement = (listIndex >= 0 ? toOptionElement(items[listIndex]) : 0)) {
excludeElement = items[listIndex];
if (m_activeSelectionAnchorIndex < 0 || deselect)
setActiveSelectionAnchorIndex(listIndex);
int optionIndex2 = -1;
for (int listIndex = 0; listIndex < listSize; ++listIndex) {
- if (items[listIndex]->hasTagName(optionTag)) {
+ if (isOptionElement(items[listIndex])) {
++optionIndex2;
if (optionIndex2 == optionIndex)
return listIndex;
int HTMLSelectElement::listToOptionIndex(int listIndex) const
{
const Vector<HTMLElement*>& items = listItems();
- if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !items[listIndex]->hasTagName(optionTag))
+ if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isOptionElement(items[listIndex]))
return -1;
// Actual index of option not counting OPTGROUP entries that may be in list.
int optionIndex = 0;
for (int i = 0; i < listIndex; ++i) {
- if (items[i]->hasTagName(optionTag))
+ if (isOptionElement(items[i]))
++optionIndex;
}
if (items[i] == excludeElement)
continue;
- if (HTMLOptionElement* optionElement = toOptionElement(items[i]))
+ if (OptionElement* optionElement = toOptionElement(items[i]))
optionElement->setSelectedState(false);
}
}
StringBuilder builder;
builder.reserveCapacity(length);
for (unsigned i = 0; i < length; ++i) {
- HTMLOptionElement* optionElement = toOptionElement(items[i]);
+ OptionElement* optionElement = toOptionElement(items[i]);
bool selected = optionElement && optionElement->selected();
builder.append(selected ? 'X' : '.');
}
size_t length = items.size();
for (unsigned i = 0; i < length; ++i) {
- if (HTMLOptionElement* optionElement = toOptionElement(items[i]))
+ if (OptionElement* optionElement = toOptionElement(items[i]))
optionElement->setSelectedState(state[i] == 'X');
}
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- HTMLOptionElement* optionElement = toOptionElement(items[i]);
+ OptionElement* optionElement = toOptionElement(items[i]);
if (optionElement && optionElement->selected() && !optionElement->disabled()) {
list.appendData(name, optionElement->value());
successful = true;
void HTMLSelectElement::reset()
{
- HTMLOptionElement* firstOption = 0;
- HTMLOptionElement* selectedOption = 0;
+ OptionElement* firstOption = 0;
+ OptionElement* selectedOption = 0;
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- HTMLOptionElement* optionElement = toOptionElement(items[i]);
+ OptionElement* optionElement = toOptionElement(items[i]);
if (!optionElement)
continue;
bool multiSelect = m_multiple && multi && !shift;
Element* clickedElement = listItems()[listIndex];
- HTMLOptionElement* option = toOptionElement(clickedElement);
+ OptionElement* option = toOptionElement(clickedElement);
if (option) {
// Keep track of whether an active selection (like during drag
// selection), should select or deselect.
{
const Vector<HTMLElement*>& items = listItems();
for (size_t i = items.size(); i;) {
- if (HTMLOptionElement* optionElement = toOptionElement(items[--i])) {
+ if (OptionElement* optionElement = toOptionElement(items[--i])) {
if (optionElement->selected())
return i;
}
// to use startWith once that is fixed.
String prefixWithCaseFolded(prefix.foldCase());
for (int i = 0; i < itemCount; ++i, index = (index + 1) % itemCount) {
- HTMLOptionElement* optionElement = toOptionElement(items[index]);
+ OptionElement* optionElement = toOptionElement(items[index]);
if (!optionElement || items[index]->disabled())
continue;
// If this index is already selected, unselect. otherwise update the selected index.
const Vector<HTMLElement*>& items = listItems();
int listIndex = optionToListIndex(index);
- if (HTMLOptionElement* optionElement = (listIndex >= 0 ? toOptionElement(items[listIndex]) : 0)) {
+ if (OptionElement* optionElement = (listIndex >= 0 ? toOptionElement(items[listIndex]) : 0)) {
if (optionElement->selected())
optionElement->setSelectedState(false);
else
const Vector<HTMLElement*>& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- if (items[i]->hasTagName(optionTag))
+ if (isOptionElement(items[i]))
++options;
}
PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const
{
- RetainPtr<CGImageRef> image(AdoptCF, copyNativeImage(copyBehavior));
+ RetainPtr<CGImageRef> image = copyNativeImage(copyBehavior);
if (!image)
return 0;
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLNames.h"
-#include "HTMLOptionElement.h"
#include "HTMLOptGroupElement.h"
#include "HTMLSelectElement.h"
#include "HitTestResult.h"
#include "NodeRenderStyle.h"
+#include "OptionElement.h"
#include "Page.h"
#include "PaintInfo.h"
#include "RenderLayer.h"
float width = 0;
for (int i = 0; i < size; ++i) {
- HTMLElement* element = listItems[i];
+ Element* element = listItems[i];
String text;
Font itemFont = style()->font();
- if (element->hasTagName(optionTag))
- text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ if (OptionElement* optionElement = toOptionElement(element))
+ text = optionElement->textIndentedToRespectGroupLabel();
else if (element->hasTagName(optgroupTag)) {
text = static_cast<const HTMLOptGroupElement*>(element)->groupLabelText();
FontDescription d = itemFont.fontDescription();
int size = numItems();
const Vector<HTMLElement*>& listItems = select->listItems();
for (int i = 0; i < size; ++i) {
- HTMLElement* element = listItems[i];
- if (element->hasTagName(optionTag) && !toHTMLOptionElement(element)->disabled()) {
+ OptionElement* optionElement = toOptionElement(listItems[i]);
+ if (optionElement && !optionElement->disabled()) {
rects.append(itemBoundingBoxRect(additionalOffset, i));
return;
}
FontCachePurgePreventer fontCachePurgePreventer;
const Vector<HTMLElement*>& listItems = toHTMLSelectElement(node())->listItems();
- HTMLElement* element = listItems[listIndex];
+ Element* element = listItems[listIndex];
+ OptionElement* optionElement = toOptionElement(element);
RenderStyle* itemStyle = element->renderStyle();
if (!itemStyle)
return;
String itemText;
- bool isOptionElement = element->hasTagName(optionTag);
- if (isOptionElement)
- itemText = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ if (optionElement)
+ itemText = optionElement->textIndentedToRespectGroupLabel();
else if (element->hasTagName(optgroupTag))
itemText = static_cast<const HTMLOptGroupElement*>(element)->groupLabelText();
applyTextTransform(style(), itemText, ' ');
Color textColor = element->renderStyle() ? element->renderStyle()->visitedDependentColor(CSSPropertyColor) : style()->visitedDependentColor(CSSPropertyColor);
- if (isOptionElement && toHTMLOptionElement(element)->selected()) {
+ if (optionElement && optionElement->selected()) {
if (frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
textColor = theme()->activeListBoxSelectionForegroundColor();
// Honor the foreground color for disabled items
void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset, int listIndex)
{
const Vector<HTMLElement*>& listItems = toHTMLSelectElement(node())->listItems();
- HTMLElement* element = listItems[listIndex];
+ Element* element = listItems[listIndex];
+ OptionElement* optionElement = toOptionElement(element);
Color backColor;
- if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected()) {
+ if (optionElement && optionElement->selected()) {
if (frame()->selection()->isFocusedAndActive() && document()->focusedNode() == node())
backColor = theme()->activeListBoxSelectionBackgroundColor();
else
#include "Frame.h"
#include "FrameView.h"
#include "HTMLNames.h"
-#include "HTMLOptionElement.h"
#include "HTMLOptGroupElement.h"
#include "HTMLSelectElement.h"
#include "NodeRenderStyle.h"
+#include "OptionElement.h"
#include "Page.h"
#include "PopupMenu.h"
#include "RenderBR.h"
FontCachePurgePreventer fontCachePurgePreventer;
for (int i = 0; i < size; ++i) {
- HTMLElement* element = listItems[i];
- if (!element->hasTagName(optionTag))
+ Element* element = listItems[i];
+ OptionElement* optionElement = toOptionElement(element);
+ if (!optionElement)
continue;
- String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ String text = optionElement->textIndentedToRespectGroupLabel();
applyTextTransform(style(), text, ' ');
if (theme()->popupOptionSupportsTextIndent()) {
// Add in the option's text indent. We can't calculate percentage values for now.
String text = "";
if (i >= 0 && i < size) {
Element* element = listItems[i];
- if (element->hasTagName(optionTag)) {
- text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ if (OptionElement* optionElement = toOptionElement(element)) {
+ text = optionElement->textIndentedToRespectGroupLabel();
m_optionStyle = element->renderStyle();
}
}
Element* element = listItems[listIndex];
if (element->hasTagName(optgroupTag))
itemString = static_cast<const HTMLOptGroupElement*>(element)->groupLabelText();
- else if (element->hasTagName(optionTag))
- itemString = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ else if (OptionElement* optionElement = toOptionElement(element))
+ itemString = optionElement->textIndentedToRespectGroupLabel();
applyTextTransform(style(), itemString, ' ');
return itemString;
const Vector<HTMLElement*>& listItems = toHTMLSelectElement(node())->listItems();
if (listIndex >= listItems.size())
return false;
- HTMLElement* element = listItems[listIndex];
- return element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected();
+ if (OptionElement* optionElement = toOptionElement(listItems[listIndex]))
+ return optionElement->selected();
+ return false;
}
void RenderMenuList::setTextFromItem(unsigned listIndex)
+2011-10-20 Sheriff Bot <webkit.review.bot@gmail.com>
+
+ Unreviewed, rolling out r97917.
+ http://trac.webkit.org/changeset/97917
+ https://bugs.webkit.org/show_bug.cgi?id=70475
+
+ number of crashes on Snow Leopard/Lion tests bots
+ http://build.webkit.org/results/Lion%20Intel%20Release%20(Tests)/r97917%20(2020)/http/tests/inspector
+ /extensions-network-redirect-crash-log.txt (Requested by
+ loislo on #webkit).
+
+ * src/WebOptionElement.cpp:
+ (WebKit::WebOptionElement::defaultSelected):
+ (WebKit::WebOptionElement::setDefaultSelected):
+ * src/WebSearchableFormData.cpp:
+ (HTMLNames::IsSelectInDefaultState):
+
2011-10-19 Nat Duca <nduca@chromium.org>
[chromium] Route requestAnimationFrame through CCProxy in threaded mode
#include <wtf/PassRefPtr.h>
using namespace WebCore;
-using namespace HTMLNames;
namespace WebKit {
bool WebOptionElement::defaultSelected() const
{
- return constUnwrap<HTMLOptionElement>()->hasAttribute(selectedAttr);
+ return constUnwrap<HTMLOptionElement>()->defaultSelected();
}
void WebOptionElement::setDefaultSelected(bool newSelected)
{
- return unwrap<HTMLOptionElement>()->setAttribute(selectedAttr, newSelected ? "" : 0);
+ return unwrap<HTMLOptionElement>()->setDefaultSelected(newSelected);
}
WebString WebOptionElement::label() const
if (!(*i)->hasLocalName(HTMLNames::optionTag))
continue;
HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(*i);
- if (optionElement->selected() != optionElement->hasAttribute(selectedAttr))
+ if (optionElement->selected() != optionElement->defaultSelected())
return false;
}
return true;
if (!(*i)->hasLocalName(HTMLNames::optionTag))
continue;
HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(*i);
- if (optionElement->hasAttribute(selectedAttr)) {
+ if (optionElement->defaultSelected()) {
// The page specified the option to select.
initialSelected = optionElement;
break;