Changeset 133722 in webkit
- Timestamp:
- Nov 6, 2012 10:29:43 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/ChangeLog
r133678 r133722 1 2012-11-06 Keishi Hattori <keishi@webkit.org> 2 3 Implement month picking to calendar picker 4 https://bugs.webkit.org/show_bug.cgi?id=101333 5 6 Reviewed by Kent Tamura. 7 8 * ManualTests/forms/calendar-picker.html: Added test for month picker. 9 1 10 2012-11-06 Laszlo Gombos <l.gombos@samsung.com> 2 11 -
trunk/ManualTests/forms/calendar-picker.html
r130888 r133722 28 28 <option>Arabic with datalist</option> 29 29 <option>Arabic with long datalist</option> 30 <option>Month</option> 30 31 </select> 31 32 … … 239 240 suggestionHighlightTextColor: "#ffffff" 240 241 }; 242 var monthArguments = { 243 locale: 'en-US', 244 monthLabels : ['January', 'February', 'March', 'April', 'May', 'June', 245 'July', 'August', 'September', 'October', 'November', 'December'], 246 dayLabels : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], 247 todayLabel : 'This Month', 248 clearLabel : 'Clear', 249 cancelLabel : 'Cancel', 250 weekStartDay : 0, 251 step : "1", 252 stepBase: "0", 253 currentValue : '2000-01', 254 max : '2099-03', 255 mode: "month" 256 }; 241 257 242 258 function openCalendar(args) { … … 311 327 openCalendar(arabicLongDatalistArguments); 312 328 break; 329 case 7: 330 openCalendar(monthArguments); 331 break; 313 332 } 314 333 } -
trunk/Source/WebCore/ChangeLog
r133720 r133722 1 2012-11-06 Keishi Hattori <keishi@webkit.org> 2 3 Implement month picking to calendar picker 4 https://bugs.webkit.org/show_bug.cgi?id=101333 5 6 Reviewed by Kent Tamura. 7 8 This adds month picker mode to CalendarPicker. 9 10 No new tests. Tests will be added later when this feature is enabled in DRT. 11 12 * Resources/pagepopups/calendarPicker.css: 13 (.month-mode .day): Remove rounded corners when in month mode. 14 * Resources/pagepopups/calendarPicker.js: 15 (Month.createFromToday): Creates month containing today. 16 (CalendarPicker): Set this.selectionConstructor to Day or Month depending on the mode. Create DayTables or MonthPickerDaysTable depending on the mode. 17 (CalendarPicker.prototype.handleToday): 18 (CalendarPicker.prototype._layoutButtons): 19 (DaysTable.prototype._renderMonth): Set element.dataset.monthValue for all date nodes. 20 (DaysTable.prototype._markRangeAsSelected): Marks all day nodes in range as selected. 21 (DaysTable.prototype.selectRange): Selects a day. 22 (DaysTable.prototype.selectRangeAndShowEntireRange): Same as selectRange. 23 (DaysTable.prototype._selectRangeContainingNode): 24 (DaysTable.prototype._rangeForNode): Returns Day for node. 25 (DaysTable.prototype.startDate): Start datetime of visible date range. This value is inclusive. 26 (DaysTable.prototype.endDate): End datetime of visible date range. This value is exclusive. 27 (DaysTable.prototype._handleKey): 28 (MonthPickerDaysTable): 29 (MonthPickerDaysTable.prototype._markRangeAsSelected): Marks all day nodes in range as selected. 30 (MonthPickerDaysTable.prototype.selectRange): Selects month. If month is not visible, navigates to that month. 31 (MonthPickerDaysTable.prototype.selectRangeAndShowEntireRange): Selects month. Navigates to the month. 32 (MonthPickerDaysTable.prototype._rangeForNode): Returns Month for node. 33 (MonthPickerDaysTable.prototype._handleKey): Arrow keys simply move the selection forwards or backwards. 34 1 35 2012-11-06 Dan Beam <dbeam@chromium.org> 2 36 -
trunk/Source/WebCore/Resources/pagepopups/calendarPicker.css
r132028 r133722 225 225 -webkit-transition: none; 226 226 } 227 228 .month-mode .day { 229 -webkit-transition: none; 230 border-radius: 0; 231 border: 1px solid transparent; 232 } -
trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js
r133565 r133722 47 47 DaysArea: "days-area", 48 48 DaysAreaContainer: "days-area-container", 49 MonthMode: "month-mode", 49 50 MonthSelector: "month-selector", 50 51 MonthSelectorBox: "month-selector-box", … … 215 216 216 217 // See WebCore/platform/DateComponents.h. 217 Day.Minimum = new Da te(-62135596800000.0);218 Day.Maximum = new Da te(8640000000000000.0);218 Day.Minimum = new Day(-62135596800000.0); 219 Day.Maximum = new Day(8640000000000000.0); 219 220 220 221 /** … … 231 232 return new Day(year, month, date); 232 233 }; 234 233 235 /** 234 236 * @param {!Date} date … … 239 241 }; 240 242 243 /** 244 * @return {!Month} 245 */ 241 246 Day.createFromToday = function() { 242 247 var now = new Date(); 243 248 return new Day(now.getFullYear(), now.getMonth(), now.getDate()); 244 } 249 }; 245 250 246 251 /** … … 323 328 324 329 // See WebCore/platform/DateComponents.h. 330 Month.Minimum = new Month(1, 0); 325 331 Month.Maximum = new Month(275760, 8); 326 332 … … 344 350 Month.createFromDate = function(date) { 345 351 return new Month(date.getUTCFullYear(), date.getUTCMonth()); 352 }; 353 354 /** 355 * @return {!Month} 356 */ 357 Month.createFromToday = function() { 358 var now = new Date(); 359 return new Month(now.getFullYear(), now.getMonth()); 346 360 }; 347 361 … … 501 515 function CalendarPicker(element, config) { 502 516 Picker.call(this, element, config); 517 if (this._config.mode === "month") { 518 this.selectionConstructor = Month; 519 this._daysTable = new MonthPickerDaysTable(this); 520 this._element.classList.add(ClassNames.MonthMode); 521 } else { 522 this.selectionConstructor = Day; 523 this._daysTable = new DaysTable(this); 524 } 503 525 this._element.classList.add("calendar-picker"); 504 526 this._element.classList.add("preparing"); 505 527 this._handleWindowResizeBound = this._handleWindowResize.bind(this); 506 528 window.addEventListener("resize", this._handleWindowResizeBound, false); 507 // We assume this._config.min is a valid date. 508 this._minimumValue = (typeof this._config.min !== "undefined") ? parseDateString(this._config.min).valueOf() : Day.Minimum.valueOf(); 509 // We assume this._config.max is a valid date. 510 this._maximumValue = (typeof this._config.max !== "undefined") ? parseDateString(this._config.max).valueOf() : Day.Maximum.valueOf(); 529 // We assume this._config.min/max are valid dates or months. 530 var minimum = (typeof this._config.min !== "undefined") ? parseDateString(this._config.min) : this.selectionConstructor.Minimum; 531 var maximum = (typeof this._config.max !== "undefined") ? parseDateString(this._config.max) : this.selectionConstructor.Maximum; 532 this._minimumValue = minimum.valueOf(); 533 this._maximumValue = maximum.valueOf(); 511 534 this.step = (typeof this._config.step !== undefined) ? Number(this._config.step) : CalendarPicker.DefaultStepScaleFactor; 512 535 this.stepBase = (typeof this._config.stepBase !== "undefined") ? Number(this._config.stepBase) : CalendarPicker.DefaultStepBase; 513 this._minimumMonth = Month.createFromDate( new Date(this._minimumValue));514 this.maximumMonth = Month.createFromDate( new Date(this._maximumValue));536 this._minimumMonth = Month.createFromDate(minimum.startDate()); 537 this.maximumMonth = Month.createFromDate(maximum.startDate()); 515 538 this._currentMonth = new Month(NaN, NaN); 516 539 this._yearMonthController = new YearMonthController(this); 517 this._daysTable = new DaysTable(this);518 540 this._hadKeyEvent = false; 519 541 this._layout(); 520 542 var initialSelection = parseDateString(this._config.currentValue); 521 543 if (!initialSelection) 522 initialSelection = Day.createFromToday();544 initialSelection = this.selectionConstructor.createFromToday(); 523 545 if (initialSelection.valueOf() < this._minimumValue) 524 initialSelection = new Day(this._minimumValue);546 initialSelection = new this.selectionConstructor(this._minimumValue); 525 547 else if (initialSelection.valueOf() > this._maximumValue) 526 initialSelection = new Day(this._maximumValue);548 initialSelection = new this.selectionConstructor(this._maximumValue); 527 549 this.showMonth(Month.createFromDate(initialSelection.startDate()), false); 528 this._daysTable.selectRange (initialSelection);550 this._daysTable.selectRangeAndShowEntireRange(initialSelection); 529 551 this.fixWindowSize(); 530 552 this._handleBodyKeyDownBound = this._handleBodyKeyDown.bind(this); … … 556 578 557 579 CalendarPicker.prototype.handleToday = function() { 558 var today = Day.createFromToday();559 this._daysTable.selectRange (today);580 var today = this.selectionConstructor.createFromToday(); 581 this._daysTable.selectRangeAndShowEntireRange(today); 560 582 this.submitValue(today.toString()); 561 583 }; … … 602 624 var container = createElement("div", ClassNames.TodayClearArea); 603 625 this.today = createElement("input", ClassNames.TodayButton); 626 this.today.disabled = !this.isValidDate(this.selectionConstructor.createFromToday()); 604 627 this.today.type = "button"; 605 628 this.today.value = this._config.todayLabel; … … 1081 1104 element.className = ClassNames.Day; 1082 1105 element.dataset.submitValue = Day.createFromDate(dayIterator).toString(); 1106 element.dataset.monthValue = iterMonth.toString(); 1083 1107 if (isNaN(time)) { 1084 1108 element.innerText = "-"; 1085 1109 element.classList.add(ClassNames.Unavailable); 1086 } else if (!this.picker.isValidDate( Day.createFromDate(dayIterator)))1110 } else if (!this.picker.isValidDate(this._rangeForNode(element))) 1087 1111 element.classList.add(ClassNames.Unavailable); 1088 1112 else if (!iterMonth.equals(month)) { … … 1094 1118 } 1095 1119 } 1096 1097 this.picker.today.disabled = !this.picker.isValidDate(Day.createFromToday().valueOf());1098 1120 }; 1099 1121 … … 1131 1153 1132 1154 /** 1133 * @param {!Date} date 1134 */ 1135 DaysTable.prototype.selectRange = function(day) { 1136 this._deselect(); 1137 this.picker.showMonth(Month.createFromDate(day.startDate()), true); 1155 * @param {!Day} day 1156 */ 1157 DaysTable.prototype._markRangeAsSelected = function(day) { 1138 1158 var dateString = day.toString(); 1139 1159 for (var w = 0; w < DaysTable._Weeks; w++) { … … 1148 1168 1149 1169 /** 1170 * @param {!Day} day 1171 */ 1172 DaysTable.prototype.selectRange = function(day) { 1173 this._deselect(); 1174 if (this.startDate() > day.startDate() || this.endDate() < day.endDate()) 1175 this.picker.showMonth(Month.createFromDate(day.startDate()), false); 1176 this._markRangeAsSelected(day); 1177 }; 1178 1179 /** 1180 * @param {!Day} day 1181 */ 1182 DaysTable.prototype.selectRangeAndShowEntireRange = function(day) { 1183 this.selectRange(day); 1184 }; 1185 1186 /** 1150 1187 * @param {!Element} dayNode 1151 1188 */ 1152 1189 DaysTable.prototype._selectRangeContainingNode = function(dayNode) { 1153 this._deselect();1154 if (! dayNode || !dayNode.classList.contains(ClassNames.Day) || !dayNode.classList.contains(ClassNames.Available))1190 var range = this._rangeForNode(dayNode); 1191 if (!range) 1155 1192 return; 1156 // FIXME: Select date, week or month depending on the config. 1157 dayNode.classList.add(ClassNames.Selected); 1193 this.selectRange(range); 1194 }; 1195 1196 /** 1197 * @param {!Element} dayNode 1198 * @return {?Day} 1199 */ 1200 DaysTable.prototype._rangeForNode = function(dayNode) { 1201 if (!dayNode) 1202 return null; 1203 return Day.parse(dayNode.dataset.submitValue); 1204 }; 1205 1206 /** 1207 * @return {!Date} 1208 */ 1209 DaysTable.prototype.startDate = function() { 1210 return Day.parse(this._days[0][0].dataset.submitValue).startDate(); 1211 }; 1212 1213 /** 1214 * @return {!Date} 1215 */ 1216 DaysTable.prototype.endDate = function() { 1217 return Day.parse(this._days[DaysTable._Weeks - 1][7 - 1].dataset.submitValue).endDate(); 1158 1218 }; 1159 1219 … … 1307 1367 1308 1368 } else if (key == "U+0054") { // 't' 1309 this.selectRange (Day.createFromToday());1369 this.selectRangeAndShowEntireRange(Day.createFromToday()); 1310 1370 event.stopPropagation(); 1311 1371 event.preventDefault(); … … 1322 1382 event.stopPropagation(); 1323 1383 event.preventDefault(); 1384 }; 1385 1386 /** 1387 * @constructor 1388 * @param{!CalendarPicker} picker 1389 */ 1390 function MonthPickerDaysTable(picker) { 1391 DaysTable.call(this, picker); 1392 } 1393 MonthPickerDaysTable.prototype = Object.create(DaysTable.prototype); 1394 1395 /** 1396 * @param {!Month} month 1397 */ 1398 MonthPickerDaysTable.prototype._markRangeAsSelected = function(month) { 1399 var monthString = month.toString(); 1400 for (var w = 0; w < DaysTable._Weeks; w++) { 1401 for (var d = 0; d < 7; d++) { 1402 if (this._days[w][d].dataset.monthValue == monthString) { 1403 this._days[w][d].classList.add(ClassNames.Selected); 1404 } 1405 } 1406 } 1407 }; 1408 1409 /** 1410 * @param {!Month} month 1411 */ 1412 MonthPickerDaysTable.prototype.selectRange = function(month) { 1413 this._deselect(); 1414 if (this.startDate() >= month.endDate() || this.endDate() <= month.startDate()) 1415 this.picker.showMonth(month, true); 1416 this._markRangeAsSelected(month); 1417 }; 1418 1419 /** 1420 * @param {!Month} month 1421 */ 1422 MonthPickerDaysTable.prototype.selectRangeAndShowEntireRange = function(month) { 1423 this._deselect(); 1424 this.picker.showMonth(month, true); 1425 this._markRangeAsSelected(month); 1426 }; 1427 1428 /** 1429 * @param {!Element} dayNode 1430 * @return {?Month} 1431 */ 1432 MonthPickerDaysTable.prototype._rangeForNode = function(dayNode) { 1433 if (!dayNode) 1434 return null; 1435 return Month.parse(dayNode.dataset.monthValue); 1436 }; 1437 1438 /** 1439 * @param {Event} event 1440 */ 1441 MonthPickerDaysTable.prototype._handleKey = function(event) { 1442 this.picker.maybeUpdateFocusStyle(); 1443 var key = event.keyIdentifier; 1444 var eventHandled = false; 1445 var currentMonth = this.picker.currentMonth(); 1446 var firstNodeInSelectedRange = this._firstNodeInSelectedRange(); 1447 if (!firstNodeInSelectedRange 1448 && (key == "Right" || key == "Left" || key == "Up" || key == "Down" || key == "PageUp" || key == "PageDown")) { 1449 this.selectRange(currentMonth); 1450 event.stopPropagation(); 1451 event.preventDefault(); 1452 return; 1453 } 1454 var selectedMonth = this._rangeForNode(firstNodeInSelectedRange); 1455 if (key == (global.params.isCalendarRTL ? "Right" : "Left") || key == "Up" || key == "PageUp") { 1456 if (selectedMonth.valueOf() > currentMonth.valueOf()) 1457 this.selectRangeAndShowEntireRange(currentMonth); 1458 else 1459 this.selectRangeAndShowEntireRange(currentMonth.previous()); 1460 eventHandled = true; 1461 } else if (key == (global.params.isCalendarRTL ? "Left" : "Right") || key == "Down" || key == "PageDown") { 1462 if (selectedMonth.valueOf() < currentMonth.valueOf()) 1463 this.selectRangeAndShowEntireRange(currentMonth); 1464 else 1465 this.selectRangeAndShowEntireRange(currentMonth.next()); 1466 eventHandled = true; 1467 } else if (this._hasSelection() && key == "Enter") { 1468 if (currentSelection) { 1469 this.picker.submitValue(currentSelection.toString()); 1470 eventHandled = true; 1471 } 1472 } else if (key == "U+0054") { // 't' 1473 this.selectRangeAndShowEntireRange(Month.createFromToday()); 1474 eventHandled = true; 1475 } 1476 if (eventHandled) { 1477 event.stopPropagation(); 1478 event.preventDefault(); 1479 } 1324 1480 }; 1325 1481
Note: See TracChangeset
for help on using the changeset viewer.