Adam Shaw 16 ani în urmă
părinte
comite
fc27aedcca
21 a modificat fișierele cu 2590 adăugiri și 1778 ștergeri
  1. 68 68
      docs/date-utils.txt
  2. 48 48
      docs/google-calendar.txt
  3. 36 36
      docs/locale.txt
  4. 77 77
      docs/methods.txt
  5. 24 24
      docs/theming.txt
  6. 165 165
      src/css/agenda.css
  7. 55 55
      src/css/grid.css
  8. 299 297
      src/css/main.css
  9. 9 4
      src/grid.js
  10. 6 10
      src/main.js
  11. 16 16
      src/misc/head.txt
  12. 0 11
      src/util.js
  13. 114 114
      tests/gcal.html
  14. 819 0
      tests/jquery-legacy/ui.resizable.js
  15. 107 107
      tests/loader.js
  16. 81 81
      tests/locale.html
  17. 149 149
      tests/methods.html
  18. 109 108
      tests/options.html
  19. 143 143
      tests/sources.html
  20. 86 86
      tests/theming.html
  21. 179 179
      tests/triggers.html

+ 68 - 68
docs/date-utils.txt

@@ -1,69 +1,69 @@
-
-Date Utilities
-==============
-
-**formatDate** - $.fullCalendar.formatDate(*date, formatString, [options]*)
-	Format a date into a string value with a specified format.
-	The format can be combinations of the following:
-	
-	* **s**		- seconds
-	* **ss**	- seconds, 2 digits
-	* **m**		- minutes
-	* **mm**	- minutes, 2 digits
-	* **h**		- hours
-	* **hh**	- hours, 2 digits
-	* **H**		- hours, military time
-	* **HH**	- hours, milirary time, 2 digits
-	* **d**		- date number
-	* **dd**	- date number, 2 digits
-	* **ddd**	- date name, short
-	* **dddd**	- date name, full
-	* **M**		- month number
-	* **MM**	- month number, 2 digits
-	* **MMM**	- month name, short
-	* **MMMM**	- month name, full
-	* **yy**	- year, 2 digits
-	* **yyyy**	- year, 4 digits
-	* **t**		- 'a' or 'p'
-	* **tt**	- 'am' or 'pm'
-	* **T**		- 'A' or 'P'
-	* **TT**	- 'AM' or 'PM'
-	* **u**		- ISO8601 format
-	* **S**		- 'st', 'nd', 'rd', 'th' for the date
-	
-	Special Characters:
-	
-		``'...'``
-			literal text
-		
-		``''``
-			single quote
-		
-		``(...)``
-			only displays format if one of the enclosed variables is non-zero
-		
-	*options* can override any of the :ref:`Locale Options<locale>`
-	
-	
-.. _formatDates:
-	
-**formatDates** - $.fullCalendar.formatDates(*date1, date2, formatString, [options]*)
-	Similar to ``formatDate``, but accepts *two* dates, leveraging the following
-	special characters in *formatString*:
-	
-		``{...}``
-			switches to formatting the 2nd date
-		
-		``[...]``
-			only displays the enclosed format if the current date is different from the
-			alternate date in the same regards
-
-	
-**parseDate** - $.fullCalendar.parseDate(*string*)
-	Parses a string and returns a javascript Date object.
-	The string may be in ISO8601 format, IETF format, or a UNIX timestamp.
-
-	
-**parseISO8601** - $.fullCalendar.parseISO8601(*string, [ignoreTimezone]*)
-	Parses an ISO8601 string into a javascript Date object.
+
+Date Utilities
+==============
+
+**formatDate** - $.fullCalendar.formatDate(*date, formatString, [options]*)
+	Format a date into a string value with a specified format.
+	The format can be combinations of the following:
+	
+	* **s**		- seconds
+	* **ss**	- seconds, 2 digits
+	* **m**		- minutes
+	* **mm**	- minutes, 2 digits
+	* **h**		- hours
+	* **hh**	- hours, 2 digits
+	* **H**		- hours, military time
+	* **HH**	- hours, milirary time, 2 digits
+	* **d**		- date number
+	* **dd**	- date number, 2 digits
+	* **ddd**	- date name, short
+	* **dddd**	- date name, full
+	* **M**		- month number
+	* **MM**	- month number, 2 digits
+	* **MMM**	- month name, short
+	* **MMMM**	- month name, full
+	* **yy**	- year, 2 digits
+	* **yyyy**	- year, 4 digits
+	* **t**		- 'a' or 'p'
+	* **tt**	- 'am' or 'pm'
+	* **T**		- 'A' or 'P'
+	* **TT**	- 'AM' or 'PM'
+	* **u**		- ISO8601 format
+	* **S**		- 'st', 'nd', 'rd', 'th' for the date
+	
+	Special Characters:
+	
+		``'...'``
+			literal text
+		
+		``''``
+			single quote
+		
+		``(...)``
+			only displays format if one of the enclosed variables is non-zero
+		
+	*options* can override any of the :ref:`Locale Options<locale>`
+	
+	
+.. _formatDates:
+	
+**formatDates** - $.fullCalendar.formatDates(*date1, date2, formatString, [options]*)
+	Similar to ``formatDate``, but accepts *two* dates, leveraging the following
+	special characters in *formatString*:
+	
+		``{...}``
+			switches to formatting the 2nd date
+		
+		``[...]``
+			only displays the enclosed format if the current date is different from the
+			alternate date in the same regards
+
+	
+**parseDate** - $.fullCalendar.parseDate(*string*)
+	Parses a string and returns a javascript Date object.
+	The string may be in ISO8601 format, IETF format, or a UNIX timestamp.
+
+	
+**parseISO8601** - $.fullCalendar.parseISO8601(*string, [ignoreTimezone]*)
+	Parses an ISO8601 string into a javascript Date object.
 	

+ 48 - 48
docs/google-calendar.txt

@@ -1,49 +1,49 @@
-
-Google Calendar
-===============
-
-To integrate with your Google Calendar, you must first **make your calendar public**:
-
-#. In the Google Calendar interface, locate the "My Calendar" box on the left.
-
-#. Click the arrow next to the calendar you need.
-
-#. A menu will appear. Click "Share this calendar."
-
-#. Check "Make this calendar public."
-
-#. Make sure "Share only my free/busy information" is *unchecked*.
-
-#. Click "Save."
-
-Then, you must obtain your calendar's **XML feed URL**.
-
-#. In the Google Calendar interface, locate the "My Calendar" box on the left
-
-#. Click the arrow next to the calendar you need.
-
-#. A menu will appear. Click "Calendar settings."
-
-#. In the "Calendar Address" section of the screen, click the XML badge.
-
-#. Your feed's URL will appear.
-
-The ``$.fullCalendar.gcalFeed`` function produces an event source that can be
-passed to the ``events`` or ``eventSources`` options::
-
-   $('#calendar').fullCalendar({
-      
-      events: $.fullCalendar.gcalFeed(
-         "http://www.google.com/calendar/feeds/...",   // feed URL
-         { className: 'gcal-events' }                  // optional options
-      )
-      
-   });
-   
-Here is a list of available options:
-
-* **className** - CSS class to attach to each event from this Google Calendar
-
-* **editable** - whether to allow dragging/resizing (default: ``false``)
-   
+
+Google Calendar
+===============
+
+To integrate with your Google Calendar, you must first **make your calendar public**:
+
+#. In the Google Calendar interface, locate the "My Calendar" box on the left.
+
+#. Click the arrow next to the calendar you need.
+
+#. A menu will appear. Click "Share this calendar."
+
+#. Check "Make this calendar public."
+
+#. Make sure "Share only my free/busy information" is *unchecked*.
+
+#. Click "Save."
+
+Then, you must obtain your calendar's **XML feed URL**.
+
+#. In the Google Calendar interface, locate the "My Calendar" box on the left
+
+#. Click the arrow next to the calendar you need.
+
+#. A menu will appear. Click "Calendar settings."
+
+#. In the "Calendar Address" section of the screen, click the XML badge.
+
+#. Your feed's URL will appear.
+
+The ``$.fullCalendar.gcalFeed`` function produces an event source that can be
+passed to the ``events`` or ``eventSources`` options::
+
+   $('#calendar').fullCalendar({
+      
+      events: $.fullCalendar.gcalFeed(
+         "http://www.google.com/calendar/feeds/...",   // feed URL
+         { className: 'gcal-events' }                  // optional options
+      )
+      
+   });
+   
+Here is a list of available options:
+
+* **className** - CSS class to attach to each event from this Google Calendar
+
+* **editable** - whether to allow dragging/resizing (default: ``false``)
+   
 See *gcal.html* in the *examples* directory for a complete example.

+ 36 - 36
docs/locale.txt

