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 |