CalendarPickerElement.cpp [plain text]
#include "config.h"
#include "CalendarPickerElement.h"
#if ENABLE(CALENDAR_PICKER)
#include "CalendarPicker.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "DateComponents.h"
#include "Event.h"
#include "FrameView.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "Language.h"
#include "LocalizedDate.h"
#include "LocalizedStrings.h"
#include "Page.h"
#include "RenderDetailsMarker.h"
#include "RenderTheme.h"
#include <wtf/text/StringBuilder.h>
using namespace WTF::Unicode;
namespace WebCore {
using namespace HTMLNames;
inline CalendarPickerElement::CalendarPickerElement(Document* document)
: HTMLDivElement(divTag, document)
, m_popup(0)
{
setShadowPseudoId("-webkit-calendar-picker-indicator");
}
PassRefPtr<CalendarPickerElement> CalendarPickerElement::create(Document* document)
{
return adoptRef(new CalendarPickerElement(document));
}
CalendarPickerElement::~CalendarPickerElement()
{
closePopup();
ASSERT(!m_popup);
}
RenderObject* CalendarPickerElement::createRenderer(RenderArena* arena, RenderStyle*)
{
return new (arena) RenderDetailsMarker(this);
}
inline HTMLInputElement* CalendarPickerElement::hostInput()
{
ASSERT(shadowHost());
ASSERT(shadowHost()->hasTagName(inputTag));
return static_cast<HTMLInputElement*>(shadowHost());
}
void CalendarPickerElement::defaultEventHandler(Event* event)
{
if (!renderer())
return;
HTMLInputElement* input = hostInput();
if (input->readOnly() || input->disabled())
return;
if (event->type() == eventNames().clickEvent) {
openPopup();
event->setDefaultHandled();
}
if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
}
#if !PLATFORM(IOS)
bool CalendarPickerElement::willRespondToMouseClickEvents()
{
const HTMLInputElement* input = hostInput();
if (renderer() && !input->readOnly() && !input->disabled())
return true;
return HTMLDivElement::willRespondToMouseClickEvents();
}
#endif // !PLATFORM(IOS)
void CalendarPickerElement::openPopup()
{
if (m_popup)
return;
if (!document()->page())
return;
Chrome* chrome = document()->page()->chrome();
if (!chrome)
return;
if (!document()->view())
return;
IntRect elementRectInRootView = document()->view()->contentsToRootView(hostInput()->getPixelSnappedRect());
m_popup = chrome->client()->openPagePopup(this, elementRectInRootView);
}
void CalendarPickerElement::closePopup()
{
if (!m_popup)
return;
if (!document()->page())
return;
Chrome* chrome = document()->page()->chrome();
if (!chrome)
return;
chrome->client()->closePagePopup(m_popup);
}
void CalendarPickerElement::detach()
{
closePopup();
HTMLDivElement::detach();
}
IntSize CalendarPickerElement::contentSize()
{
return IntSize(100, 100);
}
void CalendarPickerElement::writeDocument(DocumentWriter& writer)
{
HTMLInputElement* input = hostInput();
DateComponents date;
date.setMillisecondsSinceEpochForDate(input->minimum());
String minString = date.toString();
date.setMillisecondsSinceEpochForDate(input->maximum());
String maxString = date.toString();
Decimal step;
String stepString = input->fastGetAttribute(stepAttr);
if (stepString.isEmpty() || !input->getAllowedValueStep(&step))
stepString = "1";
addString("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", writer);
writer.addData(calendarPickerCss, sizeof(calendarPickerCss));
if (document()->page()) {
CString extraStyle = document()->page()->theme()->extraCalendarPickerStyleSheet();
if (extraStyle.length())
writer.addData(extraStyle.data(), extraStyle.length());
}
addString("</style></head><body><div id=main>Loading...</div><script>\n"
"window.dialogArguments = {\n", writer);
addProperty("min", minString, writer);
addProperty("max", maxString, writer);
addProperty("step", stepString, writer);
addProperty("required", input->required(), writer);
addProperty("currentValue", input->value(), writer);
addProperty("locale", defaultLanguage(), writer);
addProperty("todayLabel", calendarTodayText(), writer);
addProperty("clearLabel", calendarClearText(), writer);
addProperty("weekStartDay", firstDayOfWeek(), writer);
addProperty("monthLabels", monthLabels(), writer);
addProperty("dayLabels", weekDayShortLabels(), writer);
Direction dir = direction(monthLabels()[0][0]);
addProperty("isRTL", dir == RightToLeft || dir == RightToLeftArabic, writer);
addString("}\n", writer);
writer.addData(calendarPickerJs, sizeof(calendarPickerJs));
addString("</script></body>\n", writer);
}
void CalendarPickerElement::setValueAndClosePopup(int numValue, const String& stringValue)
{
ASSERT(m_popup);
closePopup();
if (numValue >= 0)
hostInput()->setValue(stringValue, DispatchChangeEvent);
}
void CalendarPickerElement::didClosePopup()
{
m_popup = 0;
}
}
#endif