DeprecatedRenderSelect.cpp [plain text]
#include "config.h"
#include "DeprecatedRenderSelect.h"
#include "HTMLNames.h"
#include "HTMLOptGroupElement.h"
#include "HTMLOptionElement.h"
#include "HTMLSelectElement.h"
#include "PopUpButton.h"
using std::min;
namespace WebCore {
using namespace HTMLNames;
DeprecatedRenderSelect::DeprecatedRenderSelect(HTMLSelectElement* element)
: RenderFormElement(element)
, m_size(element->size())
, m_multiple(element->multiple())
, m_selectionChanged(true)
, m_ignoreSelectEvents(false)
, m_optionsChanged(true)
{
setWidget(createListBox());
}
void DeprecatedRenderSelect::setWidgetWritingDirection()
{
TextDirection d = style()->direction() == RTL ? RTL : LTR;
static_cast<ListBox*>(m_widget)->setWritingDirection(d);
}
void DeprecatedRenderSelect::setStyle(RenderStyle* s)
{
RenderFormElement::setStyle(s);
setWidgetWritingDirection();
}
void DeprecatedRenderSelect::updateFromElement()
{
m_ignoreSelectEvents = true;
bool oldMultiple = m_multiple;
m_multiple = static_cast<HTMLSelectElement*>(node())->multiple();
if (oldMultiple != m_multiple) {
static_cast<ListBox*>(m_widget)->setSelectionMode(m_multiple ? ListBox::Extended : ListBox::Single);
m_selectionChanged = true;
m_optionsChanged = true;
}
if (m_optionsChanged) {
static_cast<HTMLSelectElement*>(node())->recalcListItems();
const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(node())->listItems();
int listIndex;
static_cast<ListBox*>(m_widget)->clear();
bool groupEnabled = true;
for (listIndex = 0; listIndex < int(listItems.size()); listIndex++) {
if (listItems[listIndex]->hasTagName(optgroupTag)) {
HTMLOptGroupElement* optgroupElement = static_cast<HTMLOptGroupElement*>(listItems[listIndex]);
DeprecatedString label = optgroupElement->getAttribute(labelAttr).deprecatedString();
label.replace('\\', backslashAsCurrencySymbol());
label = label.stripWhiteSpace();
label = label.simplifyWhiteSpace();
groupEnabled = optgroupElement->isEnabled();
static_cast<ListBox*>(m_widget)->appendGroupLabel(label, groupEnabled);
} else if (listItems[listIndex]->hasTagName(optionTag)) {
HTMLOptionElement* optionElement = static_cast<HTMLOptionElement*>(listItems[listIndex]);
DeprecatedString itemText = optionElement->text().deprecatedString();
if (itemText.isEmpty())
itemText = optionElement->getAttribute(labelAttr).deprecatedString();
itemText.replace('\\', backslashAsCurrencySymbol());
itemText = itemText.stripWhiteSpace();
itemText = itemText.simplifyWhiteSpace();
if (listItems[listIndex]->parentNode()->hasTagName(optgroupTag))
itemText.prepend(" ");
static_cast<ListBox*>(m_widget)->appendItem(itemText, groupEnabled && optionElement->isEnabled());
} else
ASSERT(false);
m_selectionChanged = true;
}
static_cast<ListBox*>(m_widget)->doneAppendingItems();
setNeedsLayoutAndMinMaxRecalc();
m_optionsChanged = false;
}
if (m_selectionChanged)
updateSelection();
m_ignoreSelectEvents = false;
RenderFormElement::updateFromElement();
}
short DeprecatedRenderSelect::baselinePosition(bool f, bool isRootLineBox) const
{
return RenderWidget::baselinePosition(f, isRootLineBox) - 7;
}
void DeprecatedRenderSelect::calcMinMaxWidth()
{
ASSERT(!minMaxKnown());
if (m_optionsChanged)
updateFromElement();
setMinMaxKnown();
layoutIfNeeded();
setNeedsLayoutAndMinMaxRecalc();
RenderFormElement::calcMinMaxWidth();
}
void DeprecatedRenderSelect::layout()
{
ASSERT(needsLayout());
ASSERT(minMaxKnown());
ListBox* w = static_cast<ListBox*>(m_widget);
int size = m_size;
if (size < 1)
size = min(static_cast<ListBox*>(m_widget)->count(), 10U);
IntSize s(w->sizeForNumberOfLines(size));
setIntrinsicWidth(s.width());
setIntrinsicHeight(s.height());
RenderFormElement::layout();
const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(node())->listItems();
bool foundOption = false;
for (unsigned i = 0; i < listItems.size() && !foundOption; i++)
foundOption = (listItems[i]->hasTagName(optionTag));
m_widget->setEnabled(foundOption && ! static_cast<HTMLSelectElement*>(node())->disabled());
}
void DeprecatedRenderSelect::selectionChanged(Widget*)
{
if (m_ignoreSelectEvents)
return;
const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(node())->m_listItems;
int j = 0;
unsigned size = listItems.size();
for (unsigned i = 0; i < size; i++) {
if (listItems[i]->hasTagName(optionTag))
static_cast<HTMLOptionElement*>(listItems[i])
->m_selected = static_cast<ListBox*>(m_widget)->isSelected(j);
if (listItems[i]->hasTagName(optionTag) || listItems[i]->hasTagName(optgroupTag))
++j;
}
static_cast<HTMLSelectElement*>(node())->onChange();
}
void DeprecatedRenderSelect::setOptionsChanged(bool _optionsChanged)
{
m_optionsChanged = _optionsChanged;
}
ListBox* DeprecatedRenderSelect::createListBox()
{
ListBox *lb = new ListBox();
lb->setSelectionMode(m_multiple ? ListBox::Extended : ListBox::Single);
m_ignoreSelectEvents = false;
return lb;
}
void DeprecatedRenderSelect::updateSelection()
{
const Vector<HTMLElement*>& listItems = static_cast<HTMLSelectElement*>(node())->listItems();
int i;
ListBox *listBox = static_cast<ListBox*>(m_widget);
int j = 0;
for (i = 0; i < int(listItems.size()); i++) {
listBox->setSelected(j, listItems[i]->hasTagName(optionTag) &&
static_cast<HTMLOptionElement*>(listItems[i])->selected());
if (listItems[i]->hasTagName(optionTag) || listItems[i]->hasTagName(optgroupTag))
++j;
}
m_selectionChanged = false;
}
}