Modified: trunk/LayoutTests/fast/forms/date/calendar-picker-appearance-pre-100.html (127726 => 127727)
--- trunk/LayoutTests/fast/forms/date/calendar-picker-appearance-pre-100.html 2012-09-06 11:02:11 UTC (rev 127726)
+++ trunk/LayoutTests/fast/forms/date/calendar-picker-appearance-pre-100.html 2012-09-06 11:05:27 UTC (rev 127727)
@@ -8,16 +8,17 @@
<div id="console"></div>
<input type=date id=date value="0002-02-02">
<script>
-function sendKey(input, keyName) {
+function sendKey(element, keyName) {
var event = document.createEvent('KeyboardEvent');
event.initKeyboardEvent('keydown', true, true, document.defaultView, keyName);
- input.dispatchEvent(event);
+ element.dispatchEvent(event);
}
function finishTest() {
pickerWindow.removeEventListener('resize', finishTest);
- sendKey(pickerWindow.global.daysTable._daysContainer, 'Right');
- sendKey(pickerWindow.global.daysTable._daysContainer, 'Enter');
+ var daysContainer = pickerWindow.document.getElementsByClassName("days-area")[0];
+ sendKey(daysContainer, 'Right');
+ sendKey(daysContainer, 'Enter');
shouldBe('document.getElementById("date").value', '"0002-02-03"');
setTimeout(function() { finishJSTest(); }, 0);
}
Modified: trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js (127726 => 127727)
--- trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js 2012-09-06 11:02:11 UTC (rev 127726)
+++ trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js 2012-09-06 11:05:27 UTC (rev 127727)
@@ -276,23 +276,73 @@
resizeWindow(main.offsetWidth, main.offsetHeight);
} else {
global.params = args;
- checkLimits();
- layout();
+ openCalendarPicker();
+ }
+}
- var initialDate = parseDateString(args.currentValue);
- if (initialDate < global.minimumDate)
- initialDate = global.minimumDate;
- else if (initialDate > global.maximumDate)
- initialDate = global.maximumDate;
- global.daysTable.selectDate(initialDate);
+function resetMain() {
+ var main = $("main");
+ main.innerHTML = "";
+ main.className = "";
+};
- setTimeout(fixWindowSize, 0);
- }
+function openCalendarPicker() {
+ resetMain();
+ new CalendarPicker($("main"), global.params);
+};
+
+/**
+ * @constructor
+ * @param {!Element} element
+ * @param {!Object} config
+ */
+function CalendarPicker(element, config) {
+ Picker.call(this, element, config);
+ // We assume this._config.min is a valid date.
+ this.minimumDate = (typeof this._config.min !== "undefined") ? parseDateString(this._config.min) : CalendarPicker.MinimumPossibleDate;
+ // We assume this._config.max is a valid date.
+ this.maximumDate = (typeof this._config.max !== "undefined") ? parseDateString(this._config.max) : CalendarPicker.MaximumPossibleDate;
+ this.step = (typeof this._config.step !== undefined) ? this._config.step * CalendarPicker.BaseStep : CalendarPicker.BaseStep;
+ this.yearMonthController = new YearMonthController(this);
+ this.daysTable = new DaysTable(this);
+ this._layout();
+ var initialDate = parseDateString(this._config.currentValue);
+ if (initialDate < this.minimumDate)
+ initialDate = this.minimumDate;
+ else if (initialDate > this.maximumDate)
+ initialDate = this.maximumDate;
+ this.daysTable.selectDate(initialDate);
+ this.fixWindowSize();
+ document.body.addEventListener("keydown", bind(this._handleBodyKeyDown, this), false);
}
+CalendarPicker.prototype = Object.create(Picker.prototype);
-function fixWindowSize() {
- var yearMonthRightElement = document.getElementsByClassName(ClassNames.YearMonthButtonRight)[0];
- var daysAreaElement = document.getElementsByClassName(ClassNames.DaysArea)[0];
+// Hard limits of type=date. See WebCore/platform/DateComponents.h.
+CalendarPicker.MinimumPossibleDate = new Date(-62135596800000.0);
+CalendarPicker.MaximumPossibleDate = new Date(8640000000000000.0);
+// See WebCore/html/DateInputType.cpp.
+CalendarPicker.BaseStep = 86400000;
+
+CalendarPicker.prototype._layout = function() {
+ this._element.style.direction = global.params.isRTL ? "rtl" : "ltr";
+ this.yearMonthController.attachTo(this._element);
+ this.daysTable.attachTo(this._element);
+ this._layoutButtons();
+};
+
+CalendarPicker.prototype.handleToday = function() {
+ var date = new Date();
+ this.daysTable.selectDate(date);
+ this.submitValue(serializeDate(date.getFullYear(), date.getMonth(), date.getDate()));
+};
+
+CalendarPicker.prototype.handleClear = function() {
+ this.submitValue("");
+};
+
+CalendarPicker.prototype.fixWindowSize = function() {
+ var yearMonthRightElement = this._element.getElementsByClassName(ClassNames.YearMonthButtonRight)[0];
+ var daysAreaElement = this._element.getElementsByClassName(ClassNames.DaysArea)[0];
var headers = daysAreaElement.getElementsByClassName(ClassNames.DayLabel);
var maxCellWidth = 0;
for (var i = 0; i < headers.length; ++i) {
@@ -300,97 +350,58 @@
maxCellWidth = headers[i].offsetWidth;
}
var DaysAreaContainerBorder = 1;
- var main = $("main");
var yearMonthEnd;
var daysAreaEnd;
if (global.params.isRTL) {
- var startOffset = main.offsetLeft + main.offsetWidth;
+ var startOffset = this._element.offsetLeft + this._element.offsetWidth;
yearMonthEnd = startOffset - yearMonthRightElement.offsetLeft;
daysAreaEnd = startOffset - (daysAreaElement.offsetLeft + daysAreaElement.offsetWidth) + maxCellWidth * 7 + DaysAreaContainerBorder;
} else {
yearMonthEnd = yearMonthRightElement.offsetLeft + yearMonthRightElement.offsetWidth;
daysAreaEnd = daysAreaElement.offsetLeft + maxCellWidth * 7 + DaysAreaContainerBorder;
}
-
var maxEnd = Math.max(yearMonthEnd, daysAreaEnd);
- var MainPadding = 6;
+ var MainPadding = 6; // FIXME: Fix name.
var MainBorder = 1;
var desiredBodyWidth = maxEnd + MainPadding + MainBorder;
- var mainHeight = main.offsetHeight;
- main.style.width = "auto";
+ var elementHeight = this._element.offsetHeight;
+ this._element.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";
- resizeWindow(desiredBodyWidth, mainHeight);
-}
+ this._element.getElementsByClassName(ClassNames.YearMonthUpper)[0].style.display = "-webkit-box";
+ this._element.getElementsByClassName(ClassNames.MonthSelectorBox)[0].style.display = "block";
+ resizeWindow(desiredBodyWidth, elementHeight);
+};
-function checkLimits() {
- // Hard limits of type=date. See WebCore/platform/DateComponents.h.
- global.minimumDate = new Date(-62135596800000.0);
- global.maximumDate = new Date(8640000000000000.0);
- // See WebCore/html/DateInputType.cpp.
- global.step = 86400000;
-
- if (global.params.min) {
- // We assume params.min is a valid date.
- global.minimumDate = parseDateString(global.params.min);
- }
- if (global.params.max) {
- // We assume params.max is a valid date.
- global.maximumDate = parseDateString(global.params.max);
- }
- if (global.params.step)
- global.step *= global.params.step;
-}
-
-function layout() {
- if (global.params.isRTL)
- document.body.dir = "rtl";
- else
- document.body.dir = "ltr";
- var main = $("main");
- var params = global.params;
- main.removeChild(main.firstChild);
- document.body.addEventListener("keydown", handleGlobalKey, false);
-
- global.yearMonthController = new YearMonthController();
- global.yearMonthController.attachTo(main);
- global.daysTable = new DaysTable();
- global.daysTable.attachTo(main);
- layoutButtons(main);
-}
-
-/**
- * @param {Element} main
- */
-function layoutButtons(main) {
+CalendarPicker.prototype._layoutButtons = function() {
var container = createElement("div", ClassNames.TodayClearArea);
- global.today = createElement("input", ClassNames.TodayButton);
- global.today.type = "button";
- global.today.value = global.params.todayLabel;
- global.today.addEventListener("click", handleToday, false);
- container.appendChild(global.today);
- global.clear = null;
- if (!global.params.required) {
- global.clear = createElement("input", ClassNames.ClearButton);
- global.clear.type = "button";
- global.clear.value = global.params.clearLabel;
- global.clear.addEventListener("click", handleClear, false);
- container.appendChild(global.clear);
+ this.today = createElement("input", ClassNames.TodayButton);
+ this.today.type = "button";
+ this.today.value = this._config.todayLabel;
+ this.today.addEventListener("click", bind(this.handleToday, this), false);
+ container.appendChild(this.today);
+ this.clear = null;
+ if (!this._config.required) {
+ this.clear = createElement("input", ClassNames.ClearButton);
+ this.clear.type = "button";
+ this.clear.value = this._config.clearLabel;
+ this.clear.addEventListener("click", bind(this.handleClear, this), false);
+ container.appendChild(this.clear);
}
- main.appendChild(container);
+ this._element.appendChild(container);
- global.lastFocusableControl = global.clear || global.today;
-}
+ this.lastFocusableControl = this.clear || this.today;
+};
// ----------------------------------------------------------------
/**
* @constructor
+ * @param {!CalendarPicker} picker
*/
-function YearMonthController() {
+function YearMonthController(picker) {
+ this.picker = picker;
/**
* @type {!number}
*/
@@ -402,9 +413,9 @@
}
/**
- * @param {!Element} main
+ * @param {!Element} element
*/
-YearMonthController.prototype.attachTo = function(main) {
+YearMonthController.prototype.attachTo = function(element) {
var outerContainer = createElement("div", ClassNames.YearMonthArea);
var innerContainer = createElement("div", ClassNames.YearMonthUpper);
@@ -429,13 +440,13 @@
box.appendChild(this._month);
this._attachRightButtonsTo(innerContainer);
- main.appendChild(outerContainer);
+ element.appendChild(outerContainer);
this._wall = createElement("div", ClassNames.MonthSelectorWall);
this._wall.addEventListener("click", bind(this._closePopup, this), false);
- main.appendChild(this._wall);
+ element.appendChild(this._wall);
- var maximumYear = global.maximumDate.getUTCFullYear();
+ var maximumYear = this.picker.maximumDate.getUTCFullYear();
var maxWidth = 0;
for (var m = 0; m < 12; ++m) {
this._month.textContent = formatYearMonth(maximumYear, m);
@@ -534,8 +545,8 @@
};
YearMonthController.prototype._redraw = function() {
- var min = global.minimumDate.getUTCFullYear() * 12 + global.minimumDate.getUTCMonth();
- var max = global.maximumDate.getUTCFullYear() * 12 + global.maximumDate.getUTCMonth();
+ var min = this.picker.minimumDate.getUTCFullYear() * 12 + this.picker.minimumDate.getUTCMonth();
+ var max = this.picker.maximumDate.getUTCFullYear() * 12 + this.picker.maximumDate.getUTCMonth();
var current = this._currentYear * 12 + this._currentMonth;
if (this._left3)
this._left3.disabled = current - 13 < min;
@@ -680,7 +691,7 @@
return;
var newYear = Number(result[1]);
var newMonth = Number(result[2]);
- global.daysTable.navigateToMonthAndKeepSelectionPosition(newYear, newMonth);
+ this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(newYear, newMonth);
};
/*
@@ -738,8 +749,8 @@
* @param {!number} amount
*/
YearMonthController.prototype.moveRelatively = function(amount) {
- var min = global.minimumDate.getUTCFullYear() * 12 + global.minimumDate.getUTCMonth();
- var max = global.maximumDate.getUTCFullYear() * 12 + global.maximumDate.getUTCMonth();
+ var min = this.picker.minimumDate.getUTCFullYear() * 12 + this.picker.minimumDate.getUTCMonth();
+ var max = this.picker.maximumDate.getUTCFullYear() * 12 + this.picker.maximumDate.getUTCMonth();
var current = this._currentYear * 12 + this._currentMonth;
var updated = current;
if (amount < 0)
@@ -748,15 +759,17 @@
updated = current + amount <= max ? current + amount : max;
if (updated == current)
return;
- global.daysTable.navigateToMonthAndKeepSelectionPosition(Math.floor(updated / 12), updated % 12);
+ this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(Math.floor(updated / 12), updated % 12);
};
// ----------------------------------------------------------------
/**
* @constructor
+ * @param {!CalendarPicker} picker
*/
-function DaysTable() {
+function DaysTable(picker) {
+ this.picker = picker;
/**
* @type {!number}
*/
@@ -790,9 +803,9 @@
DaysTable._Weeks = 6;
/**
- * @param {!Element} main
+ * @param {!Element} element
*/
-DaysTable.prototype.attachTo = function(main) {
+DaysTable.prototype.attachTo = function(element) {
this._daysContainer = createElement("table", ClassNames.DaysArea);
this._daysContainer.addEventListener("click", bind(this._handleDayClick, this), false);
this._daysContainer.addEventListener("mouseover", bind(this._handleMouseOver, this), false);
@@ -821,7 +834,7 @@
container.appendChild(this._daysContainer);
container.tabIndex = 0;
container.addEventListener("keydown", bind(this._handleKey, this), false);
- main.appendChild(container);
+ element.appendChild(container);
container.focus();
};
@@ -830,24 +843,24 @@
* @param {!number} time date in millisecond.
* @return {!boolean}
*/
-function stepMismatch(time) {
- return (time - global.minimumDate.getTime()) % global.step != 0;
+CalendarPicker.prototype.stepMismatch = function(time) {
+ return (time - this.minimumDate.getTime()) % this.step != 0;
}
/**
* @param {!number} time date in millisecond.
* @return {!boolean}
*/
-function outOfRange(time) {
- return time < global.minimumDate.getTime() || time > global.maximumDate.getTime();
+CalendarPicker.prototype.outOfRange = function(time) {
+ return time < this.minimumDate.getTime() || time > this.maximumDate.getTime();
}
/**
* @param {!number} time date in millisecond.
* @return {!boolean}
*/
-function isValidDate(time) {
- return !outOfRange(time) && !stepMismatch(time);
+CalendarPicker.prototype.isValidDate = function(time) {
+ return !this.outOfRange(time) && !this.stepMismatch(time);
}
/**
@@ -873,9 +886,9 @@
element.innerText = localizeNumber(dayIterator.getUTCDate());
element.className = ClassNames.Day;
element.dataset.submitValue = serializeDate(iterYear, iterMonth, dayIterator.getUTCDate());
- if (outOfRange(time))
+ if (this.picker.outOfRange(time))
element.classList.add(ClassNames.Unavailable);
- else if (stepMismatch(time))
+ else if (this.picker.stepMismatch(time))
element.classList.add(ClassNames.Unavailable);
else if ((iterYear == year && dayIterator.getUTCMonth() < month) || (month == 0 && iterMonth == 11)) {
element.classList.add(ClassNames.Available);
@@ -892,7 +905,7 @@
}
}
- global.today.disabled = !isValidDate(parseDateString().getTime());
+ this.picker.today.disabled = !this.picker.isValidDate(parseDateString().getTime());
};
/**
@@ -900,7 +913,7 @@
* @param {!number} month
*/
DaysTable.prototype._navigateToMonth = function(year, month) {
- global.yearMonthController.setYearMonth(year, month);
+ this.picker.yearMonthController.setYearMonth(year, month);
this._renderMonth(year, month);
};
@@ -975,7 +988,7 @@
var year = global.yearMonthController.year();
var month = global.yearMonthController.month();
var thisMonthStartTime = createUTCDate(year, month, 1).getTime();
- if (global.minimumDate.getTime() >= thisMonthStartTime)
+ if (this.minimumDate.getTime() >= thisMonthStartTime)
return false;
if (month == 0) {
year--;
@@ -998,7 +1011,7 @@
} else
month++;
var nextMonthStartTime = createUTCDate(year, month, 1).getTime();
- if (global.maximumDate.getTime() < nextMonthStartTime)
+ if (this.picker.maximumDate.getTime() < nextMonthStartTime)
return false;
this._navigateToMonthWithAnimation(year, month);
return true;
@@ -1009,7 +1022,7 @@
*/
DaysTable.prototype._handleDayClick = function(event) {
if (event.target.classList.contains(ClassNames.Available))
- submitValue(event.target.dataset.submitValue);
+ this.picker.submitValue(event.target.dataset.submitValue);
};
/**
@@ -1110,7 +1123,7 @@
} else if (this._hasSelection() && key == "Enter") {
var dayNode = this._days[y][x];
if (dayNode.classList.contains(ClassNames.Available)) {
- submitValue(dayNode.dataset.submitValue);
+ this.picker.submitValue(dayNode.dataset.submitValue);
event.stopPropagation();
}
@@ -1139,53 +1152,30 @@
event.preventDefault();
};
-// ----------------------------------------------------------------
-
-function handleToday() {
- var date = new Date();
- global.daysTable.selectDate(date);
- submitValue(serializeDate(date.getFullYear(), date.getMonth(), date.getDate()));
-}
-
-function handleClear() {
- submitValue("");
-}
-
/**
- * @param {string} value
+ * @param {!Event} event
*/
-function submitValue(value) {
- window.pagePopupController.setValueAndClosePopup(0, value);
-}
-
-function handleCancel() {
- window.pagePopupController.setValueAndClosePopup(-1, "");
-}
-
-/**
- * @param {Event} event
- */
-function handleGlobalKey(event) {
+CalendarPicker.prototype._handleBodyKeyDown = function(event) {
maybeUpdateFocusStyle();
var key = event.keyIdentifier;
if (key == "U+0009") {
if (!event.shiftKey && document.activeElement == global.lastFocusableControl) {
event.stopPropagation();
event.preventDefault();
- global.firstFocusableControl.focus();
+ this.firstFocusableControl.focus();
} else if (event.shiftKey && document.activeElement == global.firstFocusableControl) {
event.stopPropagation();
event.preventDefault();
- global.lastFocusableControl.focus();
+ this.lastFocusableControl.focus();
}
} else if (key == "U+004D") { // 'm'
- global.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousMonth : YearMonthController.NextMonth);
+ this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousMonth : YearMonthController.NextMonth);
} else if (key == "U+0059") { // 'y'
- global.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousYear : YearMonthController.NextYear);
+ this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousYear : YearMonthController.NextYear);
} else if (key == "U+0044") { // 'd'
- global.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousTenYears : YearMonthController.NextTenYears);
+ this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousTenYears : YearMonthController.NextTenYears);
} else if (key == "U+001B") // ESC
- handleCancel();
+ this.handleCancel();
}
function maybeUpdateFocusStyle() {
Modified: trunk/Source/WebCore/Resources/pagepopups/colorSuggestionPicker.js (127726 => 127727)
--- trunk/Source/WebCore/Resources/pagepopups/colorSuggestionPicker.js 2012-09-06 11:02:11 UTC (rev 127726)
+++ trunk/Source/WebCore/Resources/pagepopups/colorSuggestionPicker.js 2012-09-06 11:05:27 UTC (rev 127727)
@@ -74,29 +74,8 @@
return null;
}
-var Actions = {
- ChooseOtherColor: -2,
- Cancel: -1,
- SetValue: 0
-};
-
-/**
- * @param {string} value
- */
-function submitValue(value) {
- window.pagePopupController.setValueAndClosePopup(Actions.SetValue, value);
-}
-
-function handleCancel() {
- window.pagePopupController.setValueAndClosePopup(Actions.Cancel, "");
-}
-
-function chooseOtherColor() {
- window.pagePopupController.setValueAndClosePopup(Actions.ChooseOtherColor, "");
-}
-
function ColorPicker(element, config) {
- this._element = element;
+ Picker.call(this, element, config);
this._config = config;
if (this._config.values.length === 0)
this._config.values = DefaultColorPalette;
@@ -106,6 +85,7 @@
this._element.addEventListener("mousemove", bind(this._handleMouseMove, this));
this._element.addEventListener("mousedown", bind(this._handleMouseDown, this));
}
+ColorPicker.prototype = Object.create(Picker.prototype);
var SwatchBorderBoxWidth = 24; // keep in sync with CSS
var SwatchBorderBoxHeight = 24; // keep in sync with CSS
@@ -130,7 +110,7 @@
container.style.maxHeight = (SwatchBorderBoxHeight * SwatchesMaxRow) + "px";
this._element.appendChild(container);
var otherButton = createElement("button", "other-color", this._config.otherColorLabel);
- otherButton.addEventListener("click", chooseOtherColor, false);
+ otherButton.addEventListener("click", this.chooseOtherColor.bind(this), false);
this._element.appendChild(otherButton);
this._container = container;
this._otherButton = otherButton;
@@ -158,7 +138,7 @@
ColorPicker.prototype._handleKeyDown = function(event) {
var key = event.keyIdentifier;
if (key === "U+001B") // ESC
- handleCancel();
+ this.handleCancel();
else if (key == "Left" || key == "Up" || key == "Right" || key == "Down") {
var selectedElement = document.activeElement;
var index = 0;
@@ -194,7 +174,7 @@
ColorPicker.prototype._handleSwatchClick = function(event) {
if (event.target.classList.contains("color-swatch"))
- submitValue(event.target.dataset.value);
+ this.submitValue(event.target.dataset.value);
};
if (window.dialogArguments) {