| OLD | NEW |
| 1 "use strict"; | 1 "use strict"; |
| 2 /* | 2 /* |
| 3 * Copyright (C) 2012 Google Inc. All rights reserved. | 3 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 YearMonthButtonLeft: "year-month-button-left", | 65 YearMonthButtonLeft: "year-month-button-left", |
| 66 YearMonthButtonRight: "year-month-button-right", | 66 YearMonthButtonRight: "year-month-button-right", |
| 67 YearMonthUpper: "year-month-upper" | 67 YearMonthUpper: "year-month-upper" |
| 68 }; | 68 }; |
| 69 | 69 |
| 70 /** | 70 /** |
| 71 * @type {Object} | 71 * @type {Object} |
| 72 */ | 72 */ |
| 73 var global = { | 73 var global = { |
| 74 argumentsReceived: false, | 74 argumentsReceived: false, |
| 75 hadKeyEvent: false, | |
| 76 params: null | 75 params: null |
| 77 }; | 76 }; |
| 78 | 77 |
| 79 // ---------------------------------------------------------------- | 78 // ---------------------------------------------------------------- |
| 80 // Utility functions | 79 // Utility functions |
| 81 | 80 |
| 82 /** | 81 /** |
| 83 * @return {!string} lowercase locale name. e.g. "en-us" | 82 * @return {!string} lowercase locale name. e.g. "en-us" |
| 84 */ | 83 */ |
| 85 function getLocale() { | 84 function getLocale() { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 if (args.weekStartDay < 0 || args.weekStartDay > 6) | 259 if (args.weekStartDay < 0 || args.weekStartDay > 6) |
| 261 return "Invalid weekStartDay: " + args.weekStartDay; | 260 return "Invalid weekStartDay: " + args.weekStartDay; |
| 262 } | 261 } |
| 263 return null; | 262 return null; |
| 264 } | 263 } |
| 265 | 264 |
| 266 /** | 265 /** |
| 267 * @param {!Object} args | 266 * @param {!Object} args |
| 268 */ | 267 */ |
| 269 function initialize(args) { | 268 function initialize(args) { |
| 270 var main = $("main"); | |
| 271 main.classList.add(ClassNames.NoFocusRing); | |
| 272 | |
| 273 var errorString = validateArguments(args); | 269 var errorString = validateArguments(args); |
| 274 if (errorString) { | 270 if (errorString) { |
| 271 var main = $("main"); |
| 275 main.textContent = "Internal error: " + errorString; | 272 main.textContent = "Internal error: " + errorString; |
| 276 resizeWindow(main.offsetWidth, main.offsetHeight); | 273 resizeWindow(main.offsetWidth, main.offsetHeight); |
| 277 } else { | 274 } else { |
| 278 global.params = args; | 275 global.params = args; |
| 279 openCalendarPicker(); | 276 openCalendarPicker(); |
| 280 } | 277 } |
| 281 } | 278 } |
| 282 | 279 |
| 283 function resetMain() { | 280 function resetMain() { |
| 284 var main = $("main"); | 281 var main = $("main"); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 298 */ | 295 */ |
| 299 function CalendarPicker(element, config) { | 296 function CalendarPicker(element, config) { |
| 300 Picker.call(this, element, config); | 297 Picker.call(this, element, config); |
| 301 // We assume this._config.min is a valid date. | 298 // We assume this._config.min is a valid date. |
| 302 this.minimumDate = (typeof this._config.min !== "undefined") ? parseDateStri
ng(this._config.min) : CalendarPicker.MinimumPossibleDate; | 299 this.minimumDate = (typeof this._config.min !== "undefined") ? parseDateStri
ng(this._config.min) : CalendarPicker.MinimumPossibleDate; |
| 303 // We assume this._config.max is a valid date. | 300 // We assume this._config.max is a valid date. |
| 304 this.maximumDate = (typeof this._config.max !== "undefined") ? parseDateStri
ng(this._config.max) : CalendarPicker.MaximumPossibleDate; | 301 this.maximumDate = (typeof this._config.max !== "undefined") ? parseDateStri
ng(this._config.max) : CalendarPicker.MaximumPossibleDate; |
| 305 this.step = (typeof this._config.step !== undefined) ? this._config.step * C
alendarPicker.BaseStep : CalendarPicker.BaseStep; | 302 this.step = (typeof this._config.step !== undefined) ? this._config.step * C
alendarPicker.BaseStep : CalendarPicker.BaseStep; |
| 306 this.yearMonthController = new YearMonthController(this); | 303 this.yearMonthController = new YearMonthController(this); |
| 307 this.daysTable = new DaysTable(this); | 304 this.daysTable = new DaysTable(this); |
| 305 this._hadKeyEvent = false; |
| 308 this._layout(); | 306 this._layout(); |
| 309 var initialDate = parseDateString(this._config.currentValue); | 307 var initialDate = parseDateString(this._config.currentValue); |
| 310 if (initialDate < this.minimumDate) | 308 if (initialDate < this.minimumDate) |
| 311 initialDate = this.minimumDate; | 309 initialDate = this.minimumDate; |
| 312 else if (initialDate > this.maximumDate) | 310 else if (initialDate > this.maximumDate) |
| 313 initialDate = this.maximumDate; | 311 initialDate = this.maximumDate; |
| 314 this.daysTable.selectDate(initialDate); | 312 this.daysTable.selectDate(initialDate); |
| 315 this.fixWindowSize(); | 313 this.fixWindowSize(); |
| 316 document.body.addEventListener("keydown", this._handleBodyKeyDown.bind(this)
, false); | 314 document.body.addEventListener("keydown", this._handleBodyKeyDown.bind(this)
, false); |
| 317 } | 315 } |
| 318 CalendarPicker.prototype = Object.create(Picker.prototype); | 316 CalendarPicker.prototype = Object.create(Picker.prototype); |
| 319 | 317 |
| 320 // Hard limits of type=date. See WebCore/platform/DateComponents.h. | 318 // Hard limits of type=date. See WebCore/platform/DateComponents.h. |
| 321 CalendarPicker.MinimumPossibleDate = new Date(-62135596800000.0); | 319 CalendarPicker.MinimumPossibleDate = new Date(-62135596800000.0); |
| 322 CalendarPicker.MaximumPossibleDate = new Date(8640000000000000.0); | 320 CalendarPicker.MaximumPossibleDate = new Date(8640000000000000.0); |
| 323 // See WebCore/html/DateInputType.cpp. | 321 // See WebCore/html/DateInputType.cpp. |
| 324 CalendarPicker.BaseStep = 86400000; | 322 CalendarPicker.BaseStep = 86400000; |
| 325 | 323 |
| 326 CalendarPicker.prototype._layout = function() { | 324 CalendarPicker.prototype._layout = function() { |
| 327 this._element.style.direction = global.params.isRTL ? "rtl" : "ltr"; | 325 this._element.style.direction = global.params.isRTL ? "rtl" : "ltr"; |
| 328 this.yearMonthController.attachTo(this._element); | 326 this.yearMonthController.attachTo(this._element); |
| 329 this.daysTable.attachTo(this._element); | 327 this.daysTable.attachTo(this._element); |
| 330 this._layoutButtons(); | 328 this._layoutButtons(); |
| 329 // DaysTable will have focus but we don't want to show its focus ring until
the first key event. |
| 330 this._element.classList.add(ClassNames.NoFocusRing); |
| 331 }; | 331 }; |
| 332 | 332 |
| 333 CalendarPicker.prototype.handleToday = function() { | 333 CalendarPicker.prototype.handleToday = function() { |
| 334 var date = new Date(); | 334 var date = new Date(); |
| 335 this.daysTable.selectDate(date); | 335 this.daysTable.selectDate(date); |
| 336 this.submitValue(serializeDate(date.getFullYear(), date.getMonth(), date.get
Date())); | 336 this.submitValue(serializeDate(date.getFullYear(), date.getMonth(), date.get
Date())); |
| 337 }; | 337 }; |
| 338 | 338 |
| 339 CalendarPicker.prototype.handleClear = function() { | 339 CalendarPicker.prototype.handleClear = function() { |
| 340 this.submitValue(""); | 340 this.submitValue(""); |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 if (this._hasSelection()) | 1049 if (this._hasSelection()) |
| 1050 this._days[this._y][this._x].classList.remove(ClassNames.Selected); | 1050 this._days[this._y][this._x].classList.remove(ClassNames.Selected); |
| 1051 this._x = -1; | 1051 this._x = -1; |
| 1052 this._y = -1; | 1052 this._y = -1; |
| 1053 }; | 1053 }; |
| 1054 | 1054 |
| 1055 /** | 1055 /** |
| 1056 * @param {Event} event | 1056 * @param {Event} event |
| 1057 */ | 1057 */ |
| 1058 DaysTable.prototype._handleKey = function(event) { | 1058 DaysTable.prototype._handleKey = function(event) { |
| 1059 maybeUpdateFocusStyle(); | 1059 this.picker.maybeUpdateFocusStyle(); |
| 1060 var x = this._x; | 1060 var x = this._x; |
| 1061 var y = this._y; | 1061 var y = this._y; |
| 1062 var key = event.keyIdentifier; | 1062 var key = event.keyIdentifier; |
| 1063 if (!this._hasSelection() && (key == "Left" || key == "Up" || key == "Right"
|| key == "Down")) { | 1063 if (!this._hasSelection() && (key == "Left" || key == "Up" || key == "Right"
|| key == "Down")) { |
| 1064 // Put the selection on a center cell. | 1064 // Put the selection on a center cell. |
| 1065 this.updateSelection(event, 3, Math.floor(DaysTable._Weeks / 2 - 1)); | 1065 this.updateSelection(event, 3, Math.floor(DaysTable._Weeks / 2 - 1)); |
| 1066 return; | 1066 return; |
| 1067 } | 1067 } |
| 1068 | 1068 |
| 1069 if (key == (global.params.isRTL ? "Right" : "Left")) { | 1069 if (key == (global.params.isRTL ? "Right" : "Left")) { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1149 this._y = y; | 1149 this._y = y; |
| 1150 } | 1150 } |
| 1151 event.stopPropagation(); | 1151 event.stopPropagation(); |
| 1152 event.preventDefault(); | 1152 event.preventDefault(); |
| 1153 }; | 1153 }; |
| 1154 | 1154 |
| 1155 /** | 1155 /** |
| 1156 * @param {!Event} event | 1156 * @param {!Event} event |
| 1157 */ | 1157 */ |
| 1158 CalendarPicker.prototype._handleBodyKeyDown = function(event) { | 1158 CalendarPicker.prototype._handleBodyKeyDown = function(event) { |
| 1159 maybeUpdateFocusStyle(); | 1159 this.maybeUpdateFocusStyle(); |
| 1160 var key = event.keyIdentifier; | 1160 var key = event.keyIdentifier; |
| 1161 if (key == "U+0009") { | 1161 if (key == "U+0009") { |
| 1162 if (!event.shiftKey && document.activeElement == global.lastFocusableCon
trol) { | 1162 if (!event.shiftKey && document.activeElement == global.lastFocusableCon
trol) { |
| 1163 event.stopPropagation(); | 1163 event.stopPropagation(); |
| 1164 event.preventDefault(); | 1164 event.preventDefault(); |
| 1165 this.firstFocusableControl.focus(); | 1165 this.firstFocusableControl.focus(); |
| 1166 } else if (event.shiftKey && document.activeElement == global.firstFocus
ableControl) { | 1166 } else if (event.shiftKey && document.activeElement == global.firstFocus
ableControl) { |
| 1167 event.stopPropagation(); | 1167 event.stopPropagation(); |
| 1168 event.preventDefault(); | 1168 event.preventDefault(); |
| 1169 this.lastFocusableControl.focus(); | 1169 this.lastFocusableControl.focus(); |
| 1170 } | 1170 } |
| 1171 } else if (key == "U+004D") { // 'm' | 1171 } else if (key == "U+004D") { // 'm' |
| 1172 this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthContro
ller.PreviousMonth : YearMonthController.NextMonth); | 1172 this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthContro
ller.PreviousMonth : YearMonthController.NextMonth); |
| 1173 } else if (key == "U+0059") { // 'y' | 1173 } else if (key == "U+0059") { // 'y' |
| 1174 this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthContro
ller.PreviousYear : YearMonthController.NextYear); | 1174 this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthContro
ller.PreviousYear : YearMonthController.NextYear); |
| 1175 } else if (key == "U+0044") { // 'd' | 1175 } else if (key == "U+0044") { // 'd' |
| 1176 this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthContro
ller.PreviousTenYears : YearMonthController.NextTenYears); | 1176 this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthContro
ller.PreviousTenYears : YearMonthController.NextTenYears); |
| 1177 } else if (key == "U+001B") // ESC | 1177 } else if (key == "U+001B") // ESC |
| 1178 this.handleCancel(); | 1178 this.handleCancel(); |
| 1179 } | 1179 } |
| 1180 | 1180 |
| 1181 function maybeUpdateFocusStyle() { | 1181 CalendarPicker.prototype.maybeUpdateFocusStyle = function() { |
| 1182 if (global.hadKeyEvent) | 1182 if (this._hadKeyEvent) |
| 1183 return; | 1183 return; |
| 1184 global.hadKeyEvent = true; | 1184 this._hadKeyEvent = true; |
| 1185 $("main").classList.remove(ClassNames.NoFocusRing); | 1185 this._element.classList.remove(ClassNames.NoFocusRing); |
| 1186 } | 1186 } |
| 1187 | 1187 |
| 1188 if (window.dialogArguments) { | 1188 if (window.dialogArguments) { |
| 1189 initialize(dialogArguments); | 1189 initialize(dialogArguments); |
| 1190 } else { | 1190 } else { |
| 1191 window.addEventListener("message", handleMessage, false); | 1191 window.addEventListener("message", handleMessage, false); |
| 1192 window.setTimeout(handleArgumentsTimeout, 1000); | 1192 window.setTimeout(handleArgumentsTimeout, 1000); |
| 1193 } | 1193 } |
| OLD | NEW |