From e87e6acf78297bc718a6b42589dc7027c4ffc601 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 17:43:03 +0100 Subject: [PATCH 1/6] Datepicker: Make Calendar pass-through options more dynamic Move calendarOptions variable into datepicker prototype. --- ui/datepicker.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 09f89cd252d..8e9aca716f9 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -31,10 +31,7 @@ } }(function( $ ) { -var widget, - calendarOptions = [ "buttons", "dateFormat", "disabled", "eachDay", "max", "min", "numberOfMonths", "showWeek" ]; - -widget = $.widget( "ui.datepicker", { +var widget = $.widget( "ui.datepicker", { version: "@VERSION", options: { appendTo: null, @@ -52,6 +49,9 @@ widget = $.widget( "ui.datepicker", { select: null }, + calendarOptions: [ "buttons", "dateFormat", "disabled", "eachDay", "max", + "min", "numberOfMonths", "showWeek" ], + _create: function() { this.suppressExpandOnFocus = false; this._createCalendar(); @@ -312,7 +312,7 @@ widget = $.widget( "ui.datepicker", { _setOption: function( key, value ) { this._super( key, value ); - if ( $.inArray( key, calendarOptions ) !== -1 ) { + if ( $.inArray( key, this.calendarOptions ) !== -1 ) { this.calendarInstance.option( key, value ); } @@ -341,7 +341,7 @@ widget = $.widget( "ui.datepicker", { } }); -$.each( calendarOptions, function( index, option ) { +$.each( $.ui.datepicker.prototype.calendarOptions, function( index, option ) { $.ui.datepicker.prototype.options[ option ] = $.ui.calendar.prototype.options[ option ]; }); From cf3e57482361f554c89f915aae7e56ca9733133e Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 17:51:06 +0100 Subject: [PATCH 2/6] Datepicker: Remove whitespace --- ui/datepicker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/datepicker.js b/ui/datepicker.js index 8e9aca716f9..4a1c486f594 100644 --- a/ui/datepicker.js +++ b/ui/datepicker.js @@ -255,7 +255,7 @@ var widget = $.widget( "ui.datepicker", { this._setHiddenPicker(); this._hide( this.calendar, this.options.hide ); - this.element.attr( "tabindex" , 0 ); + this.element.attr( "tabindex", 0 ); this.isOpen = false; this._trigger( "close", event ); @@ -274,7 +274,7 @@ var widget = $.widget( "ui.datepicker", { value: function( value ) { if ( arguments.length ) { - this.valueAsDate( Globalize.parseDate( value , this.options.dateFormat ) ); + this.valueAsDate( Globalize.parseDate( value, this.options.dateFormat ) ); } else { return this._getParsedValue() ? this.element.val() : null; } From 8cbbe1eab9a29e00192e9e84de91ba516b92c77d Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 18:23:49 +0100 Subject: [PATCH 3/6] Calendar: Use button instead of link elements for day items --- tests/unit/calendar/calendar_core.js | 12 ++++++------ tests/unit/calendar/calendar_methods.js | 10 ++++++++-- tests/unit/calendar/calendar_options.js | 12 ++++++------ tests/unit/datepicker/datepicker_core.js | 2 +- tests/unit/datepicker/datepicker_events.js | 4 ++-- tests/unit/datepicker/datepicker_methods.js | 10 ++++++++-- themes/base/calendar.css | 13 ++++++++++--- ui/calendar.js | 19 ++++++++++--------- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/tests/unit/calendar/calendar_core.js b/tests/unit/calendar/calendar_core.js index 9ffbe50925c..dbcdda8eae1 100644 --- a/tests/unit/calendar/calendar_core.js +++ b/tests/unit/calendar/calendar_core.js @@ -306,7 +306,7 @@ asyncTest( "mouse", function() { date = new Date(); function step1() { - $( "tbody a:contains(10)", element ).simulate( "mousedown" ); + $( "tbody button:contains(10)", element ).simulate( "mousedown" ); date.setDate( 10 ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), @@ -315,7 +315,7 @@ asyncTest( "mouse", function() { ); element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); - $( ".ui-calendar-calendar tbody a:contains(12)", element ).simulate( "mousedown" ); + $( ".ui-calendar-calendar tbody button:contains(12)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 12 ), @@ -325,7 +325,7 @@ asyncTest( "mouse", function() { // Previous/next element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); $( ".ui-calendar-prev", element ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(16)", element ).simulate( "mousedown" ); + $( ".ui-calendar-calendar tbody button:contains(16)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 1 - 1, 16 ), @@ -334,7 +334,7 @@ asyncTest( "mouse", function() { element.calendar( "option", "value", new Date( 2008, 2 - 1, 4) ); $( ".ui-calendar-next", element ).simulate( "click" ); - $( ".ui-calendar-calendar tbody a:contains(18)", element ).simulate( "mousedown" ); + $( ".ui-calendar-calendar tbody button:contains(18)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 3 - 1, 18 ), @@ -354,7 +354,7 @@ asyncTest( "mouse", function() { }); $( ".ui-calendar-prev", element ).simulate( "click" ); - $( "tbody a:contains(16)", element ).simulate( "mousedown" ); + $( "tbody button:contains(16)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 16 ), @@ -372,7 +372,7 @@ asyncTest( "mouse", function() { }); $( ".ui-calendar-next", element ).simulate( "click" ); - $( "tbody a:contains(18)", element ).simulate( "mousedown" ); + $( "tbody button:contains(18)", element ).simulate( "mousedown" ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2008, 2 - 1, 18 ), diff --git a/tests/unit/calendar/calendar_methods.js b/tests/unit/calendar/calendar_methods.js index c7b7bf8dc8f..d447e4eab8b 100644 --- a/tests/unit/calendar/calendar_methods.js +++ b/tests/unit/calendar/calendar_methods.js @@ -42,7 +42,10 @@ test( "value", function() { var element = $( "#calendar" ).calendar(); element.calendar( "value", "1/1/14" ); - ok( element.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "first day marked as selected" ); + ok( element.find( "button[data-timestamp]:first" ) + .hasClass( "ui-state-active" ), + "first day marked as selected" + ); equal( element.calendar( "value" ), "1/1/14", "getter" ); element.calendar( "value", "abc" ); @@ -58,7 +61,10 @@ test( "valueAsDate", function() { date2; element.calendar( "valueAsDate", new Date( 2014, 0, 1 ) ); - ok( element.find( "a[data-timestamp]:first" ).hasClass( "ui-state-active" ), "First day marked as selected" ); + ok( element.find( "button[data-timestamp]:first" ) + .hasClass( "ui-state-active" ), + "First day marked as selected" + ); TestHelpers.calendar.equalsDate( element.calendar( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); element.calendar( "destroy" ); diff --git a/tests/unit/calendar/calendar_options.js b/tests/unit/calendar/calendar_options.js index e5a09d3d89e..f1ec947550f 100644 --- a/tests/unit/calendar/calendar_options.js +++ b/tests/unit/calendar/calendar_options.js @@ -112,7 +112,7 @@ test( "dateFormat", function() { var element = $( "#calendar" ).calendar({ value: "1/1/14" }), - firstDayLink = element.calendar( "widget" ).find( "td[id]:first a" ); + firstDayLink = element.calendar( "widget" ).find( "td[id]:first button" ); firstDayLink.trigger( "mousedown" ); equal( element.calendar( "value" ), "1/1/14", "default formatting" ); @@ -128,8 +128,8 @@ test( "eachDay", function() { picker = input.calendar( "widget" ), firstCell = picker.find( "td[id]:first" ); - equal( firstCell.find( "a" ).length, 1, "days are selectable by default" ); - timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 ); + equal( firstCell.find( "button" ).length, 1, "days are selectable by default" ); + timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 ); equal( new Date( timestamp ).getDate(), 1, "first available day is the 1st by default" ); // Do not render the 1st of the month @@ -139,7 +139,7 @@ test( "eachDay", function() { } }); firstCell = picker.find( "td[id]:first" ); - timestamp = parseInt( firstCell.find( "a" ).attr( "data-timestamp" ), 10 ); + timestamp = parseInt( firstCell.find( "button" ).attr( "data-timestamp" ), 10 ); equal( new Date( timestamp ).getDate(), 2, "first available day is the 2nd" ); // Display the 1st of the month but make it not selectable. @@ -149,14 +149,14 @@ test( "eachDay", function() { } }); firstCell = picker.find( "td[id]:first" ); - equal( firstCell.find( "a" ).length, 0, "the 1st is not selectable" ); + ok( firstCell.find( "button" ).prop( "disabled" ), "the 1st is not selectable" ); input.calendar( "option", "eachDay", function( day ) { if ( day.date === 1 ) { day.extraClasses = "ui-custom"; } }); - ok( picker.find( "td[id]:first a" ).hasClass( "ui-custom" ), "extraClasses applied" ); + ok( picker.find( "td[id]:first button" ).hasClass( "ui-custom" ), "extraClasses applied" ); input.calendar( "destroy" ); }); diff --git a/tests/unit/datepicker/datepicker_core.js b/tests/unit/datepicker/datepicker_core.js index ffb7ab6c4f2..f7b508d7ad3 100644 --- a/tests/unit/datepicker/datepicker_core.js +++ b/tests/unit/datepicker/datepicker_core.js @@ -136,7 +136,7 @@ asyncTest( "mouse", function() { setTimeout(function() { input.val( "4/4/08" ).datepicker( "refresh" ).datepicker( "open" ); - $( ".ui-calendar-calendar tbody a:contains(12)", picker ).simulate( "mousedown", {} ); + $( ".ui-calendar-calendar tbody button:contains(12)", picker ).simulate( "mousedown", {} ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2008, 4 - 1, 12 ), diff --git a/tests/unit/datepicker/datepicker_events.js b/tests/unit/datepicker/datepicker_events.js index 6b2cc200727..35720ebf6c7 100644 --- a/tests/unit/datepicker/datepicker_events.js +++ b/tests/unit/datepicker/datepicker_events.js @@ -57,7 +57,7 @@ test( "close", function() { shouldFire = false; input.datepicker( "open" ); shouldFire = true; - input.datepicker( "widget" ).find( "tbody tr:first a:first" ).simulate( "mousedown" ); + input.datepicker( "widget" ).find( "tbody tr:first button:first" ).simulate( "mousedown" ); }); test( "open", function() { @@ -96,7 +96,7 @@ asyncTest( "select", function() { .simulate( "focus" ) .simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); setTimeout(function() { - widget.find( "tbody tr:first a:first" ).simulate( "mousedown" ); + widget.find( "tbody tr:first button:first" ).simulate( "mousedown" ); input.datepicker( "close" ); step2(); }, 100 ); diff --git a/tests/unit/datepicker/datepicker_methods.js b/tests/unit/datepicker/datepicker_methods.js index 76b76813c4f..b969c00f493 100644 --- a/tests/unit/datepicker/datepicker_methods.js +++ b/tests/unit/datepicker/datepicker_methods.js @@ -72,7 +72,10 @@ test( "value", function() { equal( input.val(), "1/1/14", "input's value set" ); input.datepicker( "open" ); - ok( picker.find( "a[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), "first day marked as selected" ); + ok( + picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), + "first day marked as selected" + ); equal( input.datepicker( "value" ), "1/1/14", "getter" ); input.val( "abc" ); @@ -88,7 +91,10 @@ test( "valueAsDate", function() { input.datepicker( "valueAsDate", new Date( 2014, 0, 1 ) ); equal( input.val(), "1/1/14", "Input's value set" ); - ok( picker.find( "a[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), "First day marked as selected" ); + ok( + picker.find( "button[data-timestamp]" ).eq( 0 ).hasClass( "ui-state-active" ), + "First day marked as selected" + ); TestHelpers.datepicker.equalsDate( input.datepicker( "valueAsDate" ), new Date( 2014, 0, 1 ), "Getter" ); input.val( "a/b/c" ); diff --git a/themes/base/calendar.css b/themes/base/calendar.css index 7dc8e182929..2262e97a9e5 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -82,12 +82,19 @@ border: 0; padding: 1px; } -.ui-calendar td span, -.ui-calendar td a { +.ui-calendar td button { display: block; padding: .2em; text-align: right; - text-decoration: none; + cursor: pointer; + width: 100%; +} +.ui-calendar td button::-moz-focus-inner { + padding: 0; + border: 0; +} +.ui-calendar .ui-state-disabled button { + cursor: default; } .ui-calendar .ui-calendar-buttonpane { background-image: none; diff --git a/ui/calendar.js b/ui/calendar.js index 44d07a285db..6cb0dd343e6 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -75,7 +75,7 @@ return $.widget( "ui.calendar", { this.date.adjust( "M", this.options.numberOfMonths ); this.refresh(); }, - "mousedown .ui-calendar-calendar a": function( event ) { + "mousedown .ui-calendar-calendar button": function( event ) { event.preventDefault(); // TODO Exclude clicks on lead days or handle them correctly @@ -85,8 +85,8 @@ return $.widget( "ui.calendar", { }, "mouseenter .ui-calendar-header button": "_hover", "mouseleave .ui-calendar-header button": "_hover", - "mouseenter .ui-calendar-calendar a": "_hover", - "mouseleave .ui-calendar-calendar a": "_hover", + "mouseenter .ui-calendar-calendar button": "_hover", + "mouseleave .ui-calendar-calendar button": "_hover", "keydown .ui-calendar-calendar": "_handleKeydown" }); @@ -152,7 +152,7 @@ return $.widget( "ui.calendar", { .removeClass( "ui-state-focus" ); this.activeDescendant = this.grid.find( - this._sanitizeSelector( "#" + id ) + " > a" + this._sanitizeSelector( "#" + id ) + " > button" ).addClass( "ui-state-focus" ); }, @@ -351,8 +351,8 @@ return $.widget( "ui.calendar", { }, _buildDayElement: function( day, selectable ) { - var classes = [ "ui-state-default" ], - content = ""; + var attributes, content, + classes = [ "ui-state-default" ]; if ( day === this.date && selectable ) { classes.push( "ui-state-focus" ); @@ -368,12 +368,13 @@ return $.widget( "ui.calendar", { classes.push( day.extraClasses.split( " " ) ); } - classes = " class='" + classes.join( " " ) + "'"; + attributes = " class='" + classes.join( " " ) + "'"; if ( selectable ) { - content = "" + day.date + ""; + attributes += " tabindex='-1' data-timestamp='" + day.timestamp + "'"; } else { - content = "" + day.date + ""; + attributes += " disabled='disabled'"; } + content = "" + day.date + ""; if ( day.today ) { content += ", " + this._getTranslation( "currentText" ) + ""; From 854fc85feb59033a96baf501736acd08b4dd7f35 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Tue, 20 Jan 2015 18:35:59 +0100 Subject: [PATCH 4/6] Calendar: Fix border style for multiple months --- ui/calendar.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/calendar.js b/ui/calendar.js index 6cb0dd343e6..ced58bc528d 100644 --- a/ui/calendar.js +++ b/ui/calendar.js @@ -191,15 +191,15 @@ return $.widget( "ui.calendar", { // TODO: Shouldn't we pass date as a parameter to build* fns instead of setting this.date? this.date = months[ i ]; + headerClass = "ui-calendar-header ui-widget-header ui-helper-clearfix"; if ( months[ i ].first ) { - headerClass = "ui-corner-left"; + headerClass += " ui-corner-left"; } else if ( months[ i ].last ) { - headerClass = "ui-corner-right"; + headerClass += " ui-corner-right"; } html += "
" + - "
"; + "
"; if ( months[ i ].first ) { html += this._buildPreviousLink(); } else if ( months[ i ].last ) { From 0fd288fb68f44f89c0d282890a5558cd36ff3261 Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 31 Jan 2015 00:42:40 +0100 Subject: [PATCH 5/6] Calendar: Clean up styles, add comments --- themes/base/calendar.css | 43 ++++++---------------------------------- 1 file changed, 6 insertions(+), 37 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index 2262e97a9e5..b8e99baf545 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -12,6 +12,8 @@ width: 17em; padding: .2em .2em 0; } + +/* calendar header */ .ui-calendar .ui-calendar-header { position: relative; padding: .2em 0; @@ -29,22 +31,12 @@ background: none; border: none; } -.ui-calendar .ui-calendar-prev-hover, -.ui-calendar .ui-calendar-next-hover { - top: 1px; -} .ui-calendar .ui-calendar-prev { left: 2px; } .ui-calendar .ui-calendar-next { right: 2px; } -.ui-calendar .ui-calendar-prev-hover { - left: 1px; -} -.ui-calendar .ui-calendar-next-hover { - right: 1px; -} .ui-calendar .ui-calendar-prev .ui-icon, .ui-calendar .ui-calendar-next .ui-icon { display: block; @@ -58,14 +50,8 @@ line-height: 1.8em; text-align: center; } -.ui-calendar .ui-calendar-title select { - font-size: 1em; - margin: 1px 0; -} -.ui-calendar select.ui-calendar-month, -.ui-calendar select.ui-calendar-year { - width: 49%; -} + +/* calendar grid */ .ui-calendar table { width: 100%; font-size: .9em; @@ -96,6 +82,8 @@ .ui-calendar .ui-state-disabled button { cursor: default; } + +/* button pane */ .ui-calendar .ui-calendar-buttonpane { background-image: none; margin: .7em 0 0 0; @@ -128,19 +116,6 @@ width: 95%; margin: 0 2.5% .4em; } -.ui-calendar-multi-2 .ui-calendar-group { - width: 50%; -} -.ui-calendar-multi-3 .ui-calendar-group { - width: 33.3%; -} -.ui-calendar-multi-4 .ui-calendar-group { - width: 25%; -} -.ui-calendar-multi .ui-calendar-group-last .ui-calendar-header, -.ui-calendar-multi .ui-calendar-group-middle .ui-calendar-header { - border-left-width: 0; -} .ui-calendar-multi .ui-calendar-buttonpane { clear: left; } @@ -180,9 +155,3 @@ .ui-calendar-rtl .ui-calendar-group { float: right; } -.ui-calendar-rtl .ui-calendar-group-last .ui-calendar-header, -.ui-calendar-rtl .ui-calendar-group-middle .ui-calendar-header { - border-right-width: 0; - border-left-width: 1px; -} - From 54aec0ce2018db707ac6893fcc8962bbffbc12de Mon Sep 17 00:00:00 2001 From: Felix Nagel Date: Sat, 31 Jan 2015 00:53:14 +0100 Subject: [PATCH 6/6] Calendar: Adjust styles to match theme changes --- themes/base/calendar.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/themes/base/calendar.css b/themes/base/calendar.css index b8e99baf545..def9fe4fffb 100644 --- a/themes/base/calendar.css +++ b/themes/base/calendar.css @@ -23,8 +23,8 @@ cursor: pointer; position: absolute; top: 2px; - width: 19px; - height: 18px; + width: 36px; + height: 31px; } .ui-calendar .ui-calendar-prev:not(.ui-state-hover):not(.ui-state-focus), .ui-calendar .ui-calendar-next:not(.ui-state-hover):not(.ui-state-focus) { @@ -110,6 +110,7 @@ display: inline-block; } .ui-calendar-multi .ui-calendar-group { + width: 17em; float: left; } .ui-calendar-multi .ui-calendar-group table {