From 9360e3f71a0ef86010685f114298e5de0d4aa93d Mon Sep 17 00:00:00 2001 From: David Huynh Date: Sun, 27 Nov 2011 20:22:58 +0000 Subject: [PATCH] Fixed Issue 488: ISO 8601 dates not supported in cell editing - cell-ui.js. git-svn-id: http://google-refine.googlecode.com/svn/trunk@2388 7d457c2a-affb-35e4-300a-418c747d4874 --- LICENSE.txt | 4 +- licenses/simile-ajax.2.3.0.LICENSE.txt | 35 +++ .../webapp/modules/core/MOD-INF/controller.js | 2 + .../modules/core/scripts/util/date-time.js | 232 ++++++++++++++++++ .../core/scripts/views/data-table/cell-ui.js | 3 + 5 files changed, 275 insertions(+), 1 deletion(-) create mode 100644 licenses/simile-ajax.2.3.0.LICENSE.txt create mode 100644 main/webapp/modules/core/scripts/util/date-time.js diff --git a/LICENSE.txt b/LICENSE.txt index 033ea7894..796bf70b5 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -85,6 +85,9 @@ licenses/dom4j.LICENSE.txt licenses/simile.LICENSE.txt simile vicino +licenses/simile-ajax.2.3.0.LICENSE.txt + Simile Ajax + licenses/arithcode.LICENSE.txt arithcode @@ -94,7 +97,6 @@ licenses/freebase_suggest.LICENSE.txt licenses/chrome_frame.LICENSE.txt CFInstall - MIT --- diff --git a/licenses/simile-ajax.2.3.0.LICENSE.txt b/licenses/simile-ajax.2.3.0.LICENSE.txt new file mode 100644 index 000000000..d2ab060e4 --- /dev/null +++ b/licenses/simile-ajax.2.3.0.LICENSE.txt @@ -0,0 +1,35 @@ +/* + * (c) Copyright The SIMILE Project 2008. 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. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. + * + * Note: JQuery, www.jquery.com is included in this distribution. It is + * covered by its own license: + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + */ \ No newline at end of file diff --git a/main/webapp/modules/core/MOD-INF/controller.js b/main/webapp/modules/core/MOD-INF/controller.js index 0d903744c..1d105e720 100644 --- a/main/webapp/modules/core/MOD-INF/controller.js +++ b/main/webapp/modules/core/MOD-INF/controller.js @@ -316,6 +316,7 @@ function init() { "scripts/util/menu.js", "scripts/util/dialog.js", "scripts/util/dom.js", + "scripts/util/date-time.js", "scripts/util/encoding.js", "scripts/index.js", @@ -391,6 +392,7 @@ function init() { "scripts/util/menu.js", "scripts/util/dialog.js", "scripts/util/dom.js", + "scripts/util/date-time.js", "scripts/util/custom-suggest.js", "scripts/util/encoding.js", diff --git a/main/webapp/modules/core/scripts/util/date-time.js b/main/webapp/modules/core/scripts/util/date-time.js new file mode 100644 index 000000000..692eaa26e --- /dev/null +++ b/main/webapp/modules/core/scripts/util/date-time.js @@ -0,0 +1,232 @@ +/* + +Copyright 2011, 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: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +OWNER OR 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. + + */ + +/* + * The following code has been adapted from the Simile Ajax library at + * http://code.google.com/p/simile-widgets/ + */ + +/* + * (c) Copyright The SIMILE Project 2008. 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. + * + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. + * + * Note: JQuery, www.jquery.com is included in this distribution. It is + * covered by its own license: + * + * Copyright (c) 2008 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + */ + +DateTimeUtil = {}; + +DateTimeUtil._dateRegexp = new RegExp( + "^(-?)([0-9]{4})(" + [ + "(-?([0-9]{2})(-?([0-9]{2}))?)", // -month-dayOfMonth + "(-?([0-9]{3}))", // -dayOfYear + "(-?W([0-9]{2})(-?([1-7]))?)" // -Wweek-dayOfWeek + ].join("|") + ")?$" +); +DateTimeUtil._timezoneRegexp = new RegExp( + "Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$" +); +DateTimeUtil._timeRegexp = new RegExp( + "^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(\.([0-9]+))?)?)?$" +); + +DateTimeUtil.setIso8601Date = function(dateObject, string) { + /* + * This function has been adapted from dojo.date, v.0.3.0 + * http://dojotoolkit.org/. + */ + + var d = string.match(DateTimeUtil._dateRegexp); + if(!d) { + throw new Error("Invalid date string: " + string); + } + + var sign = (d[1] == "-") ? -1 : 1; // BC or AD + var year = sign * d[2]; + var month = d[5]; + var date = d[7]; + var dayofyear = d[9]; + var week = d[11]; + var dayofweek = (d[13]) ? d[13] : 1; + + dateObject.setUTCFullYear(year); + if (dayofyear) { + dateObject.setUTCMonth(0); + dateObject.setUTCDate(Number(dayofyear)); + } else if (week) { + dateObject.setUTCMonth(0); + dateObject.setUTCDate(1); + var gd = dateObject.getUTCDay(); + var day = (gd) ? gd : 7; + var offset = Number(dayofweek) + (7 * Number(week)); + + if (day <= 4) { + dateObject.setUTCDate(offset + 1 - day); + } else { + dateObject.setUTCDate(offset + 8 - day); + } + } else { + if (month) { + dateObject.setUTCDate(1); + dateObject.setUTCMonth(month - 1); + } + if (date) { + dateObject.setUTCDate(date); + } + } + + return dateObject; +}; + +/** + * Takes a date object and a string containing an ISO 8601 time and sets the + * the time using information parsed from the string. Note that this method + * does not parse any date information. + * + * @param {Date} dateObject the date object to modify + * @param {String} string an ISO 8601 string to parse + * @return {Date} the modified date object + */ +DateTimeUtil.setIso8601Time = function (dateObject, string) { + /* + * This function has been adapted from dojo.date, v.0.3.0 + * http://dojotoolkit.org/. + */ + + var d = string.match(DateTimeUtil._timeRegexp); + if(!d) { + SimileAjax.Debug.warn("Invalid time string: " + string); + return false; + } + var hours = d[1]; + var mins = Number((d[3]) ? d[3] : 0); + var secs = (d[5]) ? d[5] : 0; + var ms = d[7] ? (Number("0." + d[7]) * 1000) : 0; + + dateObject.setUTCHours(hours); + dateObject.setUTCMinutes(mins); + dateObject.setUTCSeconds(secs); + dateObject.setUTCMilliseconds(ms); + + return dateObject; +}; + +/** + * The timezone offset in minutes in the user's browser. + * @type Number + */ +DateTimeUtil.timezoneOffset = new Date().getTimezoneOffset(); + +/** + * Takes a date object and a string containing an ISO 8601 date and time and + * sets the date object using information parsed from the string. + * + * @param {Date} dateObject the date object to modify + * @param {String} string an ISO 8601 string to parse + * @return {Date} the modified date object + */ +DateTimeUtil.setIso8601 = function (dateObject, string){ + /* + * This function has been adapted from dojo.date, v.0.3.0 + * http://dojotoolkit.org/. + */ + + var offset = null; + var comps = (string.indexOf("T") == -1) ? string.split(" ") : string.split("T"); + + DateTimeUtil.setIso8601Date(dateObject, comps[0]); + if (comps.length == 2) { + // first strip timezone info from the end + var d = comps[1].match(DateTimeUtil._timezoneRegexp); + if (d) { + if (d[0] == 'Z') { + offset = 0; + } else { + offset = (Number(d[3]) * 60) + Number(d[5]); + offset *= ((d[2] == '-') ? 1 : -1); + } + comps[1] = comps[1].substr(0, comps[1].length - d[0].length); + } + + DateTimeUtil.setIso8601Time(dateObject, comps[1]); + } + if (offset == null) { + offset = dateObject.getTimezoneOffset(); // local time zone if no tz info + } + dateObject.setTime(dateObject.getTime() + offset * 60000); + + return dateObject; +}; + +/** + * Takes a string containing an ISO 8601 date and returns a newly instantiated + * date object with the parsed date and time information from the string. + * + * @param {String} string an ISO 8601 string to parse + * @return {Date} a new date object created from the string + */ +DateTimeUtil.parseIso8601DateTime = function (string) { + try { + return DateTimeUtil.setIso8601(new Date(0), string); + } catch (e) { + return null; + } +}; \ No newline at end of file diff --git a/main/webapp/modules/core/scripts/views/data-table/cell-ui.js b/main/webapp/modules/core/scripts/views/data-table/cell-ui.js index 15015ea37..982cb9e9a 100644 --- a/main/webapp/modules/core/scripts/views/data-table/cell-ui.js +++ b/main/webapp/modules/core/scripts/views/data-table/cell-ui.js @@ -488,6 +488,9 @@ DataTableCellUI.prototype._startEdit = function(elmt) { value = ("true" == text); } else if (type == "date") { value = Date.parse(text); + if (!value) { + value = DateTimeUtil.parseIso8601DateTime(text); + } if (!value) { alert("Not a valid date."); return;