Calendar Picker: Resize to minimal size to fit the content
authortkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Apr 2012 01:26:05 +0000 (01:26 +0000)
committertkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 26 Apr 2012 01:26:05 +0000 (01:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=84826

Reviewed by Hajime Morita.

.:

* ManualTests/forms/calendar-picker.html:
Sync with the size specified in CalendarPickerElement.cpp.

Source/WebCore:

Using fixed-size popup isn't nice. The calender picker popup size should
be minimal.

The minimal size depends on font settings, localized labels, and
localized formats. So we put visible objects on a transparent element,
calculate minimal size, resize the popup, then show the objects.

* Resources/calendarPicker.css:
(body): Don't use purple. It was for debugging purpose.
The body is visible for a short period becuse we use transparent element.
(#main):
 - Add nowrap to avoid text wrapping.
 - Add wider width to avoid wrapping.
 - Add opacity to hide incomplete layout.
(.year-month-upper): Don't set flexible box yet.
(.month-selector-box): Fix incorrect display value.
(.days-area):
Don't set table-layout:fixed and width:100% in order that it has the
minimal width.

* Resources/calendarPicker.js:
(initialize): Make a new functio to resize.
(fixWindowSize):
Compute the required width from the right edge of the next year button,
the maximum cell width, and so on.  Then, set CSS properties to have
correct layout.
(YearMonthController.prototype.attachTo):
Set min-width property for a long year-month string.
(YearMonthController.prototype._showPopup):
Center the _monthPopup vertically.

* html/shadow/CalendarPickerElement.cpp:
(WebCore::CalendarPickerElement::contentSize):
Specify small size for the initial size. It's better than showing a
large window then shrink the size.
* page/PagePopupClient.h:
(PagePopupClient): Remove a false comment. We should support resize*().

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@115276 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
ManualTests/forms/calendar-picker.html
Source/WebCore/ChangeLog
Source/WebCore/Resources/calendarPicker.css
Source/WebCore/Resources/calendarPicker.js
Source/WebCore/html/shadow/CalendarPickerElement.cpp
Source/WebCore/page/PagePopupClient.h

index c2abe17..ae00eb4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-04-24  Kent Tamura  <tkent@chromium.org>
+
+        Calendar Picker: Resize to minimal size to fit the content
+        https://bugs.webkit.org/show_bug.cgi?id=84826
+
+        Reviewed by Hajime Morita.
+
+        * ManualTests/forms/calendar-picker.html:
+        Sync with the size specified in CalendarPickerElement.cpp.
+
 2012-04-25  Allan Sandfeld Jensen  <allan.jensen@nokia.com>
 
         [Qt] Zoom back can overscroll document edges.
index c4a7b5b..43eed5c 100644 (file)
@@ -9,8 +9,8 @@ body {
 }
 iframe {
     z-index: 2147483647;
-    width: 290px;
-    height: 256px;
+    width: 100px;
+    height: 100px;
     border: 0;
     overflow: hidden;
 }
index fbfe4ac..30f8fd6 100644 (file)
@@ -1,3 +1,54 @@
+2012-04-24  Kent Tamura  <tkent@chromium.org>
+
+        Calendar Picker: Resize to minimal size to fit the content
+        https://bugs.webkit.org/show_bug.cgi?id=84826
+
+        Reviewed by Hajime Morita.
+
+        Using fixed-size popup isn't nice. The calender picker popup size should
+        be minimal.
+
+        The minimal size depends on font settings, localized labels, and
+        localized formats. So we put visible objects on a transparent element,
+        calculate minimal size, resize the popup, then show the objects.
+
+        * Resources/calendarPicker.css:
+        (body): Don't use purple. It was for debugging purpose.
+        The body is visible for a short period becuse we use transparent element.
+        (#main):
+         - Add nowrap to avoid text wrapping.
+         - Add wider width to avoid wrapping.
+         - Add opacity to hide incomplete layout.
+        (.year-month-upper): Don't set flexible box yet.
+        (.month-selector-box): Fix incorrect display value.
+        (.days-area):
+        Don't set table-layout:fixed and width:100% in order that it has the
+        minimal width.
+
+        * Resources/calendarPicker.js:
+        (initialize): Make a new functio to resize.
+        (fixWindowSize):
+        Compute the required width from the right edge of the next year button,
+        the maximum cell width, and so on.  Then, set CSS properties to have
+        correct layout.
+        (YearMonthController.prototype.attachTo):
+        Set min-width property for a long year-month string.
+        (YearMonthController.prototype._showPopup):
+        Center the _monthPopup vertically.
+
+        * html/shadow/CalendarPickerElement.cpp:
+        (WebCore::CalendarPickerElement::contentSize):
+        Specify small size for the initial size. It's better than showing a
+        large window then shrink the size.
+        * page/PagePopupClient.h:
+        (PagePopupClient): Remove a false comment. We should support resize*().
+
+2012-04-25  Kent Tamura  <tkent@chromium.org>
+
+        Unreviewed. Sort Xcode project file.
+
+        * WebCore.xcodeproj/project.pbxproj:
+
 2012-04-25  Alpha Lam  <hclam@chromium.org>
 
         Unreviewed, rolling out r115260.
index 72b5943..b0737d0 100644 (file)
@@ -30,7 +30,7 @@
 
 body {
     -webkit-user-select: none;
-    background-color: purple;
+    background-color: white;
     font: -webkit-small-control;
     margin: 0;
     overflow: hidden;
@@ -46,13 +46,17 @@ body {
     box-shadow: inset 2px 2px 2px white,
         inset -2px -2px 1px rgba(0,0,0,0.1);
     padding: 6px;
+    whitespace: nowrap;
+    /* width and opacity are reset in the JS code. */
+    width: 500px;
+    opacity: 0;
 }
 
 .year-month-area {
 }
 
 .year-month-upper {
-    display: -webkit-box;
+    /* display:-webkit-box; is added in the JS code. */
 }
 
 .year-selector {
@@ -61,7 +65,7 @@ body {
 }
 
 .month-selector-box {
-    display: inline-box;
+    display: inline-block;
     text-align: center;
     -webkit-box-flex: 2;
 }
@@ -141,8 +145,7 @@ body {
     border-collapse: separate;
     border-spacing: 0px;
     font: -webkit-small-control;
-    table-layout: fixed;
-    width: 100%;
+    /* table-layout:fixed and width:100% are added in the JS code. */
 }
 
 .day-label { /* <th> */
index 621545f..ceeba72 100644 (file)
@@ -286,12 +286,40 @@ function initialize(args) {
             initialDate = global.maximumDate;
         global.daysTable.selectDate(initialDate);
 
-        setTimeout(function() {
-            if (window.frameElement)
-                window.frameElement.style.height = main.offsetHeight + "px";
-            else
-                window.resizeTo(window.outerWidth, main.offsetTop + main.offsetHeight);
-        }, 0);
+        setTimeout(fixWindowSize, 0);
+    }
+}
+
+function fixWindowSize() {
+    var yearMonthRightElement = document.getElementsByClassName(ClassNames.YearMonthButtonRight)[0];
+    var daysAreaElement = document.getElementsByClassName(ClassNames.DaysArea)[0];
+    var headers = daysAreaElement.getElementsByClassName(ClassNames.DayLabel);
+    var maxCellWidth = 0;
+    for (var i = 0; i < headers.length; ++i) {
+        if (maxCellWidth < headers[i].offsetWidth)
+            maxCellWidth = headers[i].offsetWidth;
+    }
+    var DaysAreaContainerBorder = 1;
+    var maxRight = Math.max(yearMonthRightElement.offsetLeft + yearMonthRightElement.offsetWidth,
+                            daysAreaElement.offsetLeft + maxCellWidth * 7 + DaysAreaContainerBorder);
+    var MainPadding = 6;
+    var MainBorder = 1;
+    var desiredBodyWidth = maxRight + MainPadding + MainBorder;
+
+    var main = $("main");
+    var mainHeight = main.offsetHeight;
+    main.style.width = "auto";
+    daysAreaElement.style.width = "100%";
+    daysAreaElement.style.tableLayout = "fixed";
+    document.getElementsByClassName(ClassNames.YearMonthUpper)[0].style.display = "-webkit-box";
+    document.getElementsByClassName(ClassNames.MonthSelectorBox)[0].style.display = "block";
+    main.style.webkitTransition = "opacity 0.1s ease";
+    main.style.opacity = "1";
+    if (window.frameElement) {
+        window.frameElement.style.width = desiredBodyWidth + "px";
+        window.frameElement.style.height = mainHeight + "px";
+    } else {
+        window.resizeTo(desiredBodyWidth, mainHeight);
     }
 }
 
@@ -398,6 +426,16 @@ YearMonthController.prototype.attachTo = function(main) {
     this._wall.addEventListener("click", bind(this._closePopup, this), false);
     main.appendChild(this._wall);
 
+    // The maximum year which <input type=date> supports is 275,760.
+    // See WebCore/platform/DateComponents.h
+    var MaximumYear = 275760;
+    var maxWidth = 0;
+    for (var m = 0; m < 12; ++m) {
+        this._month.textContent = formatYearMonth(MaximumYear, m);
+        maxWidth = Math.max(maxWidth, this._month.offsetWidth);
+    }
+    this._month.style.minWidth = maxWidth + 'px';
+
     global.firstFocusableControl = this._left2; // FIXME: Shoud it be this.month?
 };
 
@@ -513,7 +551,7 @@ YearMonthController.prototype._showPopup = function() {
     this._monthPopup.style.display = "block";
     this._monthPopup.style.position = "absolute";
     this._monthPopup.style.zIndex = "1000"; // Larger than the days area.
-    this._monthPopup.style.left = this._month.offsetLeft + "px";
+    this._monthPopup.style.left = this._month.offsetLeft + (this._month.offsetWidth - this._monthPopup.offsetWidth) / 2 + "px";
     this._monthPopup.style.top = this._month.offsetTop + this._month.offsetHeight + "px";
     this._monthPopup.focus();
 
index c197ac0..79d6c68 100644 (file)
@@ -129,7 +129,7 @@ void CalendarPickerElement::detach()
 
 IntSize CalendarPickerElement::contentSize()
 {
-    return IntSize(320, 256);
+    return IntSize(100, 100);
 }
 
 #define addLiteral(literal, writer)    writer.addData(literal, sizeof(literal) - 1)
index 450c2d7..d329ada 100644 (file)
@@ -48,7 +48,6 @@ public:
     // source is rendered in a PagePopup.
     // The content HTML supports:
     //  - No <select> popups
-    //  - No window.resizeBy() and resizeTo()
     //  - window.setValueAndClosePopup(number, string).
     virtual void writeDocument(DocumentWriter&) = 0;