Log Message
Add suggestionPicker to CalendarPicker https://bugs.webkit.org/show_bug.cgi?id=97201
Reviewed by Kent Tamura. .: * ManualTests/forms/calendar-picker.html: Added tests for SuggestionPicker. Source/WebCore: This adds the suggestionPicker to CalendarPicker. It is not available yet as a datalist UI but it can be used inside ManualTests/forms/calendar-picker.html. No new tests. Suggestion Picker can be tested in ManualTests/forms/calendar-picker.html. * Resources/pagepopups/calendarPicker.js: (initialize): (openSuggestionPicker): * Resources/pagepopups/pickerCommon.js: (enclosingNodeOrSelfWithClass): * Resources/pagepopups/suggestionPicker.css: Added. (.suggestion-list): (.suggestion-list-entry): (.suggestion-list-entry:focus): (.suggestion-list-entry:focus .label): (.suggestion-list-entry .content): (.suggestion-list-entry .title): (.suggestion-list-entry .label): (.measuring-width .suggestion-list-entry .label): (.suggestion-list .separator): * Resources/pagepopups/suggestionPicker.js: Added. (SuggestionPicker): (SuggestionPicker.validateConfig): (SuggestionPicker.prototype.cleanup): (SuggestionPicker.prototype._setColors): Creates css rules that sets highlight colors. (SuggestionPicker.prototype._createSuggestionEntryElement): Creates an entry that when selected submits the value. (SuggestionPicker.prototype._createActionEntryElement): Creates an entry that causes an action. (e.x. "Other...") (SuggestionPicker.prototype._measureMaxContentWidth): Temporarily left align everything to measure the width. (SuggestionPicker.prototype._fixWindowSize): (SuggestionPicker.prototype._layout): (SuggestionPicker.prototype.selectEntry): (SuggestionPicker.prototype._handleEntryClick): (SuggestionPicker.prototype._findFirstVisibleEntry): (SuggestionPicker.prototype._findLastVisibleEntry): (SuggestionPicker.prototype._handleBodyKeyDown): (SuggestionPicker.prototype._handleEntryMouseOver): (SuggestionPicker.prototype._handleMouseOut): * WebCore.gyp/WebCore.gyp: Source/WebKit/chromium: * src/DateTimeChooserImpl.cpp: (WebKit::DateTimeChooserImpl::writeDocument): Add js/css for SuggestionPicker to page picker. Add highlight color to args.
Modified Paths
- trunk/ChangeLog
- trunk/ManualTests/forms/calendar-picker.html
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js
- trunk/Source/WebCore/Resources/pagepopups/pickerCommon.js
- trunk/Source/WebCore/WebCore.gyp/WebCore.gyp
- trunk/Source/WebKit/chromium/ChangeLog
- trunk/Source/WebKit/chromium/src/DateTimeChooserImpl.cpp
Added Paths
Diff
Modified: trunk/ChangeLog (129325 => 129326)
--- trunk/ChangeLog 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/ChangeLog 2012-09-24 04:39:09 UTC (rev 129326)
@@ -1,3 +1,12 @@
+2012-09-23 Keishi Hattori <[email protected]>
+
+ Add suggestionPicker to CalendarPicker
+ https://bugs.webkit.org/show_bug.cgi?id=97201
+
+ Reviewed by Kent Tamura.
+
+ * ManualTests/forms/calendar-picker.html: Added tests for SuggestionPicker.
+
2012-09-21 Ami Fischman <[email protected]>
HTMLMediaElement isn't garbage collected between document reloads
Modified: trunk/ManualTests/forms/calendar-picker.html (129325 => 129326)
--- trunk/ManualTests/forms/calendar-picker.html 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/ManualTests/forms/calendar-picker.html 2012-09-24 04:39:09 UTC (rev 129326)
@@ -23,6 +23,8 @@
<option>English</option>
<option>Japanese</option>
<option>Arabic</option>
+ <option>with datalist</option>
+ <option>with long datalist</option>
</select>
<div><input type="text" id="date"></div>
@@ -68,6 +70,83 @@
step : 1,
max : '2020-05-15',
};
+var datalistArguments = {
+ locale: 'en-US',
+ monthLabels : ['January', 'February', 'March', 'April', 'May', 'June',
+ 'July', 'August', 'September', 'October', 'November', 'December'],
+ dayLabels : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ todayLabel : 'Today',
+ clearLabel : 'Clear',
+ cancelLabel : 'Cancel',
+ weekStartDay : 0,
+ step : 1,
+ max : '2099-12-31',
+ suggestionValues : ['2012-01-01', '2012-06-03', '2012-09-06', '2012-12-24'],
+ localizedSuggestionValues : ['1/1/12', '6/3/12', '9/6/12', '12/24/12'],
+ suggestionLabels : ['', 'Birthday', '', 'Christmas'],
+ showOtherDateEntry: true,
+ otherDateLabel: 'Other...',
+ inputWidth: 127,
+ suggestionHighlightColor: "#0000ff",
+ suggestionHighlightTextColor: "#ffffff"
+};
+var longDatalistArguments = {
+ locale: 'en-US',
+ monthLabels : ['January', 'February', 'March', 'April', 'May', 'June',
+ 'July', 'August', 'September', 'October', 'November', 'December'],
+ dayLabels : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ todayLabel : 'Today',
+ clearLabel : 'Clear',
+ cancelLabel : 'Cancel',
+ weekStartDay : 0,
+ step : 1,
+ max : '2099-12-31',
+ suggestionValues: ["2012-01-01", "2012-01-02", "2012-01-03", "2012-01-04",
+ "2012-01-05", "2012-01-06", "2012-01-07", "2012-01-08", "2012-01-09",
+ "2012-01-10", "2012-01-11", "2012-01-12", "2012-01-13", "2012-01-14",
+ "2012-01-15", "2012-01-16", "2012-01-17", "2012-01-18", "2012-01-19",
+ "2012-01-20", "2012-01-21", "2012-01-22", "2012-01-23", "2012-01-24",
+ "2012-01-25", "2012-01-26", "2012-01-27", "2012-01-28", "2012-01-29",
+ "2012-01-30", "2012-01-31", "2012-02-01", "2012-02-02", "2012-02-03",
+ "2012-02-04", "2012-02-05", "2012-02-06", "2012-02-07", "2012-02-08",
+ "2012-02-09", "2012-02-10", "2012-02-11", "2012-02-12", "2012-02-13",
+ "2012-02-14", "2012-02-15", "2012-02-16", "2012-02-17", "2012-02-18",
+ "2012-02-19", "2012-02-20", "2012-02-21", "2012-02-22", "2012-02-23",
+ "2012-02-24", "2012-02-25", "2012-02-26", "2012-02-27", "2012-02-28",
+ "2012-02-29", "2012-03-01", "2012-03-02", "2012-03-03", "2012-03-04",
+ "2012-03-05", "2012-03-06", "2012-03-07", "2012-03-08", "2012-03-09",
+ "2012-03-10", "2012-03-11", "2012-03-12", "2012-03-13", "2012-03-14",
+ "2012-03-15", "2012-03-16", "2012-03-17", "2012-03-18", "2012-03-19",
+ "2012-03-20", "2012-03-21", "2012-03-22", "2012-03-23", "2012-03-24",
+ "2012-03-25", "2012-03-26", "2012-03-27", "2012-03-28", "2012-03-29",
+ "2012-03-30", "2012-03-31"],
+ localizedSuggestionValues: ["1/1/12", "1/2/12", "1/3/12", "1/4/12",
+ "1/5/12", "1/6/12", "1/7/12", "1/8/12", "1/9/12", "1/10/12", "1/11/12",
+ "1/12/12", "1/13/12", "1/14/12", "1/15/12", "1/16/12", "1/17/12",
+ "1/18/12", "1/19/12", "1/20/12", "1/21/12", "1/22/12", "1/23/12",
+ "1/24/12", "1/25/12", "1/26/12", "1/27/12", "1/28/12", "1/29/12",
+ "1/30/12", "1/31/12", "2/1/12", "2/2/12", "2/3/12", "2/4/12", "2/5/12",
+ "2/6/12", "2/7/12", "2/8/12", "2/9/12", "2/10/12", "2/11/12", "2/12/12",
+ "2/13/12", "2/14/12", "2/15/12", "2/16/12", "2/17/12", "2/18/12",
+ "2/19/12", "2/20/12", "2/21/12", "2/22/12", "2/23/12", "2/24/12",
+ "2/25/12", "2/26/12", "2/27/12", "2/28/12", "2/29/12", "3/1/12",
+ "3/2/12", "3/3/12", "3/4/12", "3/5/12", "3/6/12", "3/7/12", "3/8/12",
+ "3/9/12", "3/10/12", "3/11/12", "3/12/12", "3/13/12", "3/14/12",
+ "3/15/12", "3/16/12", "3/17/12", "3/18/12", "3/19/12", "3/20/12",
+ "3/21/12", "3/22/12", "3/23/12", "3/24/12", "3/25/12", "3/26/12",
+ "3/27/12", "3/28/12", "3/29/12", "3/30/12", "3/31/12"],
+ suggestionLabels: ["Today", "Tomorrow", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", ""],
+ showOtherDateEntry: true,
+ otherDateLabel: 'Other...',
+ inputWidth: 127,
+ suggestionHighlightColor: "#0000ff",
+ suggestionHighlightTextColor: "#ffffff"
+};
function openCalendar(args) {
var frame = document.getElementsByTagName('iframe')[0];
@@ -77,6 +156,10 @@
commonCssLink.rel = 'stylesheet';
commonCssLink.href = '' + (new Date()).getTime();
doc.head.appendChild(commonCssLink);
+ var suggestionPickerCssLink = doc.createElement('link');
+ suggestionPickerCssLink.rel = 'stylesheet';
+ suggestionPickerCssLink.href = '' + (new Date()).getTime();
+ doc.head.appendChild(suggestionPickerCssLink);
var link = doc.createElement('link');
link.rel = 'stylesheet';
link.href = '' + (new Date()).getTime();
@@ -84,6 +167,9 @@
var commonJsScript = doc.createElement('script');
commonJsScript.src = '' + (new Date()).getTime();
doc.body.appendChild(commonJsScript);
+ var suggestionPickerJsScript = doc.createElement('script');
+ suggestionPickerJsScript.src = '' + (new Date()).getTime();
+ doc.body.appendChild(suggestionPickerJsScript);
var script = doc.createElement('script');
script.src = '' + (new Date()).getTime();
doc.body.appendChild(script);
@@ -121,6 +207,12 @@
case 2:
openCalendar(arabicArguments);
break;
+ case 3:
+ openCalendar(datalistArguments);
+ break;
+ case 4:
+ openCalendar(longDatalistArguments);
+ break;
}
}
Modified: trunk/Source/WebCore/ChangeLog (129325 => 129326)
--- trunk/Source/WebCore/ChangeLog 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/Source/WebCore/ChangeLog 2012-09-24 04:39:09 UTC (rev 129326)
@@ -1,3 +1,48 @@
+2012-09-23 Keishi Hattori <[email protected]>
+
+ Add suggestionPicker to CalendarPicker
+ https://bugs.webkit.org/show_bug.cgi?id=97201
+
+ Reviewed by Kent Tamura.
+
+ This adds the suggestionPicker to CalendarPicker. It is not available yet as a datalist UI but it can be used inside ManualTests/forms/calendar-picker.html.
+
+ No new tests. Suggestion Picker can be tested in ManualTests/forms/calendar-picker.html.
+
+ * Resources/pagepopups/calendarPicker.js:
+ (initialize):
+ (openSuggestionPicker):
+ * Resources/pagepopups/pickerCommon.js:
+ (enclosingNodeOrSelfWithClass):
+ * Resources/pagepopups/suggestionPicker.css: Added.
+ (.suggestion-list):
+ (.suggestion-list-entry):
+ (.suggestion-list-entry:focus):
+ (.suggestion-list-entry:focus .label):
+ (.suggestion-list-entry .content):
+ (.suggestion-list-entry .title):
+ (.suggestion-list-entry .label):
+ (.measuring-width .suggestion-list-entry .label):
+ (.suggestion-list .separator):
+ * Resources/pagepopups/suggestionPicker.js: Added.
+ (SuggestionPicker):
+ (SuggestionPicker.validateConfig):
+ (SuggestionPicker.prototype.cleanup):
+ (SuggestionPicker.prototype._setColors): Creates css rules that sets highlight colors.
+ (SuggestionPicker.prototype._createSuggestionEntryElement): Creates an entry that when selected submits the value.
+ (SuggestionPicker.prototype._createActionEntryElement): Creates an entry that causes an action. (e.x. "Other...")
+ (SuggestionPicker.prototype._measureMaxContentWidth): Temporarily left align everything to measure the width.
+ (SuggestionPicker.prototype._fixWindowSize):
+ (SuggestionPicker.prototype._layout):
+ (SuggestionPicker.prototype.selectEntry):
+ (SuggestionPicker.prototype._handleEntryClick):
+ (SuggestionPicker.prototype._findFirstVisibleEntry):
+ (SuggestionPicker.prototype._findLastVisibleEntry):
+ (SuggestionPicker.prototype._handleBodyKeyDown):
+ (SuggestionPicker.prototype._handleEntryMouseOver):
+ (SuggestionPicker.prototype._handleMouseOut):
+ * WebCore.gyp/WebCore.gyp:
+
2012-09-23 Andreas Kling <[email protected]>
REGRESSION(r128239): Mutable ElementAttributeData leak their Attribute vectors.
Modified: trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js (129325 => 129326)
--- trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js 2012-09-24 04:39:09 UTC (rev 129326)
@@ -268,13 +268,18 @@
*/
function initialize(args) {
var errorString = CalendarPicker.validateConfig(args);
+ if (args.suggestionValues)
+ errorString = errorString || SuggestionPicker.validateConfig(args)
if (errorString) {
var main = $("main");
main.textContent = "Internal error: " + errorString;
resizeWindow(main.offsetWidth, main.offsetHeight);
} else {
global.params = args;
- openCalendarPicker();
+ if (global.params.suggestionValues && global.params.suggestionValues.length)
+ openSuggestionPicker();
+ else
+ openCalendarPicker();
}
}
@@ -286,6 +291,11 @@
main.className = "";
};
+function openSuggestionPicker() {
+ closePicker();
+ global.picker = new SuggestionPicker($("main"), global.params);
+};
+
function openCalendarPicker() {
closePicker();
global.picker = new CalendarPicker($("main"), global.params);
Modified: trunk/Source/WebCore/Resources/pagepopups/pickerCommon.js (129325 => 129326)
--- trunk/Source/WebCore/Resources/pagepopups/pickerCommon.js 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/Source/WebCore/Resources/pagepopups/pickerCommon.js 2012-09-24 04:39:09 UTC (rev 129326)
@@ -76,6 +76,19 @@
}
/**
+ * @param {!string} className
+ * @return {?Element}
+ */
+function enclosingNodeOrSelfWithClass(selfNode, className)
+{
+ for (var node = selfNode; node && node !== selfNode.ownerDocument; node = node.parentNode) {
+ if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains(className))
+ return node;
+ }
+ return null;
+};
+
+/**
* @constructor
* @param {!Element} element
* @param {!Object} config
Added: trunk/Source/WebCore/Resources/pagepopups/suggestionPicker.css (0 => 129326)
--- trunk/Source/WebCore/Resources/pagepopups/suggestionPicker.css (rev 0)
+++ trunk/Source/WebCore/Resources/pagepopups/suggestionPicker.css 2012-09-24 04:39:09 UTC (rev 129326)
@@ -0,0 +1,43 @@
+.suggestion-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ font: -webkit-small-control;
+ border: 1px solid #7f9db9;
+ background-color: white;
+ overflow-y: auto;
+}
+
+.suggestion-list-entry {
+ white-space: nowrap;
+ height: 1.73em;
+ line-height: 1.73em;
+ -webkit-select: none;
+ cursor: default;
+}
+
+.suggestion-list-entry:focus {
+ outline: none;
+}
+
+.suggestion-list-entry .content {
+ padding: 0 4px;
+}
+
+.suggestion-list-entry .label {
+ padding-left: 20px;
+ text-align: right;
+ color: #737373;
+ float: right;
+ margin-right: 4px;
+}
+
+.measuring-width .suggestion-list-entry .label {
+ float: none;
+ margin-right: 0;
+}
+
+.suggestion-list .separator {
+ border-top: 1px solid #dcdcdc;
+ height: 0;
+}
Added: trunk/Source/WebCore/Resources/pagepopups/suggestionPicker.js (0 => 129326)
--- trunk/Source/WebCore/Resources/pagepopups/suggestionPicker.js (rev 0)
+++ trunk/Source/WebCore/Resources/pagepopups/suggestionPicker.js 2012-09-24 04:39:09 UTC (rev 129326)
@@ -0,0 +1,311 @@
+"use strict";
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @param {!Element} element
+ * @param {!Object} config
+ */
+function SuggestionPicker(element, config) {
+ Picker.call(this, element, config);
+ this._isFocusByMouse = false;
+ this._containerElement = null;
+ this._setColors();
+ this._layout();
+ this._fixWindowSize();
+ this._handleBodyKeyDownBound = this._handleBodyKeyDown.bind(this);
+ document.body.addEventListener("keydown", this._handleBodyKeyDownBound);
+ this._element.addEventListener("mouseout", this._handleMouseOut.bind(this), false);
+};
+SuggestionPicker.prototype = Object.create(Picker.prototype);
+
+SuggestionPicker.NumberOfVisibleEntries = 20;
+
+// An entry needs to be at least this many pixels visible for it to be a visible entry.
+SuggestionPicker.VisibleEntryThresholdHeight = 4;
+
+SuggestionPicker.ActionNames = {
+ OpenCalendarPicker: "openCalendarPicker"
+};
+
+SuggestionPicker.ListEntryClass = "suggestion-list-entry";
+
+SuggestionPicker.validateConfig = function(config) {
+ if (config.showOtherDateEntry && !config.otherDateLabel)
+ return "No otherDateLabel.";
+ if (config.suggestionHighlightColor && !config.suggestionHighlightColor)
+ return "No suggestionHighlightColor.";
+ if (config.suggestionHighlightTextColor && !config.suggestionHighlightTextColor)
+ return "No suggestionHighlightTextColor.";
+ if (config.suggestionValues.length !== config.localizedSuggestionValues.length)
+ return "localizedSuggestionValues.length must equal suggestionValues.length.";
+ if (config.suggestionValues.length !== config.suggestionLabels.length)
+ return "suggestionLabels.length must equal suggestionValues.length.";
+ if (typeof config.inputWidth === "undefined")
+ return "No inputWidth.";
+ return null;
+};
+
+SuggestionPicker.prototype._setColors = function() {
+ var text = "." + SuggestionPicker.ListEntryClass + ":focus {\
+ background-color: " + this._config.suggestionHighlightColor + ";\
+ color: " + this._config.suggestionHighlightTextColor + "; }";
+ text += "." + SuggestionPicker.ListEntryClass + ":focus .label { color: " + this._config.suggestionHighlightTextColor + "; }";
+ document.head.appendChild(createElement("style", null, text));
+};
+
+SuggestionPicker.prototype.cleanup = function() {
+ document.body.removeEventListener("keydown", this._handleBodyKeyDownBound, false);
+};
+
+/**
+ * @param {!string} title
+ * @param {!string} label
+ * @param {!string} value
+ * @return {!Element}
+ */
+SuggestionPicker.prototype._createSuggestionEntryElement = function(title, label, value) {
+ var entryElement = createElement("li", SuggestionPicker.ListEntryClass);
+ entryElement.tabIndex = 0;
+ entryElement.dataset.value = value;
+ var content = createElement("span", "content");
+ entryElement.appendChild(content);
+ var titleElement = createElement("span", "title", title);
+ content.appendChild(titleElement);
+ if (label) {
+ var labelElement = createElement("span", "label", label);
+ content.appendChild(labelElement);
+ }
+ entryElement.addEventListener("mouseover", this._handleEntryMouseOver.bind(this), false);
+ return entryElement;
+};
+
+/**
+ * @param {!string} title
+ * @param {!string} actionName
+ * @return {!Element}
+ */
+SuggestionPicker.prototype._createActionEntryElement = function(title, actionName) {
+ var entryElement = createElement("li", SuggestionPicker.ListEntryClass);
+ entryElement.tabIndex = 0;
+ entryElement.dataset.action = ""
+ var content = createElement("span", "content");
+ entryElement.appendChild(content);
+ var titleElement = createElement("span", "title", title);
+ content.appendChild(titleElement);
+ entryElement.addEventListener("mouseover", this._handleEntryMouseOver.bind(this), false);
+ return entryElement;
+};
+
+/**
+* @return {!number}
+*/
+SuggestionPicker.prototype._measureMaxContentWidth = function() {
+ // To measure the required width, we first set the class to "measuring-width" which
+ // left aligns all the content including label.
+ this._containerElement.classList.add("measuring-width");
+ var maxContentWidth = 0;
+ if (typeof this._config.inputWidth === "number")
+ maxContentWidth = this._config.inputWidth;
+ var contentElements = this._containerElement.getElementsByClassName("content");
+ for (var i=0; i < contentElements.length; ++i) {
+ maxContentWidth = Math.max(maxContentWidth, contentElements[i].offsetWidth);
+ }
+ this._containerElement.classList.remove("measuring-width");
+ return maxContentWidth;
+};
+
+SuggestionPicker.prototype._fixWindowSize = function() {
+ var ListBorder = 2;
+ var desiredWindowWidth = this._measureMaxContentWidth() + ListBorder;
+ var totalHeight = ListBorder;
+ var maxHeight = 0;
+ var entryCount = 0;
+ for (var i = 0; i < this._containerElement.childNodes.length; ++i) {
+ var node = this._containerElement.childNodes[i];
+ if (node.classList.contains(SuggestionPicker.ListEntryClass))
+ entryCount++;
+ totalHeight += node.offsetHeight;
+ if (maxHeight === 0 && entryCount == SuggestionPicker.NumberOfVisibleEntries)
+ maxHeight = totalHeight;
+ }
+ var desiredWindowHeight = totalHeight;
+ if (maxHeight !== 0 && totalHeight > maxHeight) {
+ this._containerElement.style.maxHeight = (maxHeight - ListBorder) + "px";
+ desiredWindowWidth += getScrollbarWidth();
+ desiredWindowHeight = maxHeight;
+ }
+
+ resizeWindow(desiredWindowWidth, desiredWindowHeight);
+};
+
+SuggestionPicker.prototype._layout = function() {
+ this._containerElement = createElement("ul", "suggestion-list");
+ this._containerElement.addEventListener("click", this._handleEntryClick.bind(this), false);
+ for (var i = 0; i < this._config.suggestionValues.length; ++i) {
+ this._containerElement.appendChild(this._createSuggestionEntryElement(this._config.localizedSuggestionValues[i], this._config.suggestionLabels[i], this._config.suggestionValues[i]));
+ }
+ if (this._config.showOtherDateEntry) {
+ // Add separator
+ var separator = createElement("div", "separator");
+ this._containerElement.appendChild(separator);
+
+ // Add "Other..." entry
+ var otherEntry = this._createActionEntryElement(this._config.otherDateLabel, SuggestionPicker.ActionNames.OpenCalendarPicker);
+ this._containerElement.appendChild(otherEntry);
+ }
+ this._element.appendChild(this._containerElement);
+};
+
+/**
+ * @param {!Element} entry
+ */
+SuggestionPicker.prototype.selectEntry = function(entry) {
+ if (typeof entry.dataset.value !== "undefined") {
+ this.submitValue(entry.dataset.value);
+ } else if (entry.dataset.action ="" SuggestionPicker.ActionNames.OpenCalendarPicker) {
+ openCalendarPicker();
+ }
+};
+
+/**
+ * @param {!Event} event
+ */
+SuggestionPicker.prototype._handleEntryClick = function(event) {
+ var entry = enclosingNodeOrSelfWithClass(event.target, SuggestionPicker.ListEntryClass);
+ if (!entry)
+ return;
+ this.selectEntry(entry);
+ event.preventDefault();
+};
+
+/**
+ * @return {?Element}
+ */
+SuggestionPicker.prototype._findFirstVisibleEntry = function() {
+ var scrollTop = this._containerElement.scrollTop;
+ var childNodes = this._containerElement.childNodes;
+ for (var i = 0; i < childNodes.length; ++i) {
+ var node = childNodes[i];
+ if (node.nodeType !== Node.ELEMENT_NODE || !node.classList.contains(SuggestionPicker.ListEntryClass))
+ continue;
+ if (node.offsetTop + node.offsetHeight - scrollTop > SuggestionPicker.VisibleEntryThresholdHeight)
+ return node;
+ }
+ return null;
+};
+
+/**
+ * @return {?Element}
+ */
+SuggestionPicker.prototype._findLastVisibleEntry = function() {
+ var scrollBottom = this._containerElement.scrollTop + this._containerElement.offsetHeight;
+ var childNodes = this._containerElement.childNodes;
+ for (var i = childNodes.length - 1; i >= 0; --i){
+ var node = childNodes[i];
+ if (node.nodeType !== Node.ELEMENT_NODE || !node.classList.contains(SuggestionPicker.ListEntryClass))
+ continue;
+ if (scrollBottom - node.offsetTop > SuggestionPicker.VisibleEntryThresholdHeight)
+ return node;
+ }
+ return null;
+};
+
+/**
+ * @param {!Event} event
+ */
+SuggestionPicker.prototype._handleBodyKeyDown = function(event) {
+ var eventHandled = false;
+ var key = event.keyIdentifier;
+ if (key === "U+001B") { // ESC
+ this.handleCancel();
+ eventHandled = true;
+ } else if (key == "Up") {
+ if (document.activeElement && document.activeElement.classList.contains(SuggestionPicker.ListEntryClass)) {
+ for (var node = document.activeElement.previousElementSibling; node; node = node.previousElementSibling) {
+ if (node.classList.contains(SuggestionPicker.ListEntryClass)) {
+ this._isFocusByMouse = false;
+ node.focus();
+ break;
+ }
+ }
+ } else {
+ this._element.querySelector("." + SuggestionPicker.ListEntryClass + ":last-child").focus();
+ }
+ eventHandled = true;
+ } else if (key == "Down") {
+ if (document.activeElement && document.activeElement.classList.contains(SuggestionPicker.ListEntryClass)) {
+ for (var node = document.activeElement.nextElementSibling; node; node = node.nextElementSibling) {
+ if (node.classList.contains(SuggestionPicker.ListEntryClass)) {
+ this._isFocusByMouse = false;
+ node.focus();
+ break;
+ }
+ }
+ } else {
+ this._element.querySelector("." + SuggestionPicker.ListEntryClass + ":first-child").focus();
+ }
+ eventHandled = true;
+ } else if (key === "Enter") {
+ this.selectEntry(document.activeElement);
+ eventHandled = true;
+ } else if (key === "PageUp") {
+ this._containerElement.scrollTop -= this._containerElement.clientHeight;
+ // Scrolling causes mouseover event to be called and that tries to move the focus too.
+ // To prevent flickering we won't focus if the current focus was caused by the mouse.
+ if (!this._isFocusByMouse)
+ this._findFirstVisibleEntry().focus();
+ eventHandled = true;
+ } else if (key === "PageDown") {
+ this._containerElement.scrollTop += this._containerElement.clientHeight;
+ if (!this._isFocusByMouse)
+ this._findLastVisibleEntry().focus();
+ eventHandled = true;
+ }
+ if (eventHandled)
+ event.preventDefault();
+};
+
+/**
+ * @param {!Event} event
+ */
+SuggestionPicker.prototype._handleEntryMouseOver = function(event) {
+ var entry = enclosingNodeOrSelfWithClass(event.target, SuggestionPicker.ListEntryClass);
+ if (!entry)
+ return;
+ this._isFocusByMouse = true;
+ entry.focus();
+ event.preventDefault();
+};
+
+/**
+ * @param {!Event} event
+ */
+SuggestionPicker.prototype._handleMouseOut = function(event) {
+ if (!document.activeElement.classList.contains(SuggestionPicker.ListEntryClass))
+ return;
+ this._isFocusByMouse = false;
+ document.activeElement.blur();
+ event.preventDefault();
+};
Modified: trunk/Source/WebCore/WebCore.gyp/WebCore.gyp (129325 => 129326)
--- trunk/Source/WebCore/WebCore.gyp/WebCore.gyp 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/Source/WebCore/WebCore.gyp/WebCore.gyp 2012-09-24 04:39:09 UTC (rev 129326)
@@ -946,6 +946,8 @@
'inputs': [
'../Resources/pagepopups/calendarPicker.css',
'../Resources/pagepopups/calendarPicker.js',
+ '../Resources/pagepopups/suggestionPicker.css',
+ '../Resources/pagepopups/suggestionPicker.js',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/webkit/CalendarPicker.h',
Modified: trunk/Source/WebKit/chromium/ChangeLog (129325 => 129326)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-09-24 04:39:09 UTC (rev 129326)
@@ -1,3 +1,13 @@
+2012-09-23 Keishi Hattori <[email protected]>
+
+ Add suggestionPicker to CalendarPicker
+ https://bugs.webkit.org/show_bug.cgi?id=97201
+
+ Reviewed by Kent Tamura.
+
+ * src/DateTimeChooserImpl.cpp:
+ (WebKit::DateTimeChooserImpl::writeDocument): Add js/css for SuggestionPicker to page picker. Add highlight color to args.
+
2012-09-21 Kenichi Ishibashi <[email protected]>
[Chromium] Use OpenTypeVerticalData on Linux
Modified: trunk/Source/WebKit/chromium/src/DateTimeChooserImpl.cpp (129325 => 129326)
--- trunk/Source/WebKit/chromium/src/DateTimeChooserImpl.cpp 2012-09-24 03:47:49 UTC (rev 129325)
+++ trunk/Source/WebKit/chromium/src/DateTimeChooserImpl.cpp 2012-09-24 04:39:09 UTC (rev 129326)
@@ -88,6 +88,7 @@
addString("<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", writer);
writer.addData(WebCore::pickerCommonCss, sizeof(WebCore::pickerCommonCss));
+ writer.addData(WebCore::suggestionPickerCss, sizeof(WebCore::suggestionPickerCss));
writer.addData(WebCore::calendarPickerCss, sizeof(WebCore::calendarPickerCss));
CString extraStyle = WebCore::RenderTheme::defaultTheme()->extraCalendarPickerStyleSheet();
if (extraStyle.length())
@@ -114,10 +115,13 @@
addProperty("suggestionLabels", m_parameters.suggestionLabels, writer);
addProperty("showOtherDateEntry", m_parameters.type == WebCore::InputTypeNames::date(), writer);
addProperty("otherDateLabel", Platform::current()->queryLocalizedString(WebLocalizedString::OtherDateLabel), writer);
+ addProperty("suggestionHighlightColor", WebCore::RenderTheme::defaultTheme()->activeListBoxSelectionBackgroundColor().serialized(), writer);
+ addProperty("suggestionHighlightTextColor", WebCore::RenderTheme::defaultTheme()->activeListBoxSelectionForegroundColor().serialized(), writer);
}
addString("}\n", writer);
writer.addData(WebCore::pickerCommonJs, sizeof(WebCore::pickerCommonJs));
+ writer.addData(WebCore::suggestionPickerJs, sizeof(WebCore::suggestionPickerJs));
writer.addData(WebCore::calendarPickerJs, sizeof(WebCore::calendarPickerJs));
addString("</script></body>\n", writer);
}
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo/webkit-changes