@@ -1,36 +1,36 @@
-
-.. _locale:
-
-Locale Options
-==============
-
-**firstDay**: Integer, *Default*: ``0``
-	The day-of-week each week begins. Sunday=0,
-	Monday=1 (for UK users), Tuesday=2, etc.
-  
-**isRTL**: Boolean, *Default*: ``false``
-	Displays the calendar right-to-left (for languages such as Arabic and Hebrew)
-  
-**monthNames**: Array, *Default*: ``['January','February','March'...``
-	Full names of months.
-
-**monthNamesShort**: Array, *Default*: ``['Jan','Feb','Mar'...``
-	Abbreviated names of months.
-
-**dayNames**: Array, *Default*: ``['Sunday','Monday','Tuesday'...``
-	Full names of days-of-week.
-
-**dayNamesShort**: Array, *Default*: ``['Sun','Mon','Tue'...``
-	Abbreviated names of days-of-week.
-
-**buttonText**: Object
-	Text that will be displayed on buttons of the header. Default::
-	
-		{
-			prev: '&#9668;', // left triangle
-			next: '&#9658;', // right triangle
-			today: 'today',
-			month: 'month',
-			week: 'week',
-			day: 'day'
-		}
+
+.. _locale:
+
+Locale Options
+==============
+
+**firstDay**: Integer, *Default*: ``0``
+	The day-of-week each week begins. Sunday=0,
+	Monday=1 (for UK users), Tuesday=2, etc.
+  
+**isRTL**: Boolean, *Default*: ``false``
+	Displays the calendar right-to-left (for languages such as Arabic and Hebrew)
+  
+**monthNames**: Array, *Default*: ``['January','February','March'...``
+	Full names of months.
+
+**monthNamesShort**: Array, *Default*: ``['Jan','Feb','Mar'...``
+	Abbreviated names of months.
+
+**dayNames**: Array, *Default*: ``['Sunday','Monday','Tuesday'...``
+	Full names of days-of-week.
+
+**dayNamesShort**: Array, *Default*: ``['Sun','Mon','Tue'...``
+	Abbreviated names of days-of-week.
+
+**buttonText**: Object
+	Text that will be displayed on buttons of the header. Default::
+	
+		{
+			prev: '&#9668;', // left triangle
+			next: '&#9658;', // right triangle
+			today: 'today',
+			month: 'month',
+			week: 'week',
+			day: 'day'
+		}

+ 77 - 77
docs/methods.txt

@@ -1,78 +1,78 @@
-
-Methods
-=======
-
-The following are methods that can be called on a FullCalendar-initialized
-jQuery object:
-
-**prev** - .fullCalendar('prev')
-	Moves the calendar one step back (either by a month, week, or day).
-
-**next** - .fullCalendar('next')
-	Moves the calendar one step forward (either by a month, week, or day).
-	
-**today** - .fullCalendar('today')
-	Moves the calendar to the current date.
-	
-**gotoDate** - .fullCalendar('gotoDate', *year, [month, [date]]*)
-	Moves the calendar to an arbitrary year/month/date.
-	
-	``month`` is 0-based, meaning January=0, February=1, etc.
-	
-**moveDate** - .fullCalendar('moveDate', *years, [months, [days]]*)
-	Moves the calendar forward/backward an arbitrary amount of time.
-	
-**updateEvent** - .fullCalendar('updateEvent', *calEvent*)
-	Reports changes about a modified :ref:`CalEvent <CalEvent>`. This will cause the event
-	to be rerendered on the calendar.
-	If there are repeating events on the calendar with the
-	same ID, these events will be changed as well.
-	
-	``calEvent`` must be a :ref:`CalEvent <CalEvent>` retrieved from a
-	:ref:`Triggered Action<triggered-actions>` or from the ``clientEvents`` method.
-	
-**renderEvent** - .fullCalendar('renderEvent', *calEvent, [stick]*)
-	Renders a new event on the calendar. ``calEvent`` must have
-	at least a ``title`` and a ``start``.
-	
-	By default, the event will disappear once the calendar refetches its event
-	sources (example: when prev/next is clicked). However, specifying ``stick`` as ``true``
-	will cause the event to be permanently fixed to the calendar.
-	
-**removeEvents** - .fullCalendar('removeEvents', *[idOrFilter]*)
-	If the second argument is omitted, all events are removed.
-	If the second argument is a :ref:`CalEvent's <CalEvent>` ID, all events with
-	the same ID will be removed.
-	
-	The second argument may also be a filter function that accepts
-	one :ref:`CalEvent <CalEvent>` argument and returns ``true`` or ``false`` about
-	whether it should be removed.
-	
-**clientEvents** - .fullCalendar('clientEvents', *[idOrFilter]*)
-	This method will return :ref:`CalEvents <CalEvent>` that FullCalendar has stored on
-	the client-side (browser).
-	
-	If the second argument is omitted, all events will be returned.
-	If the second argument is a :ref:`CalEvent's <CalEvent>` ID, all events with the
-	same ID will be returned.
-	
-	The second argument may also be a filter function that accepts
-	one :ref:`CalEvent <CalEvent>` argument and returns ``true`` or ``false`` about
-	whether it should be included in the result set.
-
-**addEventSource** - .fullCalendar('addEventSource', *source*)
-	Adds an :ref:`Event Source <event-sources>`. ``source`` may be an array/string/function just as in
-	the ``events`` option. Events will be immediately fetched from this source
-	and placed on the calendar.
-
-**removeEventSource** - .fullCalendar('removeEventSource', *source*)
-	Removes an :ref:`Event Source <event-sources>`. ``source`` must be a reference to the
-	original array/string/function. Events from the source will immediately be
-	removed from the calendar.
-
-**rerenderEvents** - .fullCalendar(``'rerenderEvents'``)
-	Rerenders all events on the screen.
-
-**refetchEvents** - .fullCalendar(``'refetchEvents'``)
-	Refetches events from all event sources and rerenders them on the screen.
+
+Methods
+=======
+
+The following are methods that can be called on a FullCalendar-initialized
+jQuery object:
+
+**prev** - .fullCalendar('prev')
+	Moves the calendar one step back (either by a month, week, or day).
+
+**next** - .fullCalendar('next')
+	Moves the calendar one step forward (either by a month, week, or day).
+	
+**today** - .fullCalendar('today')
+	Moves the calendar to the current date.
+	
+**gotoDate** - .fullCalendar('gotoDate', *year, [month, [date]]*)
+	Moves the calendar to an arbitrary year/month/date.
+	
+	``month`` is 0-based, meaning January=0, February=1, etc.
+	
+**moveDate** - .fullCalendar('moveDate', *years, [months, [days]]*)
+	Moves the calendar forward/backward an arbitrary amount of time.
+	
+**updateEvent** - .fullCalendar('updateEvent', *calEvent*)
+	Reports changes about a modified :ref:`CalEvent <CalEvent>`. This will cause the event
+	to be rerendered on the calendar.
+	If there are repeating events on the calendar with the
+	same ID, these events will be changed as well.
+	
+	``calEvent`` must be a :ref:`CalEvent <CalEvent>` retrieved from a
+	:ref:`Triggered Action<triggered-actions>` or from the ``clientEvents`` method.
+	
+**renderEvent** - .fullCalendar('renderEvent', *calEvent, [stick]*)
+	Renders a new event on the calendar. ``calEvent`` must have
+	at least a ``title`` and a ``start``.
+	
+	By default, the event will disappear once the calendar refetches its event
+	sources (example: when prev/next is clicked). However, specifying ``stick`` as ``true``
+	will cause the event to be permanently fixed to the calendar.
+	
+**removeEvents** - .fullCalendar('removeEvents', *[idOrFilter]*)
+	If the second argument is omitted, all events are removed.
+	If the second argument is an ID, all events with
+	the same ID will be removed.
+	
+	The second argument may also be a filter function that accepts
+	one :ref:`CalEvent <CalEvent>` argument and returns ``true`` if it
+	should be removed.
+	
+**clientEvents** - .fullCalendar('clientEvents', *[idOrFilter]*)
+	This method will return an array of :ref:`CalEvents <CalEvent>` that
+	FullCalendar has stored on the client-side (browser).
+	
+	If the second argument is omitted, all events will be returned.
+	If the second argument is an ID, all events with the
+	same ID will be returned.
+	
+	The second argument may also be a filter function that accepts
+	one :ref:`CalEvent <CalEvent>` argument and returns ``true`` if it should
+	be included in the result set.
+
+**addEventSource** - .fullCalendar('addEventSource', *source*)
+	Adds an :ref:`Event Source <event-sources>`. ``source`` may be an array/string/function just as in
+	the ``events`` option. Events will be immediately fetched from this source
+	and placed on the calendar.
+
+**removeEventSource** - .fullCalendar('removeEventSource', *source*)
+	Removes an :ref:`Event Source <event-sources>`. ``source`` must be a reference to the
+	original array/string/function. Events from the source will immediately be
+	removed from the calendar.
+
+**rerenderEvents** - .fullCalendar(``'rerenderEvents'``)
+	Rerenders all events on the screen.
+
+**refetchEvents** - .fullCalendar(``'refetchEvents'``)
+	Refetches events from all event sources and rerenders them on the screen.
 	

+ 24 - 24
docs/theming.txt

@@ -1,25 +1,25 @@
-
-Theming
-=======
-
-FullCalendar can be used with jQuery UI themes. Themes provide a more stylized
-look for the calendar and can easily be created using the
-`jQuery UI ThemeRoller <http://jqueryui.com/themeroller/>`_.
-
-In order for themes to work, you must include the theme's CSS file and
-*fullcalendar.css* on the current page. You must also enable the ``theme`` option.
-Here is the full list of theme-related options:
-
-**theme**: Boolean, *Default*: ``false``
-	Enables/disables use of jQuery UI themes
-
-**buttonIcons**: Object
-	Determines which icons appear within header buttons. If a button
-	does not have an entry, it falls back to using ``buttonText``.
-	
-	Here is the default value for ``buttonIcons``::
-	
-		{
-			prev: 'circle-triangle-w',
-			next: 'circle-triangle-e'
+
+Theming
+=======
+
+FullCalendar can be used with jQuery UI themes. Themes provide a more stylized
+look for the calendar and can easily be created using the
+`jQuery UI ThemeRoller <http://jqueryui.com/themeroller/>`_.
+
+In order for themes to work, you must include the theme's CSS file and
+*fullcalendar.css* on the current page. You must also enable the ``theme`` option.
+Here is the full list of theme-related options:
+
+**theme**: Boolean, *Default*: ``false``
+	Enables/disables use of jQuery UI themes
+
+**buttonIcons**: Object
+	Determines which icons appear within header buttons. If a button
+	does not have an entry, it falls back to using ``buttonText``.
+	
+	Here is the default value for ``buttonIcons``::
+	
+		{
+			prev: 'circle-triangle-w',
+			next: 'circle-triangle-e'
 		}

+ 165 - 165
src/css/agenda.css

@@ -1,166 +1,166 @@
-
-	
-/* header styles */
-	
-.fc .fc-agenda-head th.fc-first {
-	border-left: 0;
-	}
-	
-.fc .fc-agenda-head th,
-.fc .fc-agenda-head td {
-	border-width: 1px 0 0 1px;
-	}
-
-.fc-agenda-head tr.fc-first th {
-	border-width: 0 0 0 1px;
-	}
-	
-.fc-agenda-head tr.fc-last th,
-.fc-agenda-head tr.fc-last td {
-	border-bottom-width: 2px;
-	}
-	
-
-	
-.fc-agenda-head tr.fc-last th {
-	/*border-width: 1px 0 1px 1px;*/
-	background-image: none;
-	}
-	
-.fc-agenda-head tr.fc-last th.fc-first {
-	/*border-width: 0 2px 1px 0;*/
-	}
-	
-.fc-agenda-head tr.fc-last th.fc-last {
-	/*border-width: 0 0 0 3px;*/
-	}
-	
-.fc .fc-agenda-head td {
-	/*border-width: 3px 0 3px 1px;*/
-	background: none;
-	}
-	
-	
-	
-	
-.fc-agenda-body {
-	/*width: 100%;*/
-	overflow: auto;
-	}
-	
-	
-	
-	
-
-	
-.fc .fc-agenda-body th {
-	border-width: 1px 0 0 0;
-	background-image: none;
-	text-align: right;
-	font-weight: normal;
-	vertical-align: middle;
-	width: 48px;
-	height: 22px;
-	padding-right: 2px;
-	}
-	
-.fc .fc-agenda-body td {
-	border-width: 1px 0 0 1px;
-	background: none;
-	}
-
-.fc .fc-agenda-body tr.fc-minor th,
-.fc .fc-agenda-body tr.fc-minor td {
-	border-top-style: dotted;
-	}
-	
-.fc .fc-agenda-body tr.fc-first th,
-.fc .fc-agenda-body tr.fc-first td {
-	border-top: 0;
-	}
-	
-	
-	
-.fc .fc-agenda-bg td {
-	border-style: double;
-	border-width: 0 0 0 3px;
-	}
-	
-.fc .fc-agenda-bg td.fc-not-today {
-	background: none;
-	}
-	
-	
-	
-.fc-agenda .fc-day-content {
-	padding: 2px 1px 14px;
-	}
-	
-	
-	
-	
-/* vertical events */
-
-.fc-event-vert {
-	border-width: 0 1px;
-	}
-	
-.fc-event-vert a {
-	border-width: 0;
-	}
-	
-.fc-content .fc-corner-top {
-	margin-top: 1px;
-	}
-	
-.fc-content .fc-corner-top a {
-	margin-top: -1px;
-	border-top-width: 1px;
-	}
-	
-.fc-content .fc-corner-bottom {
-	margin-bottom: 1px;
-	}
-	
-.fc-content .fc-corner-bottom a {
-	margin-bottom: -1px;
-	border-bottom-width: 1px;
-	}
-	
-.fc-event-vert span {
-	display: block;
-	position: relative;
-	z-index: 2;
-	}
-	
-.fc-event-vert span.fc-event-time {
-	white-space: nowrap;
-	_white-space: normal;
-	overflow: hidden;
-	font-size: 10px;
-	}
-	
-.fc-event-vert span.fc-event-title {
-	line-height: 13px;
-	}
-	
-.fc-event-vert span.fc-event-bg {
-	position: absolute;
-	z-index: 1;
-	top: 0;
-	left: 0;
-	width: 100%;
-	height: 100%;
-	background: #fff;
-	opacity: .3;
-	filter: alpha(opacity=30);
-	}
-	
-.fc-event-vert .ui-resizable-s {
-	font-family: monospace;
-	height: 8px;
-	font-size: 11px;
-	line-height: 8px;
-	bottom: 0;
-	text-align: center;
+
+	
+/* header styles */
+	
+.fc .fc-agenda-head th.fc-first {
+	border-left: 0;
+	}
+	
+.fc .fc-agenda-head th,
+.fc .fc-agenda-head td {
+	border-width: 1px 0 0 1px;
+	}
+
+.fc-agenda-head tr.fc-first th {
+	border-width: 0 0 0 1px;
+	}
+	
+.fc-agenda-head tr.fc-last th,
+.fc-agenda-head tr.fc-last td {
+	border-bottom-width: 2px;
+	}
+	
+
+	
+.fc-agenda-head tr.fc-last th {
+	/*border-width: 1px 0 1px 1px;*/
+	background-image: none;
+	}
+	
+.fc-agenda-head tr.fc-last th.fc-first {
+	/*border-width: 0 2px 1px 0;*/
+	}
+	
+.fc-agenda-head tr.fc-last th.fc-last {
+	/*border-width: 0 0 0 3px;*/
+	}
+	
+.fc .fc-agenda-head td {
+	/*border-width: 3px 0 3px 1px;*/
+	background: none;
+	}
+	
+	
+	
+	
+.fc-agenda-body {
+	/*width: 100%;*/
+	overflow: auto;
+	}
+	
+	
+	
+	
+
+	
+.fc .fc-agenda-body th {
+	border-width: 1px 0 0 0;
+	background-image: none;
+	text-align: right;
+	font-weight: normal;
+	vertical-align: middle;
+	width: 48px;
+	height: 22px;
+	padding-right: 2px;
+	}
+	
+.fc .fc-agenda-body td {
+	border-width: 1px 0 0 1px;
+	background: none;
+	}
+
+.fc .fc-agenda-body tr.fc-minor th,
+.fc .fc-agenda-body tr.fc-minor td {
+	border-top-style: dotted;
+	}
+	
+.fc .fc-agenda-body tr.fc-first th,
+.fc .fc-agenda-body tr.fc-first td {
+	border-top: 0;
+	}
+	
+	
+	
+.fc .fc-agenda-bg td {
+	border-style: double;
+	border-width: 0 0 0 3px;
+	}
+	
+.fc .fc-agenda-bg td.fc-not-today {
+	background: none;
+	}
+	
+	
+	
+.fc-agenda .fc-day-content {
+	padding: 2px 1px 14px;
+	}
+	
+	
+	
+	
+/* vertical events */
+
+.fc-event-vert {
+	border-width: 0 1px;
+	}
+	
+.fc-event-vert a {
+	border-width: 0;
+	}
+	
+.fc-content .fc-corner-top {
+	margin-top: 1px;
+	}
+	
+.fc-content .fc-corner-top a {
+	margin-top: -1px;
+	border-top-width: 1px;
+	}
+	
+.fc-content .fc-corner-bottom {
+	margin-bottom: 1px;
+	}
+	
+.fc-content .fc-corner-bottom a {
+	margin-bottom: -1px;
+	border-bottom-width: 1px;
+	}
+	
+.fc-event-vert span {
+	display: block;
+	position: relative;
+	z-index: 2;
+	}
+	
+.fc-event-vert span.fc-event-time {
+	white-space: nowrap;
+	_white-space: normal;
+	overflow: hidden;
+	font-size: 10px;
+	}
+	
+.fc-event-vert span.fc-event-title {
+	line-height: 13px;
+	}
+	
+.fc-event-vert span.fc-event-bg {
+	position: absolute;
+	z-index: 1;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background: #fff;
+	opacity: .3;
+	filter: alpha(opacity=30);
+	}
+	
+.fc-event-vert .ui-resizable-s {
+	font-family: monospace;
+	height: 8px;
+	font-size: 11px;
+	line-height: 8px;
+	bottom: 0;
+	text-align: center;
 	}

+ 55 - 55
src/css/grid.css

@@ -1,56 +1,56 @@
-
-/* Month View, Basic Week View, Basic Day View
-------------------------------------------------------------------------*/
-
-.fc-grid table {
-	width: 100%;
-	}
-	
-.fc .fc-grid th {
-	border-width: 0 0 0 1px;
-	text-align: center;
-	}
-	
-.fc .fc-grid td {
-	border-width: 1px 0 0 1px;
-	}
-	
-.fc-grid th.fc-left,
-.fc-grid td.fc-left {
-	border-left: 0;
-	}
-	
-.fc-grid .fc-day-number {
-	float: right;
-	padding: 0 2px;
-	}
-	
-.fc-grid .fc-other-month .fc-day-number {
-	opacity: 0.3;
-	filter: alpha(opacity=30);
-	}
-	
-.fc-grid .fc-day-content {
-	clear: both;
-	padding: 2px 2px 0; /* distance between events and day edges */
-	}
-	
-/* event styles */
-	
-.fc-grid .fc-event-time {
-	font-weight: bold;
-	}
-	
-/* right-to-left */
-
-.fc-rtl .fc-grid {
-	direction: rtl;
-	}
-	
-.fc-rtl .fc-grid .fc-day-number {
-	float: left;
-	}
-	
-.fc-rtl .fc-grid .fc-event-time {
-	float: right;
+
+/* Month View, Basic Week View, Basic Day View
+------------------------------------------------------------------------*/
+
+.fc-grid table {
+	width: 100%;
+	}
+	
+.fc .fc-grid th {
+	border-width: 0 0 0 1px;
+	text-align: center;
+	}
+	
+.fc .fc-grid td {
+	border-width: 1px 0 0 1px;
+	}
+	
+.fc-grid th.fc-left,
+.fc-grid td.fc-left {
+	border-left: 0;
+	}
+	
+.fc-grid .fc-day-number {
+	float: right;
+	padding: 0 2px;
+	}
+	
+.fc-grid .fc-other-month .fc-day-number {
+	opacity: 0.3;
+	filter: alpha(opacity=30);
+	}
+	
+.fc-grid .fc-day-content {
+	clear: both;
+	padding: 2px 2px 0; /* distance between events and day edges */
+	}
+	
+/* event styles */
+	
+.fc-grid .fc-event-time {
+	font-weight: bold;
+	}
+	
+/* right-to-left */
+
+.fc-rtl .fc-grid {
+	direction: rtl;
+	}
+	
+.fc-rtl .fc-grid .fc-day-number {
+	float: left;
+	}
+	
+.fc-rtl .fc-grid .fc-event-time {
+	float: right;
 	}

+ 299 - 297
src/css/main.css

@@ -1,298 +1,300 @@
-
-.fc,
-.fc .fc-header,
-.fc .fc-content {
-	font-size: 1em;
-	}
-	
-.fc table {
-	border-collapse: collapse;
-	border-spacing: 0;
-	}
-	
-.fc td, .fc th {
-	padding: 0;
-	vertical-align: top;
-	}
-
-
-
-/* Header
-------------------------------------------------------------------------*/
-	
-table.fc-header {
-	width: 100%;
-	}
-	
-.fc-header-left {
-	width: 25%;
-	}
-	
-.fc-header-left table {
-	float: left;
-	}
-	
-.fc-header-center {
-	width: 50%;
-	}
-	
-.fc-header-center table {
-	margin: 0 auto;
-	}
-	
-.fc-header-right {
-	width: 25%;
-	}
-	
-.fc-header-right table {
-	float: right;
-	}
-	
-.fc-header-title {
-	margin-top: 0;
-	white-space: nowrap;
-	}
-	
-.fc-header-space {
-	padding-left: 10px;
-	}
-	
-/* right-to-left */
-
-.fc-rtl .fc-header-title {
-	direction: rtl;
-	}
-	
-/* button rounded corners  */
-	
-.fc-header .fc-state-default {
-	border-width: 1px 0;
-	padding: 0 1px;
-	}
-	
-.fc-header .fc-state-default a {
-	display: block;
-	position: relative;
-	margin: 0 -1px;
-	border-width: 0 1px;
-	width: 100%;
-	}
-	
-.fc-header .fc-state-default span {
-	display: block;
-	}
-	
-.fc-header .fc-corner-left {
-	margin-left: 1px;
-	padding-left: 0;
-	}
-	
-.fc-header .fc-corner-right {
-	margin-right: 1px;
-	padding-right: 0;
-	}
-	
-.fc-header .fc-no-left {
-	padding-left: 0;
-	}
-	
-.fc-header .ui-no-left {
-	border-left: 0;
-	}
-	
-/* default button state */
-	
-.fc-header .fc-state-default,
-.fc-header .ui-state-default {
-	margin-bottom: 10px;
-	cursor: pointer;
-	}
-	
-.fc-header .fc-state-default,
-.fc-header .fc-state-default a {
-	border-style: solid;
-	border-color: #6E6E6E;
-	color: #333;
-	}
-
-.fc-header .fc-state-default span {
-	border-width: 1px 0 0 1px;
-	border-style: solid;
-	border-color: #fff;
-	background: #F0F0F0;
-	}
-	
-.fc-header .fc-state-default span,
-.fc-header .ui-state-default {
-	padding: 4px 6px;
-	}
-	
-/* active button state */
-	
-.fc-header .fc-state-active a {
-	color: #fff;
-	}
-	
-.fc-header .fc-state-active span {
-	background: #787878;
-	border-color: #777;
-	}
-	
-/* down button state */
-
-.fc-header .fc-state-down span {
-	background: #787878;
-	border-color: #777;
-	}
-	
-/* disabled button state */
-	
-.fc-header .fc-state-disabled,
-.fc-header .fc-state-disabled a {
-	border-color: #ccc;
-	}
-	
-.fc-header .fc-state-disabled a {
-	color: #999;
-	}
-	
-.fc-header .fc-state-disabled span {
-	border-color: #fff;
-	background: #F0F0F0;
-	}
-	
-	
-	
-/* Content Area & Global Cell Styles
-------------------------------------------------------------------------*/
-	
-.fc-widget-content {
-	border: 1px solid #ccc; /* outer border color */
-	}
-	
-.fc-content {
-	clear: both;
-	}
-	
-.fc-content .fc-state-default {
-	border-style: solid;
-	border-color: #ccc; /* inner border color */
-	}
-	
-.fc-content .fc-state-highlight { /* today */
-	background: #FFFFCC;
-	}
-	
-.fc-content td.fc-not-today {
-	background: none;
-	}
-	
-.fc-cell-overlay { /* semi-transparent rectangle while dragging */
-	background: #ADDBFF;
-	opacity: .2;
-	filter: alpha(opacity=20); /* for IE */
-	}
-	
-.fc-view { /* prevents dragging outside of widget */
-	width: 100%;
-	overflow: hidden;
-	}
-	
-	
-	
-/* Global Event Styles
-------------------------------------------------------------------------*/
-
-.fc-event,
-.fc-event a,
-.fc-agenda .fc-event-time {
-	color: #fff;
-	border-style: solid;
-	border-color: blue;
-	background-color: blue;
-	}
-	
-.fc-event a {
-	overflow: hidden;
-	font-size: 11px;
-	text-decoration: none;
-	text-align: left;
-	cursor: pointer;
-	}
-	
-.fc-event-time,
-.fc-event-title {
-	padding: 0 1px;
-	}
-
-.fc-event a { /* prep for rounded corners */
-	display: block;
-	position: relative;
-	width: 100%;
-	height: 100%;
-	}
-	
-/* resizable */
-	
-.fc .ui-resizable-handle {
-	display: block;
-	position: absolute;
-	z-index: 99999;
-	}
-	
-	
-	
-/* Horizontal Events
-------------------------------------------------------------------------*/
-
-.fc-event-hori {
-	border-width: 1px 0;
-	margin-bottom: 1px;
-	}
-	
-.fc-event-hori a {
-	border-width: 0;
-	}
-	
-.fc-content .fc-corner-left {
-	margin-left: 1px;
-	}
-	
-.fc-content .fc-corner-left a {
-	margin-left: -1px;
-	border-left-width: 1px;
-	}
-	
-.fc-content .fc-corner-right {
-	margin-right: 1px;
-	}
-	
-.fc-content .fc-corner-right a {
-	margin-right: -1px;
-	border-right-width: 1px;
-	}
-	
-/* resizable */
-	
-.fc-event-hori .ui-resizable-e {
-	top: 0;
-	right: -5px;
-	width: 7px;
-	height: 100%;
-	cursor: e-resize;
-	}
-	
-.fc-event-hori .ui-resizable-w {
-	top: 0;
-	left: -5px;
-	width: 7px;
-	height: 100%;
-	cursor: w-resize;
-	}
-	
-.fc-event-hori .ui-resizable-handle {
-	_height: 14px; /* IE6 had 0 height */
-	}
-	
-
+
+.fc,
+.fc .fc-header,
+.fc .fc-content {
+	font-size: 1em;
+	}
+	
+.fc table {
+	border-collapse: collapse;
+	border-spacing: 0;
+	}
+	
+.fc td, .fc th {
+	padding: 0;
+	vertical-align: top;
+	}
+
+
+
+/* Header
+------------------------------------------------------------------------*/
+	
+table.fc-header {
+	width: 100%;
+	}
+	
+.fc-header-left {
+	width: 25%;
+	}
+	
+.fc-header-left table {
+	float: left;
+	}
+	
+.fc-header-center {
+	width: 50%;
+	}
+	
+.fc-header-center table {
+	margin: 0 auto;
+	}
+	
+.fc-header-right {
+	width: 25%;
+	}
+	
+.fc-header-right table {
+	float: right;
+	}
+	
+.fc-header-title {
+	margin-top: 0;
+	white-space: nowrap;
+	}
+	
+.fc-header-space {
+	padding-left: 10px;
+	}
+	
+/* right-to-left */
+
+.fc-rtl .fc-header-title {
+	direction: rtl;
+	}
+	
+/* button rounded corners  */
+	
+.fc-header .fc-state-default {
+	border-width: 1px 0;
+	padding: 0 1px;
+	}
+	
+.fc-header .fc-state-default a {
+	display: block;
+	position: relative;
+	margin: 0 -1px;
+	border-width: 0 1px;
+	width: 100%;
+	}
+	
+.fc-header .fc-state-default span {
+	display: block;
+	}
+	
+.fc-header .fc-corner-left {
+	margin-left: 1px;
+	padding-left: 0;
+	}
+	
+.fc-header .fc-corner-right {
+	margin-right: 1px;
+	padding-right: 0;
+	}
+	
+.fc-header .fc-no-left {
+	padding-left: 0;
+	}
+	
+.fc-header .ui-no-left {
+	border-left: 0;
+	}
+	
+/* default button state */
+	
+.fc-header .fc-state-default,
+.fc-header .ui-state-default {
+	margin-bottom: 10px;
+	cursor: pointer;
+	}
+	
+.fc-header .fc-state-default,
+.fc-header .fc-state-default a {
+	border-style: solid;
+	border-color: #6E6E6E;
+	color: #333;
+	}
+
+.fc-header .fc-state-default span {
+	border-width: 1px 0 0 1px;
+	border-style: solid;
+	border-color: #fff;
+	background: #F0F0F0;
+	}
+	
+.fc-header .fc-state-default span,
+.fc-header .ui-state-default {
+	padding: 4px 6px;
+	}
+	
+/* active button state */
+	
+.fc-header .fc-state-active a {
+	color: #fff;
+	}
+	
+.fc-header .fc-state-active span {
+	background: #787878;
+	border-color: #777;
+	}
+	
+/* down button state */
+
+.fc-header .fc-state-down span {
+	background: #787878;
+	border-color: #777;
+	}
+	
+/* disabled button state */
+	
+.fc-header .fc-state-disabled,
+.fc-header .fc-state-disabled a {
+	border-color: #ccc;
+	}
+	
+.fc-header .fc-state-disabled a {
+	color: #999;
+	}
+	
+.fc-header .fc-state-disabled span {
+	border-color: #fff;
+	background: #F0F0F0;
+	}
+	
+	
+	
+/* Content Area & Global Cell Styles
+------------------------------------------------------------------------*/
+	
+.fc-widget-content {
+	border: 1px solid #ccc; /* outer border color */
+	}
+	
+.fc-content {
+	clear: both;
+	}
+	
+.fc-content .fc-state-default {
+	border-style: solid;
+	border-color: #ccc; /* inner border color */
+	}
+	
+.fc-content .fc-state-highlight { /* today */
+	background: #FFFFCC;
+	}
+	
+.fc-content td.fc-not-today {
+	background: none;
+	}
+	
+.fc-cell-overlay { /* semi-transparent rectangle while dragging */
+	background: #ADDBFF;
+	opacity: .2;
+	filter: alpha(opacity=20); /* for IE */
+	}
+	
+.fc-view { /* prevents dragging outside of widget */
+	width: 100%;
+	overflow: hidden;
+	}
+	
+	
+	
+/* Global Event Styles
+------------------------------------------------------------------------*/
+
+.fc-event,
+.fc-event a,
+.fc-agenda .fc-event-time {
+	color: #fff;
+	border-style: solid;
+	border-color: blue;
+	background-color: blue;
+	}
+	
+.fc-event a {
+	overflow: hidden;
+	font-size: 11px;
+	text-decoration: none;
+	text-align: left;
+	cursor: pointer;
+	}
+	
+.fc-event-time,
+.fc-event-title {
+	padding: 0 1px;
+	}
+
+.fc-event a { /* prep for rounded corners */
+	display: block;
+	position: relative;
+	width: 100%;
+	height: 100%;
+	}
+	
+/* resizable */
+	
+.fc .ui-resizable-handle {
+	display: block;
+	position: absolute;
+	z-index: 99999;
+	}
+	
+	
+	
+/* Horizontal Events
+------------------------------------------------------------------------*/
+
+.fc-event-hori {
+	border-width: 1px 0;
+	margin-bottom: 1px;
+	}
+	
+.fc-event-hori a {
+	border-width: 0;
+	}
+	
+.fc-content .fc-corner-left {
+	margin-left: 1px;
+	}
+	
+.fc-content .fc-corner-left a {
+	margin-left: -1px;
+	border-left-width: 1px;
+	}
+	
+.fc-content .fc-corner-right {
+	margin-right: 1px;
+	}
+	
+.fc-content .fc-corner-right a {
+	margin-right: -1px;
+	border-right-width: 1px;
+	}
+	
+/* resizable */
+
+.fc-event-hori .ui-resizable-handle {
+	_height: 14px !important; /* IE6 had 0 height */
+	}
+	
+.fc-event-hori .ui-resizable-e {
+	top: 0           !important;
+	right: -5px      !important;
+	width: 7px       !important;
+	height: 100%     !important;
+	border: 0        !important;
+	background: none !important;
+	cursor: e-resize;
+	}
+	
+.fc-event-hori .ui-resizable-w {
+	top: 0           !important;
+	left: -5px       !important;
+	width: 7px       !important;
+	height: 100%     !important;
+	border: 0        !important;
+	background: none !important;
+	cursor: w-resize;
+	}
 	

+ 9 - 4
src/grid.js

@@ -62,6 +62,7 @@ views.basicDay = function(element, options) {
 
 
 // flags for [Opera] rendering bugs
+
 var tdTopBug, trTopBug, tbodyTopBug, sniffBugs = true;
 
 var tdHeightBug;
@@ -100,7 +101,8 @@ function Grid(element, options, methods) {
 	
 	
 	
-	/********************************* grid rendering *************************************/
+	/* Grid Rendering
+	-----------------------------------------------------------------------------*/
 	
 	
 	element.addClass('fc-grid').css('position', 'relative');
@@ -289,7 +291,8 @@ function Grid(element, options, methods) {
 	
 	
 	
-	/******************************** event rendering *****************************/
+	/* Event Rendering
+	-----------------------------------------------------------------------------*/
 	
 	
 	function renderEvents(events) {
@@ -451,7 +454,8 @@ function Grid(element, options, methods) {
 	
 	
 	
-	/***************************** draggable *********************************/
+	/* Draggable
+	-----------------------------------------------------------------------------*/
 	
 	
 	function draggableEvent(event, eventElement) {
@@ -507,7 +511,8 @@ function Grid(element, options, methods) {
 	
 	
 	
-	/******************************* resizable *****************************/
+	/* Resizable
+	-----------------------------------------------------------------------------*/
 	
 	
 	function resizableEvent(event, eventElement) {

+ 6 - 10
src/main.js

@@ -413,15 +413,11 @@ $.fn.fullCalendar = function(options) {
 							return e._id == id;
 						};
 					}
-					events = filterArray(events, function(e) {
-						return !filter(e);
-					});
+					events = $.grep(events, filter, true);
 					// remove events from array sources
 					for (var i=0; i<eventSources.length; i++) {
 						if (typeof eventSources[i] == 'object') {
-							eventSources[i] = filterArray(eventSources[i], function(e) {
-								return !filter(e);
-							});
+							eventSources[i] = $.grep(eventSources[i], filter, true);
 						}
 					}
 				}
@@ -430,11 +426,11 @@ $.fn.fullCalendar = function(options) {
 			
 			clientEvents: function(filter) {
 				if ($.isFunction(filter)) {
-					return filterArray(events, filter);
+					return $.grep(events, filter);
 				}
 				else if (filter) { // an event ID
 					filter += '';
-					return filterArray(events, function(e) {
+					return $.grep(events, function(e) {
 						return e._id == filter;
 					});
 				}
@@ -459,11 +455,11 @@ $.fn.fullCalendar = function(options) {
 			},
 		
 			removeEventSource: function(source) {
-				eventSources = filterArray(eventSources, function(src) {
+				eventSources = $.grep(eventSources, function(src) {
 					return src != source;
 				});
 				// remove all client events from that source
-				events = filterArray(events, function(e) {
+				events = $.grep(events, function(e) {
 					return e.source != source;
 				});
 				eventsChanged();

+ 16 - 16
src/misc/head.txt

@@ -1,17 +1,17 @@
-/*!
- * FullCalendar
- * http://arshaw.com/fullcalendar/
- *
- * use fullcalendar.css for basic styling
- * requires jQuery UI core and draggables ONLY if you plan to do drag & drop
- *
- * Copyright (c) 2009 Adam Shaw
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- *
- * Date:
- * Revision:
- */
- 
+/*!
+ * FullCalendar
+ * http://arshaw.com/fullcalendar/
+ *
+ * use fullcalendar.css for basic styling
+ * requires jQuery UI core and draggables ONLY if you plan to do drag & drop
+ *
+ * Copyright (c) 2009 Adam Shaw
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ * Date:
+ * Revision:
+ */
+ 
 (function($) {

+ 0 - 11
src/util.js

@@ -319,14 +319,3 @@ function zeroPad(n) {
 function strProp(s, prop) {
 	return typeof s == 'string' ? s : s[prop];
 }
-
-function filterArray(a, test) {
-	var res = [],
-		i, len = a.length;
-	for (i=0; i<len; i++) {
-		if (test(a[i])) {
-			res.push(a[i]);
-		}
-	}
-	return res;
-}

+ 114 - 114
tests/gcal.html

@@ -1,115 +1,115 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<script type='text/javascript' src='loader.js'></script>
-<script type='text/javascript'>
-
-	var d = new Date();
-	var y = d.getFullYear();
-	var m = d.getMonth();
-
-	$(document).ready(function() {
-		$('#calendar').fullCalendar({
-			editable: true,
-			eventSources: [
-				$.fullCalendar.gcalFeed(
-					"http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic",
-					{
-						//editable: true,
-						className: 'holiday'
-					}
-				),
-				/*$.fullCalendar.gcalFeed(
-					"http://www.google.com/calendar/feeds/mike%40maddogsportsbar.com/private-4ad75f9427058f8fe6525c0857c59fbc/basic",
-					{
-						className: 'maddog'
-					}
-				),*/
-				[
-					{
-						id: 1,
-						title: "Long Event",
-						start: new Date(y, m, 6),
-						end: new Date(y, m, 10)
-					},
-					{
-						id: 2,
-						title: "Repeating",
-						start: new Date(y, m, 2)
-					},
-					{
-						id: 2,
-						title: "Repeating",
-						start: new Date(y, m, 9)
-					},
-					{
-						id: 3,
-						title: "Meeting",
-						start: new Date(y, m, 20, 9, 0),
-						end: new Date(y, m, 20, 10, 0),
-						allDay: false
-					},
-					{
-						id: 4,
-						title: "Click for Facebook",
-						start: new Date(y, m, 27),
-						end: new Date(y, m, 28),
-						url: "http://facebook.com/"
-					},
-					{
-						id: 5,
-						title: "timed event1",
-						start: new Date (y, m, 31, 17, 30),
-						allDay: false
-					},
-					{
-						id: 6,
-						title: "timed event1",
-						start: new Date (y, m+1, 2, 14, 15),
-						allDay: false
-					},
-					{
-						id: 7,
-						title: "timed event1",
-						start: new Date (y, m+1, 4, 15, 00),
-						end: new Date(y, m+1, 4, 17, 00),
-						allDay: false
-					}
-				]
-			]
-		});
-	});
-
-</script>
-<style>
-
-	.holiday,
-	.holiday a {
-		background: green;
-		border-color: green;
-		}
-		
-	.maddog,
-	.maddog a {
-		background: red;
-		border-color: red;
-		}
-		
-		
-
-	/* rescued from fullcalendar.css (not used here) */
-	
-	.fc-event-nobg,
-	.fc-event-nobg a,
-	.fc-agenda .fc-event-nobg .fc-event-time {
-		border-style: none;
-		background: none;
-		color: inherit;
-		}
-
-</style>
-</head>
-<body style='font-size:12px'>
-<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
-</body>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<script type='text/javascript' src='loader.js'></script>
+<script type='text/javascript'>
+
+	var d = new Date();
+	var y = d.getFullYear();
+	var m = d.getMonth();
+
+	$(document).ready(function() {
+		$('#calendar').fullCalendar({
+			editable: true,
+			eventSources: [
+				$.fullCalendar.gcalFeed(
+					"http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic",
+					{
+						//editable: true,
+						className: 'holiday'
+					}
+				),
+				/*$.fullCalendar.gcalFeed(
+					"http://www.google.com/calendar/feeds/mike%40maddogsportsbar.com/private-4ad75f9427058f8fe6525c0857c59fbc/basic",
+					{
+						className: 'maddog'
+					}
+				),*/
+				[
+					{
+						id: 1,
+						title: "Long Event",
+						start: new Date(y, m, 6),
+						end: new Date(y, m, 10)
+					},
+					{
+						id: 2,
+						title: "Repeating",
+						start: new Date(y, m, 2)
+					},
+					{
+						id: 2,
+						title: "Repeating",
+						start: new Date(y, m, 9)
+					},
+					{
+						id: 3,
+						title: "Meeting",
+						start: new Date(y, m, 20, 9, 0),
+						end: new Date(y, m, 20, 10, 0),
+						allDay: false
+					},
+					{
+						id: 4,
+						title: "Click for Facebook",
+						start: new Date(y, m, 27),
+						end: new Date(y, m, 28),
+						url: "http://facebook.com/"
+					},
+					{
+						id: 5,
+						title: "timed event1",
+						start: new Date (y, m, 31, 17, 30),
+						allDay: false
+					},
+					{
+						id: 6,
+						title: "timed event1",
+						start: new Date (y, m+1, 2, 14, 15),
+						allDay: false
+					},
+					{
+						id: 7,
+						title: "timed event1",
+						start: new Date (y, m+1, 4, 15, 00),
+						end: new Date(y, m+1, 4, 17, 00),
+						allDay: false
+					}
+				]
+			]
+		});
+	});
+
+</script>
+<style>
+
+	.holiday,
+	.holiday a {
+		background: green;
+		border-color: green;
+		}
+		
+	.maddog,
+	.maddog a {
+		background: red;
+		border-color: red;
+		}
+		
+		
+
+	/* rescued from fullcalendar.css (not used here) */
+	
+	.fc-event-nobg,
+	.fc-event-nobg a,
+	.fc-agenda .fc-event-nobg .fc-event-time {
+		border-style: none;
+		background: none;
+		color: inherit;
+		}
+
+</style>
+</head>
+<body style='font-size:12px'>
+<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
+</body>
 </html>

+ 819 - 0
tests/jquery-legacy/ui.resizable.js

@@ -0,0 +1,819 @@
+/*
+ * jQuery UI Resizable 1.6
+ *
+ * Copyright (c) 2008 AUTHORS.txt (http://ui.jquery.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ *	ui.core.js
+ */
+(function($) {
+
+$.widget("ui.resizable", $.extend({}, $.ui.mouse, {
+
+	_init: function() {
+
+		var self = this, o = this.options;
+
+		var elpos = this.element.css('position');
+
+		this.originalElement = this.element;
+
+		// simulate .ui-resizable { position: relative; }
+		this.element.addClass("ui-resizable").css({ position: /static/.test(elpos) ? 'relative' : elpos });
+
+		$.extend(o, {
+			_aspectRatio: !!(o.aspectRatio),
+			helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null,
+			knobHandles: o.knobHandles === true ? 'ui-resizable-knob-handle' : o.knobHandles
+		});
+
+		//Default Theme
+		var aBorder = '1px solid #DEDEDE';
+
+		o.defaultTheme = {
+			'ui-resizable': { display: 'block' },
+			'ui-resizable-handle': { position: 'absolute', background: '#F2F2F2', fontSize: '0.1px' },
+			'ui-resizable-n': { cursor: 'n-resize', height: '4px', left: '0px', right: '0px', borderTop: aBorder },
+			'ui-resizable-s': { cursor: 's-resize', height: '4px', left: '0px', right: '0px', borderBottom: aBorder },
+			'ui-resizable-e': { cursor: 'e-resize', width: '4px', top: '0px', bottom: '0px', borderRight: aBorder },
+			'ui-resizable-w': { cursor: 'w-resize', width: '4px', top: '0px', bottom: '0px', borderLeft: aBorder },
+			'ui-resizable-se': { cursor: 'se-resize', width: '4px', height: '4px', borderRight: aBorder, borderBottom: aBorder },
+			'ui-resizable-sw': { cursor: 'sw-resize', width: '4px', height: '4px', borderBottom: aBorder, borderLeft: aBorder },
+			'ui-resizable-ne': { cursor: 'ne-resize', width: '4px', height: '4px', borderRight: aBorder, borderTop: aBorder },
+			'ui-resizable-nw': { cursor: 'nw-resize', width: '4px', height: '4px', borderLeft: aBorder, borderTop: aBorder }
+		};
+
+		o.knobTheme = {
+			'ui-resizable-handle': { background: '#F2F2F2', border: '1px solid #808080', height: '8px', width: '8px' },
+			'ui-resizable-n': { cursor: 'n-resize', top: '0px', left: '45%' },
+			'ui-resizable-s': { cursor: 's-resize', bottom: '0px', left: '45%' },
+			'ui-resizable-e': { cursor: 'e-resize', right: '0px', top: '45%' },
+			'ui-resizable-w': { cursor: 'w-resize', left: '0px', top: '45%' },
+			'ui-resizable-se': { cursor: 'se-resize', right: '0px', bottom: '0px' },
+			'ui-resizable-sw': { cursor: 'sw-resize', left: '0px', bottom: '0px' },
+			'ui-resizable-nw': { cursor: 'nw-resize', left: '0px', top: '0px' },
+			'ui-resizable-ne': { cursor: 'ne-resize', right: '0px', top: '0px' }
+		};
+
+		o._nodeName = this.element[0].nodeName;
+
+		//Wrap the element if it cannot hold child nodes
+		if(o._nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+			var el = this.element;
+
+			//Opera fixing relative position
+			if (/relative/.test(el.css('position')) && $.browser.opera)
+				el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+			//Create a wrapper element and set the wrapper to the new current internal element
+			el.wrap(
+				$('<div class="ui-wrapper"	style="overflow: hidden;"></div>').css( {
+					position: el.css('position'),
+					width: el.outerWidth(),
+					height: el.outerHeight(),
+					top: el.css('top'),
+					left: el.css('left')
+				})
+			);
+
+			var oel = this.element; this.element = this.element.parent();
+
+			// store instance on wrapper
+			this.element.data('resizable', this);
+
+			//Move margins to the wrapper
+			this.element.css({ marginLeft: oel.css("marginLeft"), marginTop: oel.css("marginTop"),
+				marginRight: oel.css("marginRight"), marginBottom: oel.css("marginBottom")
+			});
+
+			oel.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+			//Prevent Safari textarea resize
+			if ($.browser.safari && o.preventDefault) oel.css('resize', 'none');
+
+			o.proportionallyResize = oel.css({ position: 'static', zoom: 1, display: 'block' });
+
+			// avoid IE jump
+			this.element.css({ margin: oel.css('margin') });
+
+			// fix handlers offset
+			this._proportionallyResize();
+		}
+
+		if(!o.handles) o.handles = !$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' };
+		if(o.handles.constructor == String) {
+
+			o.zIndex = o.zIndex || 1000;
+
+			if(o.handles == 'all') o.handles = 'n,e,s,w,se,sw,ne,nw';
+
+			var n = o.handles.split(","); o.handles = {};
+
+			// insertions are applied when don't have theme loaded
+			var insertionsDefault = {
+				handle: 'position: absolute; display: none; overflow:hidden;',
+				n: 'top: 0pt; width:100%;',
+				e: 'right: 0pt; height:100%;',
+				s: 'bottom: 0pt; width:100%;',
+				w: 'left: 0pt; height:100%;',
+				se: 'bottom: 0pt; right: 0px;',
+				sw: 'bottom: 0pt; left: 0px;',
+				ne: 'top: 0pt; right: 0px;',
+				nw: 'top: 0pt; left: 0px;'
+			};
+
+			for(var i = 0; i < n.length; i++) {
+				var handle = $.trim(n[i]), dt = o.defaultTheme, hname = 'ui-resizable-'+handle, loadDefault = !$.ui.css(hname) && !o.knobHandles, userKnobClass = $.ui.css('ui-resizable-knob-handle'),
+							allDefTheme = $.extend(dt[hname], dt['ui-resizable-handle']), allKnobTheme = $.extend(o.knobTheme[hname], !userKnobClass ? o.knobTheme['ui-resizable-handle'] : {});
+
+				// increase zIndex of sw, se, ne, nw axis
+				var applyZIndex = /sw|se|ne|nw/.test(handle) ? { zIndex: ++o.zIndex } : {};
+
+				var defCss = (loadDefault ? insertionsDefault[handle] : ''),
+					axis = $(['<div class="ui-resizable-handle ', hname, '" style="', defCss, insertionsDefault.handle, '"></div>'].join('')).css( applyZIndex );
+				o.handles[handle] = '.ui-resizable-'+handle;
+
+				this.element.append(
+					//Theme detection, if not loaded, load o.defaultTheme
+					axis.css( loadDefault ? allDefTheme : {} )
+						// Load the knobHandle css, fix width, height, top, left...
+						.css( o.knobHandles ? allKnobTheme : {} ).addClass(o.knobHandles ? 'ui-resizable-knob-handle' : '').addClass(o.knobHandles)
+				);
+			}
+
+			if (o.knobHandles) this.element.addClass('ui-resizable-knob').css( !$.ui.css('ui-resizable-knob') ? { /*border: '1px #fff dashed'*/ } : {} );
+		}
+
+		this._renderAxis = function(target) {
+			target = target || this.element;
+
+			for(var i in o.handles) {
+				if(o.handles[i].constructor == String)
+					o.handles[i] = $(o.handles[i], this.element).show();
+
+				if (o.transparent)
+					o.handles[i].css({opacity:0});
+
+				//Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+				if (this.element.is('.ui-wrapper') &&
+					o._nodeName.match(/textarea|input|select|button/i)) {
+
+					var axis = $(o.handles[i], this.element), padWrapper = 0;
+
+					//Checking the correct pad and border
+					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+					//The padding type i have to apply...
+					var padPos = [ 'padding',
+						/ne|nw|n/.test(i) ? 'Top' :
+						/se|sw|s/.test(i) ? 'Bottom' :
+						/^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+					if (!o.transparent)
+						target.css(padPos, padWrapper);
+
+					this._proportionallyResize();
+				}
+				if(!$(o.handles[i]).length) continue;
+			}
+		};
+
+		this._renderAxis(this.element);
+		o._handles = $('.ui-resizable-handle', self.element);
+
+		if (o.disableSelection)
+			o._handles.disableSelection();
+
+		//Matching axis name
+		o._handles.mouseover(function() {
+			if (!o.resizing) {
+				if (this.className)
+					var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+				//Axis, default = se
+				self.axis = o.axis = axis && axis[1] ? axis[1] : 'se';
+			}
+		});
+
+		//If we want to auto hide the elements
+		if (o.autoHide) {
+			o._handles.hide();
+			$(self.element).addClass("ui-resizable-autohide").hover(function() {
+				$(this).removeClass("ui-resizable-autohide");
+				o._handles.show();
+			},
+			function(){
+				if (!o.resizing) {
+					$(this).addClass("ui-resizable-autohide");
+					o._handles.hide();
+				}
+			});
+		}
+
+		this._mouseInit();
+	},
+
+	destroy: function() {
+		var el = this.element, wrapped = el.children(".ui-resizable").get(0);
+
+		this._mouseDestroy();
+
+		var _destroy = function(exp) {
+			$(exp).removeClass("ui-resizable ui-resizable-disabled")
+				.removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+		};
+
+		_destroy(el);
+
+		if (el.is('.ui-wrapper') && wrapped) {
+			el.parent().append(
+				$(wrapped).css({
+					position: el.css('position'),
+					width: el.outerWidth(),
+					height: el.outerHeight(),
+					top: el.css('top'),
+					left: el.css('left')
+				})
+			).end().remove();
+
+			_destroy(wrapped);
+		}
+	},
+
+	_mouseCapture: function(event) {
+
+		if(this.options.disabled) return false;
+
+		var handle = false;
+		for(var i in this.options.handles) {
+			if($(this.options.handles[i])[0] == event.target) handle = true;
+		}
+		if (!handle) return false;
+
+		return true;
+
+	},
+
+	_mouseStart: function(event) {
+
+		var o = this.options, iniPos = this.element.position(), el = this.element,
+			ie6 = $.browser.msie && $.browser.version < 7;
+		o.resizing = true;
+		o.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+		// bugfix #1749
+		if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+
+			// sOffset decides if document scrollOffset will be added to the top/left of the resizable element
+			var sOffset = $.browser.msie && !o.containment && (/absolute/).test(el.css('position')) && !(/relative/).test(el.parent().css('position'));
+			var dscrollt = sOffset ? this.documentScroll.top : 0, dscrolll = sOffset ? this.documentScroll.left : 0;
+
+			el.css({ position: 'absolute', top: (iniPos.top + dscrollt), left: (iniPos.left + dscrolll) });
+		}
+
+		//Opera fixing relative position
+		if ($.browser.opera && (/relative/).test(el.css('position')))
+			el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+		this._renderProxy();
+
+		var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+		if (o.containment) {
+			curleft += $(o.containment).scrollLeft()||0;
+			curtop += $(o.containment).scrollTop()||0;
+		}
+
+		//Store needed variables
+		this.offset = this.helper.offset();
+		this.position = { left: curleft, top: curtop };
+		this.size = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+		this.originalSize = o.helper || ie6 ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+		this.originalPosition = { left: curleft, top: curtop };
+		this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+		this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+		//Aspect Ratio
+		o.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height)||1);
+
+		if (o.preserveCursor) {
+		    var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+		    $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+		}
+
+		this._propagate("start", event);
+		return true;
+	},
+
+	_mouseDrag: function(event) {
+
+		//Increase performance, avoid regex
+		var el = this.helper, o = this.options, props = {},
+			self = this, smp = this.originalMousePosition, a = this.axis;
+
+		var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+		var trigger = this._change[a];
+		if (!trigger) return false;
+
+		// Calculate the attrs that will be change
+		var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+		if (o._aspectRatio || event.shiftKey)
+			data = this._updateRatio(data, event);
+
+		data = this._respectSize(data, event);
+
+		// plugins callbacks need to be called first
+		this._propagate("resize", event);
+
+		el.css({
+			top: this.position.top + "px", left: this.position.left + "px",
+			width: this.size.width + "px", height: this.size.height + "px"
+		});
+
+		if (!o.helper && o.proportionallyResize)
+			this._proportionallyResize();
+
+		this._updateCache(data);
+
+		// calling the user callback at the end
+		this.element.triggerHandler("resize", [event, this.ui()], this.options["resize"]);
+
+		return false;
+	},
+
+	_mouseStop: function(event) {
+
+		this.options.resizing = false;
+		var o = this.options, self = this;
+
+		if(o.helper) {
+			var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName),
+						soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+							soffsetw = ista ? 0 : self.sizeDiff.width;
+
+			var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+				left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+				top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+			if (!o.animate)
+				this.element.css($.extend(s, { top: top, left: left }));
+
+			if (o.helper && !o.animate) this._proportionallyResize();
+		}
+
+		if (o.preserveCursor)
+			$('body').css('cursor', 'auto');
+
+		this._propagate("stop", event);
+
+		if (o.helper) this.helper.remove();
+
+		return false;
+	},
+
+	_updateCache: function(data) {
+		var o = this.options;
+		this.offset = this.helper.offset();
+		if (data.left) this.position.left = data.left;
+		if (data.top) this.position.top = data.top;
+		if (data.height) this.size.height = data.height;
+		if (data.width) this.size.width = data.width;
+	},
+
+	_updateRatio: function(data, event) {
+
+		var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+		if (data.height) data.width = (csize.height * o.aspectRatio);
+		else if (data.width) data.height = (csize.width / o.aspectRatio);
+
+		if (a == 'sw') {
+			data.left = cpos.left + (csize.width - data.width);
+			data.top = null;
+		}
+		if (a == 'nw') {
+			data.top = cpos.top + (csize.height - data.height);
+			data.left = cpos.left + (csize.width - data.width);
+		}
+
+		return data;
+	},
+
+	_respectSize: function(data, event) {
+
+		var el = this.helper, o = this.options, pRatio = o._aspectRatio || event.shiftKey, a = this.axis,
+				ismaxw = data.width && o.maxWidth && o.maxWidth < data.width, ismaxh = data.height && o.maxHeight && o.maxHeight < data.height,
+					isminw = data.width && o.minWidth && o.minWidth > data.width, isminh = data.height && o.minHeight && o.minHeight > data.height;
+
+		if (isminw) data.width = o.minWidth;
+		if (isminh) data.height = o.minHeight;
+		if (ismaxw) data.width = o.maxWidth;
+		if (ismaxh) data.height = o.maxHeight;
+
+		var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+		var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+		if (isminw && cw) data.left = dw - o.minWidth;
+		if (ismaxw && cw) data.left = dw - o.maxWidth;
+		if (isminh && ch)	data.top = dh - o.minHeight;
+		if (ismaxh && ch)	data.top = dh - o.maxHeight;
+
+		// fixing jump error on top/left - bug #2330
+		var isNotwh = !data.width && !data.height;
+		if (isNotwh && !data.left && data.top) data.top = null;
+		else if (isNotwh && !data.top && data.left) data.left = null;
+
+		return data;
+	},
+
+	_proportionallyResize: function() {
+		var o = this.options;
+		if (!o.proportionallyResize) return;
+		var prel = o.proportionallyResize, el = this.helper || this.element;
+
+		if (!o.borderDif) {
+			var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+				p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+			o.borderDif = $.map(b, function(v, i) {
+				var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+				return border + padding;
+			});
+		}
+		prel.css({
+			height: (el.height() - o.borderDif[0] - o.borderDif[2]) + "px",
+			width: (el.width() - o.borderDif[1] - o.borderDif[3]) + "px"
+		});
+	},
+
+	_renderProxy: function() {
+		var el = this.element, o = this.options;
+		this.elementOffset = el.offset();
+
+		if(o.helper) {
+			this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+			// fix ie6 offset
+			var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+			pxyoffset = ( ie6 ? 2 : -1 );
+
+			this.helper.addClass(o.helper).css({
+				width: el.outerWidth() + pxyoffset,
+				height: el.outerHeight() + pxyoffset,
+				position: 'absolute',
+				left: this.elementOffset.left - ie6offset +'px',
+				top: this.elementOffset.top - ie6offset +'px',
+				zIndex: ++o.zIndex
+			});
+
+			this.helper.appendTo("body");
+
+			if (o.disableSelection)
+				this.helper.disableSelection();
+
+		} else {
+			this.helper = el;
+		}
+	},
+
+	_change: {
+		e: function(event, dx, dy) {
+			return { width: this.originalSize.width + dx };
+		},
+		w: function(event, dx, dy) {
+			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+			return { left: sp.left + dx, width: cs.width - dx };
+		},
+		n: function(event, dx, dy) {
+			var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+			return { top: sp.top + dy, height: cs.height - dy };
+		},
+		s: function(event, dx, dy) {
+			return { height: this.originalSize.height + dy };
+		},
+		se: function(event, dx, dy) {
+			return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+		},
+		sw: function(event, dx, dy) {
+			return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+		},
+		ne: function(event, dx, dy) {
+			return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+		},
+		nw: function(event, dx, dy) {
+			return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+		}
+	},
+
+	_propagate: function(n, event) {
+		$.ui.plugin.call(this, n, [event, this.ui()]);
+		if (n != "resize") this.element.triggerHandler(["resize", n].join(""), [event, this.ui()], this.options[n]);
+	},
+
+	plugins: {},
+
+	ui: function() {
+		return {
+			originalElement: this.originalElement,
+			element: this.element,
+			helper: this.helper,
+			position: this.position,
+			size: this.size,
+			options: this.options,
+			originalSize: this.originalSize,
+			originalPosition: this.originalPosition
+		};
+	}
+
+}));
+
+$.extend($.ui.resizable, {
+	version: "1.6",
+	defaults: {
+		alsoResize: false,
+		animate: false,
+		animateDuration: "slow",
+		animateEasing: "swing",
+		aspectRatio: false,
+		autoHide: false,
+		cancel: ":input",
+		containment: false,
+		disableSelection: true,
+		distance: 1,
+		delay: 0,
+		ghost: false,
+		grid: false,
+		knobHandles: false,
+		maxHeight: null,
+		maxWidth: null,
+		minHeight: 10,
+		minWidth: 10,
+		preserveCursor: true,
+		preventDefault: true,
+		proportionallyResize: false,
+		transparent: false
+	}
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+	start: function(event, ui) {
+		var o = ui.options, self = $(this).data("resizable"),
+
+		_store = function(exp) {
+			$(exp).each(function() {
+				$(this).data("resizable-alsoresize", {
+					width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
+					left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
+				});
+			});
+		};
+
+		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+			if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0];	_store(o.alsoResize); }
+			else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
+		}else{
+			_store(o.alsoResize);
+		}
+	},
+
+	resize: function(event, ui){
+		var o = ui.options, self = $(this).data("resizable"), os = self.originalSize, op = self.originalPosition;
+
+		var delta = {
+			height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+			top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+		},
+
+		_alsoResize = function(exp, c) {
+			$(exp).each(function() {
+				var start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
+
+				$.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
+					var sum = (start[prop]||0) + (delta[prop]||0);
+					if (sum && sum >= 0)
+						style[prop] = sum || null;
+				});
+				$(this).css(style);
+			});
+		};
+
+		if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+			$.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
+		}else{
+			_alsoResize(o.alsoResize);
+		}
+	},
+
+	stop: function(event, ui){
+		$(this).removeData("resizable-alsoresize-start");
+	}
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+	stop: function(event, ui) {
+		var o = ui.options, self = $(this).data("resizable");
+
+		var pr = o.proportionallyResize, ista = pr && (/textarea/i).test(pr.get(0).nodeName),
+						soffseth = ista && $.ui.hasScroll(pr.get(0), 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+							soffsetw = ista ? 0 : self.sizeDiff.width;
+
+		var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+					left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+						top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+		self.element.animate(
+			$.extend(style, top && left ? { top: top, left: left } : {}), {
+				duration: o.animateDuration,
+				easing: o.animateEasing,
+				step: function() {
+
+					var data = {
+						width: parseInt(self.element.css('width'), 10),
+						height: parseInt(self.element.css('height'), 10),
+						top: parseInt(self.element.css('top'), 10),
+						left: parseInt(self.element.css('left'), 10)
+					};
+
+					if (pr) pr.css({ width: data.width, height: data.height });
+
+					// propagating resize, and updating values for each animation step
+					self._updateCache(data);
+					self._propagate("animate", event);
+
+				}
+			}
+		);
+	}
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+	start: function(event, ui) {
+		var o = ui.options, self = $(this).data("resizable"), el = self.element;
+		var oc = o.containment,	ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+		if (!ce) return;
+
+		self.containerElement = $(ce);
+
+		if (/document/.test(oc) || oc == document) {
+			self.containerOffset = { left: 0, top: 0 };
+			self.containerPosition = { left: 0, top: 0 };
+
+			self.parentData = {
+				element: $(document), left: 0, top: 0,
+				width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+			};
+		}
+
+		// i'm a node, so compute top, left, right, bottom
+		else{
+			var element = $(ce), p = [];
+			$([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+			self.containerOffset = element.offset();
+			self.containerPosition = element.position();
+			self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+			var co = self.containerOffset, ch = self.containerSize.height,	cw = self.containerSize.width,
+						width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+			self.parentData = {
+				element: ce, left: co.left, top: co.top, width: width, height: height
+			};
+		}
+	},
+
+	resize: function(event, ui) {
+		var o = ui.options, self = $(this).data("resizable"),
+				ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+				pRatio = o._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+		if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+		if (cp.left < (o.helper ? co.left : 0)) {
+			self.size.width = self.size.width + (o.helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+			if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+			self.position.left = o.helper ? co.left : 0;
+		}
+
+		if (cp.top < (o.helper ? co.top : 0)) {
+			self.size.height = self.size.height + (o.helper ? (self.position.top - co.top) : self.position.top);
+			if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+			self.position.top = o.helper ? co.top : 0;
+		}
+
+		self.offset.left = self.parentData.left+self.position.left;
+		self.offset.top = self.parentData.top+self.position.top;
+
+		var woset = Math.abs( (o.helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+					hoset = Math.abs( (o.helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+		var isParent = self.containerElement.get(0) == self.element.parent().get(0),
+		    isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
+
+		if(isParent && isOffsetRelative) woset -= self.parentData.left;
+
+		if (woset + self.size.width >= self.parentData.width) {
+			self.size.width = self.parentData.width - woset;
+			if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+		}
+
+		if (hoset + self.size.height >= self.parentData.height) {
+			self.size.height = self.parentData.height - hoset;
+			if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+		}
+	},
+
+	stop: function(event, ui){
+		var o = ui.options, self = $(this).data("resizable"), cp = self.position,
+				co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+		var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+		if (o.helper && !o.animate && (/relative/).test(ce.css('position')))
+			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+		if (o.helper && !o.animate && (/static/).test(ce.css('position')))
+			$(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+	}
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+	start: function(event, ui) {
+		var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize, cs = self.size;
+
+		if (!pr) self.ghost = self.element.clone();
+		else self.ghost = pr.clone();
+
+		self.ghost.css(
+			{ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }
+		)
+		.addClass('ui-resizable-ghost').addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+		self.ghost.appendTo(self.helper);
+
+	},
+
+	resize: function(event, ui){
+		var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize;
+
+		if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+
+	},
+
+	stop: function(event, ui){
+		var o = ui.options, self = $(this).data("resizable"), pr = o.proportionallyResize;
+		if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+	}
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+	resize: function(event, ui) {
+		var o = ui.options, self = $(this).data("resizable"), cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
+		o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+		var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+		if (/^(se|s|e)$/.test(a)) {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+		}
+		else if (/^(ne)$/.test(a)) {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+			self.position.top = op.top - oy;
+		}
+		else if (/^(sw)$/.test(a)) {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+			self.position.left = op.left - ox;
+		}
+		else {
+			self.size.width = os.width + ox;
+			self.size.height = os.height + oy;
+			self.position.top = op.top - oy;
+			self.position.left = op.left - ox;
+		}
+	}
+
+});
+
+var num = function(v) {
+	return parseInt(v, 10) || 0;
+};
+
+})(jQuery);

+ 107 - 107
tests/loader.js

@@ -1,107 +1,107 @@
-
-var _origVars = [];
-for (var _prop in window) {
-	_origVars.push(_prop);
-}
-
-function varLeaks() {
-	for (var prop in window) {
-		var found = false;
-		for (var i=0; i<_origVars.length; i++) {
-			if (prop == _origVars[i]) {
-				found = true;
-				break;
-			}
-		}
-		if (!found) {
-			console.log(prop);
-		}
-	}
-}
-
-var m = window.location.href.match(/\?(.*)$/);
-var queryString = m ? m[1] : '';
-
-function queryStringParam(name) {
-	m = queryString.match(new RegExp("(?:^|&)"+name+"(?:=([^&]))?"));
-	if (m) {
-		if (m[1]) return m[1];
-		return true;
-	}
-}
-
-function includeJS(src) {
-	document.write("<script type='text/javascript' src='" + src + "'><\/script>");
-}
-
-function includeCSS(href) {
-	document.write("<link rel='stylesheet' type='text/css' href='" + href + "' />");
-}
-
-var _build = queryStringParam('build');
-var _uncompressed = queryStringParam('uncompressed');
-var _legacy = queryStringParam('legacy');
-
-if (_build) {
-	includeCSS('../build/fullcalendar/fullcalendar.css');
-}else{
-	includeCSS('../src/css/main.css');
-	includeCSS('../src/css/grid.css');
-}
-
-if (_legacy) {
-	includeJS('jquery-legacy/jquery.js');
-	includeJS('jquery-legacy/ui.core.js');
-	includeJS('jquery-legacy/ui.draggable.js');
-	includeJS('jquery-legacy/ui.resizable.js');
-}
-else if (_build) {
-	includeJS('../build/fullcalendar/jquery/jquery.js');
-	includeJS('../build/fullcalendar/jquery/ui.core.js');
-	includeJS('../build/fullcalendar/jquery/ui.draggable.js');
-	includeJS('../build/fullcalendar/jquery/ui.resizable.js');
-}
-else {
-	includeJS('../src/jquery/jquery.js');
-	includeJS('../src/jquery/ui.core.js');
-	includeJS('../src/jquery/ui.draggable.js');
-	includeJS('../src/jquery/ui.resizable.js');
-}
-
-if (_build) {
-	if (_uncompressed) {
-		includeJS('../build/fullcalendar/uncompressed/fullcalendar.js');
-	}else{
-		includeJS('../build/fullcalendar/fullcalendar.js');
-	}
-	includeJS('../build/fullcalendar/gcal.js');
-}else{
-	includeJS('../src/main.js');
-	includeJS('../src/grid.js');
-	includeJS('../src/view.js');
-	includeJS('../src/util.js');
-	includeJS('../src/gcal.js');
-}
-
-var _userAgent = navigator.userAgent.toLowerCase();
-if (!/mozilla/.test(_userAgent) || /(compatible|webkit)/.test(_userAgent)) {
-	includeJS('firebug-lite/firebug-lite-compressed.js');
-}
-
-window.onload = function() {
-	$('body').append(
-		"<form style='position:absolute;top:0;right:0;text-align:right;font-size:10px;color:#666'>" +
-			"<label for='build'>build</label> " +
-			"<input type='checkbox' id='build' name='build'" + (_build ? " checked='checked'" : '') +
-				" style='vertical-align:middle' onclick='$(this).parent().submit()' />" +
-			"<br />" +
-			"<label for='uncompressed'>uncompressed</label> " +
-			"<input type='checkbox' id='uncompressed' name='uncompressed'" + (_uncompressed ? " checked='checked'" : '') +
-				" style='vertical-align:middle' onclick='$(this).parent().submit()' />" +
-			"<br />" +
-			"<label for='legacy'>legacy</label> " +
-			"<input type='checkbox' id='legacy' name='legacy'" + (_legacy ? " checked='checked'" : '') +
-				" style='vertical-align:middle' onclick='$(this).parent().submit()' />" +
-		"</form>"
-	);
-};
+
+var _origVars = [];
+for (var _prop in window) {
+	_origVars.push(_prop);
+}
+
+function varLeaks() {
+	for (var prop in window) {
+		var found = false;
+		for (var i=0; i<_origVars.length; i++) {
+			if (prop == _origVars[i]) {
+				found = true;
+				break;
+			}
+		}
+		if (!found) {
+			console.log(prop);
+		}
+	}
+}
+
+var m = window.location.href.match(/\?(.*)$/);
+var queryString = m ? m[1] : '';
+
+function queryStringParam(name) {
+	m = queryString.match(new RegExp("(?:^|&)"+name+"(?:=([^&]))?"));
+	if (m) {
+		if (m[1]) return m[1];
+		return true;
+	}
+}
+
+function includeJS(src) {
+	document.write("<script type='text/javascript' src='" + src + "'><\/script>");
+}
+
+function includeCSS(href) {
+	document.write("<link rel='stylesheet' type='text/css' href='" + href + "' />");
+}
+
+var _build = queryStringParam('build');
+var _minified = queryStringParam('minified');
+var _legacy = queryStringParam('legacy');
+
+if (_build) {
+	includeCSS('../build/fullcalendar/fullcalendar.css');
+}else{
+	includeCSS('../src/css/main.css');
+	includeCSS('../src/css/grid.css');
+}
+
+if (_legacy) {
+	includeJS('jquery-legacy/jquery.js');
+	includeJS('jquery-legacy/ui.core.js');
+	includeJS('jquery-legacy/ui.draggable.js');
+	includeJS('jquery-legacy/ui.resizable.js');
+}
+else if (_build) {
+	includeJS('../build/fullcalendar/jquery/jquery.js');
+	includeJS('../build/fullcalendar/jquery/ui.core.js');
+	includeJS('../build/fullcalendar/jquery/ui.draggable.js');
+	includeJS('../build/fullcalendar/jquery/ui.resizable.js');
+}
+else {
+	includeJS('../src/jquery/jquery.js');
+	includeJS('../src/jquery/ui.core.js');
+	includeJS('../src/jquery/ui.draggable.js');
+	includeJS('../src/jquery/ui.resizable.js');
+}
+
+if (_build) {
+	if (_minified) {
+		includeJS('../build/fullcalendar/fullcalendar.min.js');
+	}else{
+		includeJS('../build/fullcalendar/fullcalendar.js');
+	}
+	includeJS('../build/fullcalendar/gcal.js');
+}else{
+	includeJS('../src/main.js');
+	includeJS('../src/grid.js');
+	includeJS('../src/view.js');
+	includeJS('../src/util.js');
+	includeJS('../src/gcal.js');
+}
+
+var _userAgent = navigator.userAgent.toLowerCase();
+if (!/mozilla/.test(_userAgent) || /(compatible|webkit)/.test(_userAgent)) {
+	includeJS('firebug-lite/firebug-lite-compressed.js');
+}
+
+window.onload = function() {
+	$('body').append(
+		"<form style='position:absolute;top:0;right:0;text-align:right;font-size:10px;color:#666'>" +
+			"<label for='build'>build</label> " +
+			"<input type='checkbox' id='build' name='build'" + (_build ? " checked='checked'" : '') +
+				" style='vertical-align:middle' onclick='$(this).parent().submit()' />" +
+			"<br />" +
+			"<label for='minified'>minified</label> " +
+			"<input type='checkbox' id='minified' name='minified'" + (_minified ? " checked='checked'" : '') +
+				" style='vertical-align:middle' onclick='$(this).parent().submit()' />" +
+			"<br />" +
+			"<label for='legacy'>legacy</label> " +
+			"<input type='checkbox' id='legacy' name='legacy'" + (_legacy ? " checked='checked'" : '') +
+				" style='vertical-align:middle' onclick='$(this).parent().submit()' />" +
+		"</form>"
+	);
+};

+ 81 - 81
tests/locale.html

@@ -1,82 +1,82 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<script type='text/javascript' src='loader.js'></script>
-<script type='text/javascript'>
-
-	var d = new Date();
-	var y = d.getFullYear();
-	var m = d.getMonth();
-
-	$(document).ready(function() {
-		$('#calendar').fullCalendar({
-			header: {
-				center: 'month,basicWeek,basicDay'
-			},
-			editable: true,
-			
-			isRTL: true,
-			weekMode: 'variable',
-			
-			// TODO: add drag & resize tests
-			
-			events: [
-				{
-					id: 1,
-					title: "Long Event",
-					start: new Date(y, m, 6),
-					end: new Date(y, m, 10)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 2)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 9)
-				},
-				{
-					id: 3,
-					title: "Meeting",
-					start: new Date(y, m, 20, 9, 0),
-					end: new Date(y, m, 20, 10, 0),
-					allDay: false
-				},
-				{
-					id: 4,
-					title: "Click for Facebook",
-					start: new Date(y, m, 27),
-					end: new Date(y, m, 28),
-					url: "http://facebook.com/"
-				},
-				{
-					id: 5,
-					title: "timed event1",
-					start: new Date (y, m, 31, 17, 30),
-					allDay: false
-				},
-				{
-					id: 6,
-					title: "timed event1",
-					start: new Date (y, m+1, 2, 14, 15),
-					allDay: false
-				},
-				{
-					id: 7,
-					title: "timed event1",
-					start: new Date (y, m+1, 4, 15, 00),
-					end: new Date(y, m+1, 4, 17, 00),
-					allDay: false
-				}
-			]
-		});
-	});
-
-</script>
-</head>
-<body style='font-size:12px'>
-<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
-</body>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<script type='text/javascript' src='loader.js'></script>
+<script type='text/javascript'>
+
+	var d = new Date();
+	var y = d.getFullYear();
+	var m = d.getMonth();
+
+	$(document).ready(function() {
+		$('#calendar').fullCalendar({
+			header: {
+				center: 'month,basicWeek,basicDay'
+			},
+			editable: true,
+			
+			isRTL: true,
+			weekMode: 'variable',
+			
+			// TODO: add drag & resize tests
+			
+			events: [
+				{
+					id: 1,
+					title: "Long Event",
+					start: new Date(y, m, 6),
+					end: new Date(y, m, 10)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 2)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 9)
+				},
+				{
+					id: 3,
+					title: "Meeting",
+					start: new Date(y, m, 20, 9, 0),
+					end: new Date(y, m, 20, 10, 0),
+					allDay: false
+				},
+				{
+					id: 4,
+					title: "Click for Facebook",
+					start: new Date(y, m, 27),
+					end: new Date(y, m, 28),
+					url: "http://facebook.com/"
+				},
+				{
+					id: 5,
+					title: "timed event1",
+					start: new Date (y, m, 31, 17, 30),
+					allDay: false
+				},
+				{
+					id: 6,
+					title: "timed event1",
+					start: new Date (y, m+1, 2, 14, 15),
+					allDay: false
+				},
+				{
+					id: 7,
+					title: "timed event1",
+					start: new Date (y, m+1, 4, 15, 00),
+					end: new Date(y, m+1, 4, 17, 00),
+					allDay: false
+				}
+			]
+		});
+	});
+
+</script>
+</head>
+<body style='font-size:12px'>
+<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
+</body>
 </html>

+ 149 - 149
tests/methods.html

@@ -1,150 +1,150 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<script type='text/javascript' src='loader.js'></script>
-<script type='text/javascript'>
-
-	var cal;
-	var d = new Date();
-	var y = d.getFullYear();
-	var m = d.getMonth();
-	
-	var staticEvents;
-
-	$(document).ready(function() {
-		cal = $('#calendar').fullCalendar({
-			editable: true,
-			header: {
-				left: 'prev,next today',
-				center: 'title',
-				right: 'month,basicWeek,basicDay'
-			},
-			events: staticEvents = [
-				{
-					id: 1,
-					title: "Long Event",
-					start: new Date(y, m, 6),
-					end: new Date(y, m, 10)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 2)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 9)
-				},
-				{
-					id: 3,
-					title: "Meeting",
-					start: new Date(y, m, 20, 9, 0),
-					end: new Date(y, m, 21, 0, 0),
-					allDay: false
-				},
-				{
-					id: 4,
-					title: "Click for Facebook",
-					start: new Date(y, m, 27),
-					end: new Date(y, m, 28),
-					url: "http://facebook.com/"
-				},
-				{
-					id: 5,
-					title: "timed event1",
-					start: new Date (y, m, 31, 17, 30),
-					allDay: false
-				},
-				{
-					id: 6,
-					title: "timed event1",
-					start: new Date (y, m+1, 2, 14, 15),
-					allDay: false
-				},
-				{
-					id: 7,
-					title: "timed event1",
-					start: new Date (y, m+1, 4, 15, 00),
-					end: new Date(y, m+1, 4, 17, 00),
-					allDay: false
-				}
-			]
-		});
-	});
-	
-	function updateEventStart() {
-		var event = cal.fullCalendar('clientEvents', 3)[0];
-		event.start = new Date(y, m, 25, 10, 30);
-		event.end = new Date(y, m, 26);
-		cal.fullCalendar('updateEvent', event);
-	}
-	
-	function updateRepeatingEvent() {
-		var event = cal.fullCalendar('clientEvents', 2)[0];
-		event.start = new Date(y, m, 4, 13, 30);
-		event.end = new Date(y, m, 5, 1, 0);
-		event.allDay = false;
-		event.title = "repeat yo";
-		cal.fullCalendar('updateEvent', event);
-		console.log(cal.fullCalendar('clientEvents', 2));
-	}
-	
-	function renderEvent(stick) {
-		cal.fullCalendar('renderEvent', {
-			start: new Date(y, m, 16),
-			title: 'heyman'
-		}, stick);
-	}
-	
-	var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
-	
-	var jsonFeed = "../examples/json_events.php";
-
-</script>
-<style>
-
-	button {
-		font-size: 11px;
-	}
-
-</style>
-</head>
-<body style='font-size:12px'>
-<p>
-
-<button onclick="cal.fullCalendar('prev')">prev</button>
-<button onclick="cal.fullCalendar('next')">next</button>
-<button onclick="cal.fullCalendar('today')">today</button>
-<button onclick="cal.fullCalendar('gotoDate', 1999, 9, 31)">Oct 31 1999</button>
-<button onclick="cal.fullCalendar('moveDate', 1, 1, 1)">+1 +1 +1</button>
-<button onclick="cal.fullCalendar('moveDate', -1, -1, -1)">-1 -1 -1</button>
-
-<button onclick="updateEventStart()">update event start</button>
-<button onclick="updateRepeatingEvent()">update repeating event</button>
-<button onclick="renderEvent(false)">render new event</button>
-<button onclick="renderEvent(true)">render new sticky event</button>
-<br />
-
-<button onclick="cal.fullCalendar('removeEvents')">remove all</button>
-<button onclick="cal.fullCalendar('removeEvents', 2)">remove repeating events</button>
-<button onclick="cal.fullCalendar('removeEvents', function(e){return !e.allDay})">remove timed events</button>
-<button onclick="console.log(cal.fullCalendar('clientEvents'))">log events</button>
-<button onclick="console.log(cal.fullCalendar('clientEvents', '2'))">log repeating events</button>
-<button onclick="console.log(cal.fullCalendar('clientEvents', function(e){return e.allDay}))">log all-day events</button>
-<br />
-
-<button onclick="cal.fullCalendar('addEventSource', staticEvents)">+ static events</button>
-<button onclick="cal.fullCalendar('removeEventSource', staticEvents)">- static events</button>
-<button onclick="cal.fullCalendar('addEventSource', gcalFeed)">+ gcal</button>
-<button onclick="cal.fullCalendar('removeEventSource', gcalFeed)">- gcal</button>
-<button onclick="cal.fullCalendar('addEventSource', jsonFeed)">+ json</button>
-<button onclick="cal.fullCalendar('removeEventSource', jsonFeed)">- json</button>
-
-<button onclick="cal.fullCalendar('rerenderEvents')">rerender</button>
-<button onclick="cal.fullCalendar('refetchEvents')">refetch</button>
-
-</p>
-<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
-</body>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<script type='text/javascript' src='loader.js'></script>
+<script type='text/javascript'>
+
+	var cal;
+	var d = new Date();
+	var y = d.getFullYear();
+	var m = d.getMonth();
+	
+	var staticEvents;
+
+	$(document).ready(function() {
+		cal = $('#calendar').fullCalendar({
+			editable: true,
+			header: {
+				left: 'prev,next today',
+				center: 'title',
+				right: 'month,basicWeek,basicDay'
+			},
+			events: staticEvents = [
+				{
+					id: 1,
+					title: "Long Event",
+					start: new Date(y, m, 6),
+					end: new Date(y, m, 10)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 2)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 9)
+				},
+				{
+					id: 3,
+					title: "Meeting",
+					start: new Date(y, m, 20, 9, 0),
+					end: new Date(y, m, 21, 0, 0),
+					allDay: false
+				},
+				{
+					id: 4,
+					title: "Click for Facebook",
+					start: new Date(y, m, 27),
+					end: new Date(y, m, 28),
+					url: "http://facebook.com/"
+				},
+				{
+					id: 5,
+					title: "timed event1",
+					start: new Date (y, m, 31, 17, 30),
+					allDay: false
+				},
+				{
+					id: 6,
+					title: "timed event1",
+					start: new Date (y, m+1, 2, 14, 15),
+					allDay: false
+				},
+				{
+					id: 7,
+					title: "timed event1",
+					start: new Date (y, m+1, 4, 15, 00),
+					end: new Date(y, m+1, 4, 17, 00),
+					allDay: false
+				}
+			]
+		});
+	});
+	
+	function updateEventStart() {
+		var event = cal.fullCalendar('clientEvents', 3)[0];
+		event.start = new Date(y, m, 25, 10, 30);
+		event.end = new Date(y, m, 26);
+		cal.fullCalendar('updateEvent', event);
+	}
+	
+	function updateRepeatingEvent() {
+		var event = cal.fullCalendar('clientEvents', 2)[0];
+		event.start = new Date(y, m, 4, 13, 30);
+		event.end = new Date(y, m, 5, 1, 0);
+		event.allDay = false;
+		event.title = "repeat yo";
+		cal.fullCalendar('updateEvent', event);
+		console.log(cal.fullCalendar('clientEvents', 2));
+	}
+	
+	function renderEvent(stick) {
+		cal.fullCalendar('renderEvent', {
+			start: new Date(y, m, 16),
+			title: 'heyman'
+		}, stick);
+	}
+	
+	var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
+	
+	var jsonFeed = "../examples/json_events.php";
+
+</script>
+<style>
+
+	button {
+		font-size: 11px;
+	}
+
+</style>
+</head>
+<body style='font-size:12px'>
+<p>
+
+<button onclick="cal.fullCalendar('prev')">prev</button>
+<button onclick="cal.fullCalendar('next')">next</button>
+<button onclick="cal.fullCalendar('today')">today</button>
+<button onclick="cal.fullCalendar('gotoDate', 1999, 9, 31)">Oct 31 1999</button>
+<button onclick="cal.fullCalendar('moveDate', 1, 1, 1)">+1 +1 +1</button>
+<button onclick="cal.fullCalendar('moveDate', -1, -1, -1)">-1 -1 -1</button>
+
+<button onclick="updateEventStart()">update event start</button>
+<button onclick="updateRepeatingEvent()">update repeating event</button>
+<button onclick="renderEvent(false)">render new event</button>
+<button onclick="renderEvent(true)">render new sticky event</button>
+<br />
+
+<button onclick="cal.fullCalendar('removeEvents')">remove all</button>
+<button onclick="cal.fullCalendar('removeEvents', 2)">remove repeating events</button>
+<button onclick="cal.fullCalendar('removeEvents', function(e){return !e.allDay})">remove timed events</button>
+<button onclick="console.log(cal.fullCalendar('clientEvents'))">log events</button>
+<button onclick="console.log(cal.fullCalendar('clientEvents', '2'))">log repeating events</button>
+<button onclick="console.log(cal.fullCalendar('clientEvents', function(e){return e.allDay}))">log all-day events</button>
+<br />
+
+<button onclick="cal.fullCalendar('addEventSource', staticEvents)">+ static events</button>
+<button onclick="cal.fullCalendar('removeEventSource', staticEvents)">- static events</button>
+<button onclick="cal.fullCalendar('addEventSource', gcalFeed)">+ gcal</button>
+<button onclick="cal.fullCalendar('removeEventSource', gcalFeed)">- gcal</button>
+<button onclick="cal.fullCalendar('addEventSource', jsonFeed)">+ json</button>
+<button onclick="cal.fullCalendar('removeEventSource', jsonFeed)">- json</button>
+
+<button onclick="cal.fullCalendar('rerenderEvents')">rerender</button>
+<button onclick="cal.fullCalendar('refetchEvents')">refetch</button>
+
+</p>
+<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
+</body>
 </html>

+ 109 - 108
tests/options.html

@@ -1,109 +1,110 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<script type='text/javascript' src='loader.js'></script>
-<script type='text/javascript'>
-
-	var d = new Date();
-	var y = d.getFullYear();
-	var m = d.getMonth();
-
-	$(document).ready(function() {
-		$('#calendar').fullCalendar({
-		
-			/*
-			year: 2010,
-			month: 2,
-			date: 1,
-			
-			defaultView: 'basicDay',
-			
-			aspectRatio: 1,
-			*/
-			
-			header: {
-				left: 'title',
-				center: 'prev,month,basicWeek,basicDay,next',
-				right: 'today'
-			},
-			
-			editable: true,
-			//disableDragging: true,
-			//disableResizing: true,
-			dragOpacity: .5,
-			dragRevertDuration: 100,
-			
-			weekMode: 'liquid', //'variable'
-			
-			/*
-			titleFormat: {
-				month: "'hey!'"
-			},
-			*/
-			
-			columnFormat: {
-				month: "dddd"
-			},
-			
-			timeFormat: "H(:mm)[T]{ - H(:mm)T}",
-			
-			events: [
-				{
-					id: 1,
-					title: "Long Event",
-					start: new Date(y, m, 6),
-					end: new Date(y, m, 10)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 2)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 9)
-				},
-				{
-					id: 3,
-					title: "Meeting",
-					start: new Date(y, m, 20, 9, 0),
-					end: new Date(y, m, 20, 10, 0),
-					allDay: false
-				},
-				{
-					id: 4,
-					title: "Click for Facebook",
-					start: new Date(y, m, 27),
-					end: new Date(y, m, 28),
-					url: "http://facebook.com/"
-				},
-				{
-					id: 5,
-					title: "timed event1",
-					start: new Date (y, m, 31, 17, 30),
-					allDay: false
-				},
-				{
-					id: 6,
-					title: "timed event1",
-					start: new Date (y, m+1, 2, 14, 15),
-					allDay: false
-				},
-				{
-					id: 7,
-					title: "timed event1",
-					start: new Date (y, m+1, 4, 15, 00),
-					end: new Date(y, m+1, 4, 17, 00),
-					allDay: false
-				}
-			]
-		});
-	});
-
-</script>
-</head>
-<body style='font-size:12px'>
-<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
-</body>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<script type='text/javascript' src='loader.js'></script>
+<script type='text/javascript'>
+
+	var d = new Date();
+	var y = d.getFullYear();
+	var m = d.getMonth();
+
+	$(document).ready(function() {
+		$('#calendar').fullCalendar({
+		
+			/*
+			year: 2010,
+			month: 2,
+			date: 1,
+			
+			defaultView: 'basicDay',
+			
+			aspectRatio: 1,
+			*/
+			
+			header: {
+				left: 'title',
+				center: 'prev,month,basicWeek,basicDay,next',
+				right: 'today'
+			},
+			
+			editable: true,
+			//disableDragging: true,
+			//disableResizing: true,
+			dragOpacity: .5,
+			dragRevertDuration: 100,
+			
+			weekMode: 'liquid', //'variable'
+			
+			/*
+			titleFormat: {
+				month: "'hey!'"
+			},
+			*/
+			
+			columnFormat: {
+				month: "dddd"
+			},
+			
+			timeFormat: "H(:mm)[T]{ - H(:mm)T}",
+			
+			events: [
+				{
+					id: 1,
+					title: "Long Event",
+					start: new Date(y, m, 6),
+					end: new Date(y, m, 10)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 2)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 9)
+				},
+				{
+					id: 3,
+					title: "Meeting",
+					start: new Date(y, m, 20, 9, 0),
+					end: new Date(y, m, 20, 10, 0),
+					allDay: false
+				},
+				{
+					id: 4,
+					title: "Click for Facebook",
+					start: new Date(y, m, 27),
+					end: new Date(y, m, 28),
+					url: "http://facebook.com/"
+				},
+				{
+					id: 5,
+					title: "timed event1",
+					start: new Date (y, m, 31, 17, 30),
+					allDay: false
+				},
+				{
+					id: 6,
+					title: "timed event1",
+					start: new Date (y, m+1, 2, 14, 15),
+					allDay: false
+				},
+				{
+					id: 7,
+					title: "timed event1",
+					start: new Date (y, m+1, 4, 15, 00),
+					end: new Date(y, m+1, 4, 17, 00),
+					allDay: false
+				}
+			]
+		});
+		
+	});
+
+</script>
+</head>
+<body style='font-size:12px'>
+<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
+</body>
 </html>

+ 143 - 143
tests/sources.html

@@ -1,144 +1,144 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<script type='text/javascript' src='loader.js'></script>
-<script type='text/javascript'>
-
-	var cal;
-	var d = new Date();
-	var y = d.getFullYear();
-	var m = d.getMonth();
-	
-	var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
-	
-	var jsonFeed = "../examples/json_events.php";
-	
-	var staticEvents = [
-		{
-			id: 1,
-			title: "Long Event",
-			date: new Date(y, m, 6), //!
-			end: new Date(y, m, 10),
-			className: 'red-event'
-		},
-		{
-			id: 2,
-			title: "Repeating",
-			start: new Date(y, m, 2)
-		},
-		{
-			id: 2,
-			title: "Repeating",
-			start: new Date(y, m, 9)
-		},
-		{
-			id: 3,
-			title: "Meeting",
-			start: new Date(y, m, 20, 9, 0),
-			end: new Date(y, m, 21, 0, 0),
-			allDay: false,
-			//className: 'yellow-event black-text-event',
-			className: ['yellow-event', 'black-text-event'],
-			editable: false
-		},
-		{
-			id: 4,
-			title: "Click for Facebook",
-			start: new Date(y, m, 27),
-			end: new Date(y, m, 28),
-			url: "http://facebook.com/"
-		},
-		{
-			id: 5,
-			title: "timed event1",
-			start: new Date (y, m, 31, 17, 30),
-			allDay: false
-		},
-		{
-			id: 6,
-			title: "timed event1",
-			start: new Date (y, m+1, 2, 14, 15),
-			allDay: false
-		},
-		{
-			id: 7,
-			title: "timed event1",
-			start: new Date (y, m+1, 4, 15, 00),
-			end: new Date(y, m+1, 4, 17, 00),
-			allDay: false
-		}
-	];
-	
-	var customSource = function(start, end, callback) {
-		callback([
-			{
-				title: 'FIRST',
-				start: start
-			},
-			{
-				title: 'LAST',
-				start: new Date(end - 1)
-			}
-		]);
-	};
-
-	$(document).ready(function() {
-		cal = $('#calendar').fullCalendar({
-			editable: true,
-			header: {
-				left: 'prev,next today',
-				center: 'title',
-				right: 'month,basicWeek,basicDay'
-			},
-			//events: staticEvents,
-			eventSources: [
-				staticEvents,
-				jsonFeed,
-				gcalFeed,
-				customSource
-			],
-			loading: function(bool) {
-				if (bool) {
-					$('#loading').show();
-				}else{
-					$('#loading').hide();
-				}
-			}
-			/*
-			,
-			startParam: 'mystart',
-			endParam: 'myend',
-			cacheParam: 'uniq'
-			*/
-		});
-	});
-
-</script>
-<style>
-
-	.red-event a {
-		background: red;
-	}
-	
-	.yellow-event a {
-		background: yellow;
-	}
-	
-	.black-text-event a {
-		color: #000;
-	}
-
-	button {
-		font-size: 11px;
-	}
-
-</style>
-</head>
-<body style='font-size:12px'>
-<div id='loading' style='position:absolute;top:0;left:0;display:none'>loading...</div>
-<p>
-<button onclick="cal.fullCalendar('refetchEvents')">refetch</button>
-</p>
-<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
-</body>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<script type='text/javascript' src='loader.js'></script>
+<script type='text/javascript'>
+
+	var cal;
+	var d = new Date();
+	var y = d.getFullYear();
+	var m = d.getMonth();
+	
+	var gcalFeed = $.fullCalendar.gcalFeed("http://www.google.com/calendar/feeds/usa__en%40holiday.calendar.google.com/public/basic");
+	
+	var jsonFeed = "../examples/json_events.php";
+	
+	var staticEvents = [
+		{
+			id: 1,
+			title: "Long Event",
+			date: new Date(y, m, 6), //!
+			end: new Date(y, m, 10),
+			className: 'red-event'
+		},
+		{
+			id: 2,
+			title: "Repeating",
+			start: new Date(y, m, 2)
+		},
+		{
+			id: 2,
+			title: "Repeating",
+			start: new Date(y, m, 9)
+		},
+		{
+			id: 3,
+			title: "Meeting",
+			start: new Date(y, m, 20, 9, 0),
+			end: new Date(y, m, 21, 0, 0),
+			allDay: false,
+			//className: 'yellow-event black-text-event',
+			className: ['yellow-event', 'black-text-event'],
+			editable: false
+		},
+		{
+			id: 4,
+			title: "Click for Facebook",
+			start: new Date(y, m, 27),
+			end: new Date(y, m, 28),
+			url: "http://facebook.com/"
+		},
+		{
+			id: 5,
+			title: "timed event1",
+			start: new Date (y, m, 31, 17, 30),
+			allDay: false
+		},
+		{
+			id: 6,
+			title: "timed event1",
+			start: new Date (y, m+1, 2, 14, 15),
+			allDay: false
+		},
+		{
+			id: 7,
+			title: "timed event1",
+			start: new Date (y, m+1, 4, 15, 00),
+			end: new Date(y, m+1, 4, 17, 00),
+			allDay: false
+		}
+	];
+	
+	var customSource = function(start, end, callback) {
+		callback([
+			{
+				title: 'FIRST',
+				start: start
+			},
+			{
+				title: 'LAST',
+				start: new Date(end - 1)
+			}
+		]);
+	};
+
+	$(document).ready(function() {
+		cal = $('#calendar').fullCalendar({
+			editable: true,
+			header: {
+				left: 'prev,next today',
+				center: 'title',
+				right: 'month,basicWeek,basicDay'
+			},
+			//events: staticEvents,
+			eventSources: [
+				staticEvents,
+				jsonFeed,
+				gcalFeed,
+				customSource
+			],
+			loading: function(bool) {
+				if (bool) {
+					$('#loading').show();
+				}else{
+					$('#loading').hide();
+				}
+			}
+			/*
+			,
+			startParam: 'mystart',
+			endParam: 'myend',
+			cacheParam: 'uniq'
+			*/
+		});
+	});
+
+</script>
+<style>
+
+	.red-event a {
+		background: red;
+	}
+	
+	.yellow-event a {
+		background: yellow;
+	}
+	
+	.black-text-event a {
+		color: #000;
+	}
+
+	button {
+		font-size: 11px;
+	}
+
+</style>
+</head>
+<body style='font-size:12px'>
+<div id='loading' style='position:absolute;top:0;left:0;display:none'>loading...</div>
+<p>
+<button onclick="cal.fullCalendar('refetchEvents')">refetch</button>
+</p>
+<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
+</body>
 </html>

+ 86 - 86
tests/theming.html

@@ -1,87 +1,87 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<link rel='stylesheet' type='text/css' href='../examples/redmond/theme.css' />
-<script type='text/javascript' src='loader.js'></script>
-<script type='text/javascript'>
-
-	var d = new Date();
-	var y = d.getFullYear();
-	var m = d.getMonth();
-
-	$(document).ready(function() {
-		$('#calendar').fullCalendar({
-		
-			theme: true,
-			editable: true,
-			
-			header: {
-				center: 'month,basicWeek,basicDay'
-			},
-			
-			buttonIcons: {
-				prev: 'triangle-1-w',
-				next: 'triangle-1-e',
-				today: 'home'
-			},
-			
-			events: [
-				{
-					id: 1,
-					title: "Long Event",
-					start: new Date(y, m, 6),
-					end: new Date(y, m, 10)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 2)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 9)
-				},
-				{
-					id: 3,
-					title: "Meeting",
-					start: new Date(y, m, 20, 9, 0),
-					end: new Date(y, m, 20, 10, 0),
-					allDay: false
-				},
-				{
-					id: 4,
-					title: "Click for Facebook",
-					start: new Date(y, m, 27),
-					end: new Date(y, m, 28),
-					url: "http://facebook.com/"
-				},
-				{
-					id: 5,
-					title: "timed event1",
-					start: new Date (y, m, 31, 17, 30),
-					allDay: false
-				},
-				{
-					id: 6,
-					title: "timed event1",
-					start: new Date (y, m+1, 2, 14, 15),
-					allDay: false
-				},
-				{
-					id: 7,
-					title: "timed event1",
-					start: new Date (y, m+1, 4, 15, 00),
-					end: new Date(y, m+1, 4, 17, 00),
-					allDay: false
-				}
-			]
-		});
-	});
-
-</script>
-</head>
-<body style='font-size:12px'>
-<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
-</body>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<link rel='stylesheet' type='text/css' href='../examples/redmond/theme.css' />
+<script type='text/javascript' src='loader.js'></script>
+<script type='text/javascript'>
+
+	var d = new Date();
+	var y = d.getFullYear();
+	var m = d.getMonth();
+
+	$(document).ready(function() {
+		$('#calendar').fullCalendar({
+		
+			theme: true,
+			editable: true,
+			
+			header: {
+				center: 'month,basicWeek,basicDay'
+			},
+			
+			buttonIcons: {
+				prev: 'triangle-1-w',
+				next: 'triangle-1-e',
+				today: 'home'
+			},
+			
+			events: [
+				{
+					id: 1,
+					title: "Long Event",
+					start: new Date(y, m, 6),
+					end: new Date(y, m, 10)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 2)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 9)
+				},
+				{
+					id: 3,
+					title: "Meeting",
+					start: new Date(y, m, 20, 9, 0),
+					end: new Date(y, m, 20, 10, 0),
+					allDay: false
+				},
+				{
+					id: 4,
+					title: "Click for Facebook",
+					start: new Date(y, m, 27),
+					end: new Date(y, m, 28),
+					url: "http://facebook.com/"
+				},
+				{
+					id: 5,
+					title: "timed event1",
+					start: new Date (y, m, 31, 17, 30),
+					allDay: false
+				},
+				{
+					id: 6,
+					title: "timed event1",
+					start: new Date (y, m+1, 2, 14, 15),
+					allDay: false
+				},
+				{
+					id: 7,
+					title: "timed event1",
+					start: new Date (y, m+1, 4, 15, 00),
+					end: new Date(y, m+1, 4, 17, 00),
+					allDay: false
+				}
+			]
+		});
+	});
+
+</script>
+</head>
+<body style='font-size:12px'>
+<div id='calendar' style='width:900px;margin:20px auto 0;font-family:arial'></div>
+</body>
 </html>

+ 179 - 179
tests/triggers.html

@@ -1,180 +1,180 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
-<script type='text/javascript' src='loader.js'></script>
-<script type='text/javascript'>
-
-	var d = new Date();
-	var y = d.getFullYear();
-	var m = d.getMonth();
-
-	$(document).ready(function() {
-		$('#calendar').fullCalendar({
-			header: {
-				left: 'prev,next today',
-				center: 'title',
-				right: 'month,basicWeek,basicDay'
-			},
-			editable: true,
-			weekMode: 'variable',
-			
-			viewDisplay: function(view) {
-				console.log('viewDisplay');
-				console.log(view);
-				console.log(this);
-			},
-			
-			//loading: // see sources.html
-			
-			windowResize: function(view) {
-				console.log('windowResize - ' + view.title);
-				console.log(this);
-			},
-			
-			dayClick: function(dayDate, view) {
-				console.log('dayClick - ' + dayDate + ' - ' + view.title);
-				console.log(this);
-			},
-			
-			eventRender: function(event, element, view) {
-				if (event.id == 555) {
-					return false;
-				}
-				else if (event.id == 666) {
-					return $("<div style='background:green'/>").text(event.title);
-				}
-				else if (event.id == 1) {
-					element.css('border-color', 'red');
-					console.log('renderEvent (' + event.title + ') - ' + view.title);
-				}
-			},
-			
-			eventClick: function(event, jsEvent, view) {
-				console.log('EVENT CLICK ' + event.title);
-				console.log(jsEvent);
-				console.log(view);
-				console.log(this);
-				return false;
-			},
-			/*
-			eventMouseover: function(event, jsEvent, view) {
-				console.log('MOUSEOVER ' + event.title);
-				console.log(jsEvent);
-				console.log(view);
-				console.log(this);
-			},
-			eventMouseout: function(event, jsEvent, view) {
-				console.log('MOUSEOUT ' + event.title);
-				console.log(jsEvent);
-				console.log(view);
-				console.log(this);
-			},
-			*/
-			
-			eventDragStart: function(event, jsEvent, ui, view) {
-				console.log('DRAG START ' + event.title);
-				console.log(this);
-			},
-			eventDragStop: function(event, jsEvent, ui, view) {
-				console.log('DRAG STOP ' + event.title);
-				console.log(this);
-			},
-			eventDrop: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
-				console.log('DROP ' + event.title);
-				console.log(dayDelta + ' days');
-				console.log(minuteDelta + ' minutes');
-				console.log(jsEvent);
-				console.log(ui);
-				console.log(view.title);
-				console.log(this);
-			},
-			
-			eventResizeStart: function(event, jsEvent, ui, view) {
-				console.log('RESIZE START ' + event.title);
-				console.log(this);
-			},
-			eventResizeStop: function(event, jsEvent, ui, view) {
-				console.log('RESIZE STOP ' + event.title);
-				console.log(this);
-			},
-			eventResize: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
-				console.log('RESIZE!! ' + event.title);
-				console.log(dayDelta + ' days');
-				console.log(minuteDelta + ' minutes');
-				console.log(jsEvent);
-				console.log(ui);
-				console.log(view.title);
-				console.log(this);
-			},
-			
-			events: [
-				{
-					id: 555,
-					title: "Rejected Event",
-					start: new Date(y, m, 5)
-				},
-				{
-					id: 666,
-					title: "Homemade Elm Event",
-					start: new Date(y, m, 6)
-				},
-				{
-					id: 1,
-					title: "Long Event",
-					start: new Date(y, m, 6),
-					end: new Date(y, m, 10)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 2)
-				},
-				{
-					id: 2,
-					title: "Repeating",
-					start: new Date(y, m, 9),
-					end: new Date(y, m, 10)
-				},
-				{
-					id: 3,
-					title: "Meeting",
-					start: new Date(y, m, 20, 9, 0),
-					end: new Date(y, m, 20, 10, 0),
-					allDay: false
-				},
-				{
-					id: 4,
-					title: "Click for Facebook",
-					start: new Date(y, m, 27),
-					end: new Date(y, m, 28),
-					url: "http://facebook.com/"
-				},
-				{
-					id: 5,
-					title: "timed event1",
-					start: new Date (y, m, 31, 17, 30),
-					allDay: false
-				},
-				{
-					id: 6,
-					title: "timed event1",
-					start: new Date (y, m+1, 2, 14, 15),
-					allDay: false
-				},
-				{
-					id: 7,
-					title: "timed event1",
-					start: new Date (y, m+1, 4, 15, 00),
-					end: new Date(y, m+1, 4, 17, 00),
-					allDay: false
-				}
-			]
-		});
-	});
-
-</script>
-</head>
-<body style='font-size:12px'>
-<div id='calendar' style='width:75%;margin:20px auto 0;font-family:arial'></div>
-</body>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<script type='text/javascript' src='loader.js'></script>
+<script type='text/javascript'>
+
+	var d = new Date();
+	var y = d.getFullYear();
+	var m = d.getMonth();
+
+	$(document).ready(function() {
+		$('#calendar').fullCalendar({
+			header: {
+				left: 'prev,next today',
+				center: 'title',
+				right: 'month,basicWeek,basicDay'
+			},
+			editable: true,
+			weekMode: 'variable',
+			
+			viewDisplay: function(view) {
+				console.log('viewDisplay');
+				console.log(view);
+				console.log(this);
+			},
+			
+			//loading: // see sources.html
+			
+			windowResize: function(view) {
+				console.log('windowResize - ' + view.title);
+				console.log(this);
+			},
+			
+			dayClick: function(dayDate, view) {
+				console.log('dayClick - ' + dayDate + ' - ' + view.title);
+				console.log(this);
+			},
+			
+			eventRender: function(event, element, view) {
+				if (event.id == 555) {
+					return false;
+				}
+				else if (event.id == 666) {
+					return $("<div style='background:green'/>").text(event.title);
+				}
+				else if (event.id == 1) {
+					element.css('border-color', 'red');
+					console.log('renderEvent (' + event.title + ') - ' + view.title);
+				}
+			},
+			
+			eventClick: function(event, jsEvent, view) {
+				console.log('EVENT CLICK ' + event.title);
+				console.log(jsEvent);
+				console.log(view);
+				console.log(this);
+				return false;
+			},
+			/*
+			eventMouseover: function(event, jsEvent, view) {
+				console.log('MOUSEOVER ' + event.title);
+				console.log(jsEvent);
+				console.log(view);
+				console.log(this);
+			},
+			eventMouseout: function(event, jsEvent, view) {
+				console.log('MOUSEOUT ' + event.title);
+				console.log(jsEvent);
+				console.log(view);
+				console.log(this);
+			},
+			*/
+			
+			eventDragStart: function(event, jsEvent, ui, view) {
+				console.log('DRAG START ' + event.title);
+				console.log(this);
+			},
+			eventDragStop: function(event, jsEvent, ui, view) {
+				console.log('DRAG STOP ' + event.title);
+				console.log(this);
+			},
+			eventDrop: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
+				console.log('DROP ' + event.title);
+				console.log(dayDelta + ' days');
+				console.log(minuteDelta + ' minutes');
+				console.log(jsEvent);
+				console.log(ui);
+				console.log(view.title);
+				console.log(this);
+			},
+			
+			eventResizeStart: function(event, jsEvent, ui, view) {
+				console.log('RESIZE START ' + event.title);
+				console.log(this);
+			},
+			eventResizeStop: function(event, jsEvent, ui, view) {
+				console.log('RESIZE STOP ' + event.title);
+				console.log(this);
+			},
+			eventResize: function(event, dayDelta, minuteDelta, jsEvent, ui, view) {
+				console.log('RESIZE!! ' + event.title);
+				console.log(dayDelta + ' days');
+				console.log(minuteDelta + ' minutes');
+				console.log(jsEvent);
+				console.log(ui);
+				console.log(view.title);
+				console.log(this);
+			},
+			
+			events: [
+				{
+					id: 555,
+					title: "Rejected Event",
+					start: new Date(y, m, 5)
+				},
+				{
+					id: 666,
+					title: "Homemade Elm Event",
+					start: new Date(y, m, 6)
+				},
+				{
+					id: 1,
+					title: "Long Event",
+					start: new Date(y, m, 6),
+					end: new Date(y, m, 10)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 2)
+				},
+				{
+					id: 2,
+					title: "Repeating",
+					start: new Date(y, m, 9),
+					end: new Date(y, m, 10)
+				},
+				{
+					id: 3,
+					title: "Meeting",
+					start: new Date(y, m, 20, 9, 0),
+					end: new Date(y, m, 20, 10, 0),
+					allDay: false
+				},
+				{
+					id: 4,
+					title: "Click for Facebook",
+					start: new Date(y, m, 27),
+					end: new Date(y, m, 28),
+					url: "http://facebook.com/"
+				},
+				{
+					id: 5,
+					title: "timed event1",
+					start: new Date (y, m, 31, 17, 30),
+					allDay: false
+				},
+				{
+					id: 6,
+					title: "timed event1",
+					start: new Date (y, m+1, 2, 14, 15),
+					allDay: false
+				},
+				{
+					id: 7,
+					title: "timed event1",
+					start: new Date (y, m+1, 4, 15, 00),
+					end: new Date(y, m+1, 4, 17, 00),
+					allDay: false
+				}
+			]
+		});
+	});
+
+</script>
+</head>
+<body style='font-size:12px'>
+<div id='calendar' style='width:75%;margin:20px auto 0;font-family:arial'></div>
+</body>
 </html>