Diff
Modified: trunk/Source/WebCore/ChangeLog (113415 => 113416)
--- trunk/Source/WebCore/ChangeLog 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebCore/ChangeLog 2012-04-06 07:45:48 UTC (rev 113416)
@@ -1,3 +1,61 @@
+2012-04-06 Kent Tamura <[email protected]>
+
+ Calendar Picker: Add code to open/close the calendar picker
+ https://bugs.webkit.org/show_bug.cgi?id=83258
+
+ Reviewed by Hajime Morita.
+
+ No new tests. This code is not used because of no ENABLE_INPUT_TYPE_DATE.
+
+ * WebCore.gypi: Add existing header files.
+
+ * html/DateInputType.cpp:
+ (WebCore::DateInputType::DateInputType):
+ Moved from DateInputType.h because the constructor depends on
+ CalendarPickerElement.
+ (WebCore::DateInputType::createShadowSubtree):
+ Store a CalendarPickerElement object.
+ (WebCore::DateInputType::destroyShadowSubtree):
+ Release the CalendarPickerElement object.
+ (WebCore::DateInputType::handleBlurEvent):
+ Close the calendar picker when the input loses focus.
+ * html/DateInputType.h:
+ (DateInputType):
+ - Move the constructor definition to DateInputType.cpp
+ - Add function declarations
+ - Add m_pickerElement data member.
+
+ * html/shadow/CalendarPickerElement.cpp:
+ (WebCore::CalendarPickerElement::hostInput): A helper to get the host <input>.
+ (WebCore::CalendarPickerElement::defaultEventHandler):
+ If the element is clicked, open a calendar picker.
+ (WebCore::CalendarPickerElement::openPopup):
+ Opens a calendar picker by ChromeClient::openPagePopup().
+ (WebCore::CalendarPickerElement::closePopup):
+ Closes a calendar picker by ChromeClient::closePagePopup().
+ (WebCore::CalendarPickerElement::detach):
+ Closes a calendar picker when the element loses a renderer.
+
+ (WebCore::CalendarPickerElement::contentSize):
+ Provides the initial size of a popup.
+ (WebCore::addString): A helper for writeDocument().
+ (WebCore::addJavaScriptString): ditto.
+ (WebCore::addProperty): ditto.
+ (WebCore::CalendarPickerElement::writeDocument):
+ Provides the source of a popup. The function creates a complete HTML with:
+ - WebCore/Resources/calendarPicker.css
+ - WebCore/Resources/calendarPicker.js
+ - An object to pass localization strings and <input> state
+ (WebCore::CalendarPickerElement::setValueAndClosePopup):
+ Sets the value from a calendar picker to the <input>.
+ (WebCore::CalendarPickerElement::didClosePopup):
+ Clear the popup object.
+ * html/shadow/CalendarPickerElement.h:
+ (CalendarPickerElement): Add declarations.
+
+ * platform/text/LocalizedCalendarICU.cpp:
+ (WebCore::getFirstDayOfWeek): Make sure this is 0-base. UCAL_SUNDAY is 1.
+
2012-04-05 Adele Peterson <[email protected]>
<rdar://problem/11133179> and https://bugs.webkit.org/show_bug.cgi?id=74129
Modified: trunk/Source/WebCore/WebCore.gypi (113415 => 113416)
--- trunk/Source/WebCore/WebCore.gypi 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebCore/WebCore.gypi 2012-04-06 07:45:48 UTC (rev 113416)
@@ -238,6 +238,8 @@
'page/MemoryInfo.h',
'page/Page.h',
'page/PageGroup.h',
+ 'page/PagePopup.h',
+ 'page/PagePopupClient.h',
'page/PageSerializer.h',
'page/PageVisibilityState.h',
'page/PrintContext.h',
Modified: trunk/Source/WebCore/html/DateInputType.cpp (113415 => 113416)
--- trunk/Source/WebCore/html/DateInputType.cpp 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebCore/html/DateInputType.cpp 2012-04-06 07:45:48 UTC (rev 113416)
@@ -46,6 +46,11 @@
static const double dateDefaultStep = 1.0;
static const double dateStepScaleFactor = 86400000.0;
+inline DateInputType::DateInputType(HTMLInputElement* element)
+ : BaseDateAndTimeInputType(element)
+{
+}
+
PassOwnPtr<InputType> DateInputType::create(HTMLInputElement* element)
{
return adoptPtr(new DateInputType(element));
@@ -103,9 +108,16 @@
void DateInputType::createShadowSubtree()
{
BaseDateAndTimeInputType::createShadowSubtree();
- containerElement()->insertBefore(CalendarPickerElement::create(element()->document()), innerBlockElement()->nextSibling(), ASSERT_NO_EXCEPTION);
+ m_pickerElement = CalendarPickerElement::create(element()->document());
+ containerElement()->insertBefore(m_pickerElement.get(), innerBlockElement()->nextSibling(), ASSERT_NO_EXCEPTION);
}
+void DateInputType::destroyShadowSubtree()
+{
+ TextFieldInputType::destroyShadowSubtree();
+ m_pickerElement.clear();
+}
+
bool DateInputType::needsContainer() const
{
return true;
@@ -115,6 +127,12 @@
{
return false;
}
+
+void DateInputType::handleBlurEvent()
+{
+ if (m_pickerElement)
+ m_pickerElement->closePopup();
+}
#endif // ENABLE(CALENDAR_PICKER)
} // namespace WebCore
Modified: trunk/Source/WebCore/html/DateInputType.h (113415 => 113416)
--- trunk/Source/WebCore/html/DateInputType.h 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebCore/html/DateInputType.h 2012-04-06 07:45:48 UTC (rev 113416)
@@ -32,17 +32,20 @@
#define DateInputType_h
#include "BaseDateAndTimeInputType.h"
+#include <wtf/RefPtr.h>
#if ENABLE(INPUT_TYPE_DATE)
namespace WebCore {
+class CalendarPickerElement;
+
class DateInputType : public BaseDateAndTimeInputType {
public:
static PassOwnPtr<InputType> create(HTMLInputElement*);
private:
- DateInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
+ DateInputType(HTMLInputElement*);
virtual const AtomicString& formControlType() const OVERRIDE;
virtual DateComponents::Type dateType() const OVERRIDE;
virtual double minimum() const OVERRIDE;
@@ -54,10 +57,14 @@
virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
#if ENABLE(CALENDAR_PICKER)
virtual void createShadowSubtree() OVERRIDE;
+ virtual void destroyShadowSubtree() OVERRIDE;
+ virtual void handleBlurEvent() OVERRIDE;
// TextFieldInputType functions
virtual bool needsContainer() const OVERRIDE;
virtual bool shouldHaveSpinButton() const OVERRIDE;
+
+ RefPtr<CalendarPickerElement> m_pickerElement;
#endif
};
Modified: trunk/Source/WebCore/html/shadow/CalendarPickerElement.cpp (113415 => 113416)
--- trunk/Source/WebCore/html/shadow/CalendarPickerElement.cpp 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebCore/html/shadow/CalendarPickerElement.cpp 2012-04-06 07:45:48 UTC (rev 113416)
@@ -33,8 +33,21 @@
#if ENABLE(CALENDAR_PICKER)
+#include "CalendarPicker.h"
+#include "Chrome.h"
+#include "ChromeClient.h"
+#include "DateComponents.h"
+#include "DocumentWriter.h"
+#include "Event.h"
+#include "FrameView.h"
+#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include "Language.h"
+#include "LocalizedCalendar.h"
+#include "LocalizedStrings.h"
+#include "Page.h"
#include "RenderDetailsMarker.h"
+#include <wtf/text/StringBuilder.h>
namespace WebCore {
@@ -56,6 +69,155 @@
return new (arena) RenderDetailsMarker(this);
}
+inline HTMLInputElement* CalendarPickerElement::hostInput()
+{
+ ASSERT(shadowAncestorNode());
+ ASSERT(shadowAncestorNode()->hasTagName(inputTag));
+ return static_cast<HTMLInputElement*>(shadowAncestorNode());
}
+void CalendarPickerElement::defaultEventHandler(Event* event)
+{
+ HTMLInputElement* input = hostInput();
+ if (input->readOnly() || input->disabled())
+ return;
+
+ if (event->type() == eventNames().clickEvent) {
+ openPopup();
+ event->setDefaultHandled();
+ }
+
+ if (!event->defaultHandled())
+ HTMLDivElement::defaultEventHandler(event);
+}
+
+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()->getRect());
+ 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(320, 256);
+}
+
+#define addLiteral(literal, writer) writer.addData(literal, sizeof(literal) - 1)
+
+static inline void addString(const String& str, DocumentWriter& writer)
+{
+ CString str8 = str.utf8();
+ writer.addData(str8.data(), str8.length());
+}
+
+static void addJavaScriptString(const String& str, DocumentWriter& writer)
+{
+ addLiteral("\"", writer);
+ StringBuilder builder;
+ builder.reserveCapacity(str.length());
+ for (unsigned i = 0; i < str.length(); ++i) {
+ if (str[i] == '\\' || str[i] == '"')
+ builder.append('\\');
+ builder.append(str[i]);
+ }
+ addString(builder.toString(), writer);
+ addLiteral("\"", writer);
+}
+
+static void addProperty(const char* name, const String& value, DocumentWriter& writer)
+{
+ writer.addData(name, strlen(name));
+ addLiteral(": ", writer);
+ addJavaScriptString(value, writer);
+ addLiteral(",\n", writer);
+}
+
+static void addProperty(const char* name, const Vector<String>& values, DocumentWriter& writer)
+{
+ writer.addData(name, strlen(name));
+ addLiteral(": [", writer);
+ for (unsigned i = 0; i < values.size(); ++i) {
+ if (i)
+ addLiteral(",", writer);
+ addJavaScriptString(values[i], writer);
+ }
+ addLiteral("],\n", writer);
+}
+
+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();
+ double step;
+ String stepString = input->fastGetAttribute(stepAttr);
+ if (stepString.isEmpty() || !input->getAllowedValueStep(&step))
+ stepString = "1";
+
+ addLiteral("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", writer);
+ writer.addData(calendarPickerCss, sizeof(calendarPickerCss));
+ addLiteral("</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() ? "true" : "false", writer);
+ addProperty("currentValue", input->value(), writer);
+ addProperty("locale", defaultLanguage(), writer);
+ addProperty("todayLabel", calendarTodayText(), writer);
+ addProperty("clearLabel", calendarClearText(), writer);
+ addProperty("weekStartDay", String::number(firstDayOfWeek()), writer);
+ addProperty("monthLabels", monthLabels(), writer);
+ addProperty("dayLabels", weekDayShortLabels(), writer);
+ addLiteral("}\n", writer);
+
+ writer.addData(calendarPickerJs, sizeof(calendarPickerJs));
+ addLiteral("</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
Modified: trunk/Source/WebCore/html/shadow/CalendarPickerElement.h (113415 => 113416)
--- trunk/Source/WebCore/html/shadow/CalendarPickerElement.h 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebCore/html/shadow/CalendarPickerElement.h 2012-04-06 07:45:48 UTC (rev 113416)
@@ -31,19 +31,38 @@
#ifndef CalendarPickerElement_h
#define CalendarPickerElement_h
+#if ENABLE(CALENDAR_PICKER)
#include "HTMLDivElement.h"
+#include "PagePopupClient.h"
namespace WebCore {
-class CalendarPickerElement : public HTMLDivElement {
+class HTMLInputElement;
+class PagePopup;
+
+class CalendarPickerElement : public HTMLDivElement, public PagePopupClient {
public:
static PassRefPtr<CalendarPickerElement> create(Document*);
+ void closePopup();
private:
CalendarPickerElement(Document*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) OVERRIDE;
- // FIXME: add click handling.
+ virtual void defaultEventHandler(Event*) OVERRIDE;
+ virtual void detach() OVERRIDE;
+
+ // PagePopupClient functions:
+ virtual IntSize contentSize() OVERRIDE;
+ virtual void writeDocument(DocumentWriter&) OVERRIDE;
+ virtual void setValueAndClosePopup(int, const String&) OVERRIDE;
+ virtual void didClosePopup() OVERRIDE;
+
+ HTMLInputElement* hostInput();
+ void openPopup();
+
+ PagePopup* m_popup;
};
}
#endif
+#endif
Modified: trunk/Source/WebCore/platform/text/LocalizedCalendarICU.cpp (113415 => 113416)
--- trunk/Source/WebCore/platform/text/LocalizedCalendarICU.cpp 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebCore/platform/text/LocalizedCalendarICU.cpp 2012-04-06 07:45:48 UTC (rev 113416)
@@ -147,7 +147,7 @@
ScopedDateFormat dateFormat;
if (!dateFormat.get())
return 0;
- unsigned firstDay = ucal_getAttribute(udat_getCalendar(dateFormat.get()), UCAL_FIRST_DAY_OF_WEEK);
+ unsigned firstDay = ucal_getAttribute(udat_getCalendar(dateFormat.get()), UCAL_FIRST_DAY_OF_WEEK) - UCAL_SUNDAY;
return firstDay;
}
Modified: trunk/Source/WebKit/chromium/ChangeLog (113415 => 113416)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-04-06 07:45:48 UTC (rev 113416)
@@ -1,3 +1,18 @@
+2012-04-06 Kent Tamura <[email protected]>
+
+ Calendar Picker: Add code to open/close the calendar picker
+ https://bugs.webkit.org/show_bug.cgi?id=83258
+
+ Reviewed by Hajime Morita.
+
+ * features.gypi: Enable ENABLE_PAGE_POPUP for non-Android
+ platforms. This is needed because ENABLE_CALENDAR_PICKER now depends on
+ ENABLE_PAGE_POPUP.
+ * src/ChroemClientImpl.cpp: Add stubs.
+ (WebKit::ChromeClientImpl::openPagePopup):
+ (WebKit::ChromeClientImpl::closePagePopup):
+ * src/ChromeClientImpl.h: Add declarations of openPagePopup() and closePagePopup().
+
2012-04-05 Hironori Bono <[email protected]>
[Chromium] moving a cursor on a misspelled word should not remove a misspelled underline
Modified: trunk/Source/WebKit/chromium/features.gypi (113415 => 113416)
--- trunk/Source/WebKit/chromium/features.gypi 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebKit/chromium/features.gypi 2012-04-06 07:45:48 UTC (rev 113416)
@@ -130,11 +130,13 @@
['OS=="android"', {
'feature_defines': [
'ENABLE_CALENDAR_PICKER=0',
+ 'ENABLE_PAGE_POPUP=0',
'ENABLE_WEB_AUDIO=0',
],
}, {
'feature_defines': [
'ENABLE_CALENDAR_PICKER=1',
+ 'ENABLE_PAGE_POPUP=1',
'ENABLE_WEB_AUDIO=1',
],
}],
Modified: trunk/Source/WebKit/chromium/src/ChromeClientImpl.cpp (113415 => 113416)
--- trunk/Source/WebKit/chromium/src/ChromeClientImpl.cpp 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebKit/chromium/src/ChromeClientImpl.cpp 2012-04-06 07:45:48 UTC (rev 113416)
@@ -988,6 +988,19 @@
return adoptRef(new SearchPopupMenuChromium(client));
}
+#if ENABLE(PAGE_POPUP)
+PagePopup* ChromeClientImpl::openPagePopup(PagePopupClient*, const IntRect&)
+{
+ // FIXME: Impelement this.
+ return 0;
+}
+
+void ChromeClientImpl::closePagePopup(PagePopup*)
+{
+ // FIXME: Implement this.
+}
+#endif
+
bool ChromeClientImpl::willAddTextFieldDecorationsTo(HTMLInputElement* input)
{
ASSERT(input);
Modified: trunk/Source/WebKit/chromium/src/ChromeClientImpl.h (113415 => 113416)
--- trunk/Source/WebKit/chromium/src/ChromeClientImpl.h 2012-04-06 05:23:25 UTC (rev 113415)
+++ trunk/Source/WebKit/chromium/src/ChromeClientImpl.h 2012-04-06 07:45:48 UTC (rev 113416)
@@ -195,6 +195,10 @@
virtual bool hasOpenedPopup() const OVERRIDE;
virtual PassRefPtr<WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const;
virtual PassRefPtr<WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const;
+#if ENABLE(PAGE_POPUP)
+ virtual WebCore::PagePopup* openPagePopup(WebCore::PagePopupClient*, const WebCore::IntRect&) OVERRIDE;
+ virtual void closePagePopup(WebCore::PagePopup*) OVERRIDE;
+#endif
virtual bool willAddTextFieldDecorationsTo(WebCore::HTMLInputElement*) OVERRIDE;
virtual void addTextFieldDecorationsTo(WebCore::HTMLInputElement*) OVERRIDE;