Commit a1b82974acf891d105d5297348c22dcef449db45

Authored by bernard
1 parent f7c78b68

Added ajax attributes (process,reRender,ajaxSingle,etc.).

Added widgetVar (for JavaScript).
Added JavaScript callbacks for all events that trigger ajax requests, so that developer could program veto on client side and still be notified when request finishes.
Fixed entities in message bundle (fix for WebKit bug).
Reformatted code.
Secured ScopeChain for JavaScript callbacks.
Added samples with fetching additional data, model panel with item details and internationalization.
@@ -36,7 +36,7 @@ @@ -36,7 +36,7 @@
36 --> 36 -->
37 &ui_component_attributes; 37 &ui_component_attributes;
38 &commonViewAttributes; 38 &commonViewAttributes;
39 - <!--&ui_data_attributes;--> 39 + &ajax_component_attributes;
40 <!--TODO how about reRender ajaxSingle and others?--> 40 <!--TODO how about reRender ajaxSingle and others?-->
41 <!--TODO add style attribute--> 41 <!--TODO add style attribute-->
42 <property> 42 <property>
@@ -53,6 +53,15 @@ @@ -53,6 +53,15 @@
53 <defaultvalue>"ajax"</defaultvalue> 53 <defaultvalue>"ajax"</defaultvalue>
54 </property> 54 </property>
55 <property> 55 <property>
  56 + <name>widgetVar</name>
  57 + <classname>java.lang.String</classname>
  58 + <description>
  59 + Variable name of JavaScript component.
  60 + default: null
  61 + </description>
  62 + <defaultvalue>null</defaultvalue>
  63 + </property>
  64 + <property>
56 <name>view</name> 65 <name>view</name>
57 <classname>java.lang.String</classname> 66 <classname>java.lang.String</classname>
58 <description> 67 <description>
@@ -456,7 +465,30 @@ @@ -456,7 +465,30 @@
456 <name>onItemSelected</name> 465 <name>onItemSelected</name>
457 <classname>java.lang.String</classname> 466 <classname>java.lang.String</classname>
458 <description> 467 <description>
459 - <!--TODO add description here--> 468 + JavaScript code for handling event.
  469 + Following data will be available in context:
  470 + <ul>
  471 + <li>item - selected item</li>
  472 + <li>event - javascript event</li>
  473 + <li>view - object representing current view</li>
  474 + </ul>
  475 + </description>
  476 + <defaultvalue>null</defaultvalue>
  477 + </property>
  478 + <property>
  479 + <name>onItemSelectedComplete</name>
  480 + <classname>java.lang.String</classname>
  481 + <description>
  482 + JavaScript code called when ajax request triggered when item
  483 + is selected has finished.
  484 + Following data will be available in context:
  485 + <ul>
  486 + <li>item - selected item</li>
  487 + <li>event - javascript event</li>
  488 + <li>view - object representing current view</li>
  489 + <li>request - ajax request</li>
  490 + <li>data - data returned by ajax request</li>
  491 + </ul>
460 </description> 492 </description>
461 <defaultvalue>null</defaultvalue> 493 <defaultvalue>null</defaultvalue>
462 </property> 494 </property>
@@ -464,7 +496,14 @@ @@ -464,7 +496,14 @@
464 <name>onItemDragStart</name> 496 <name>onItemDragStart</name>
465 <classname>java.lang.String</classname> 497 <classname>java.lang.String</classname>
466 <description> 498 <description>
467 - <!--TODO add description here--> 499 + JavaScript code for handling event.
  500 + Following data will be available in context:
  501 + <ul>
  502 + <li>item - selected item</li>
  503 + <li>event - javascript event</li>
  504 + <li>ui - jQuery UI object</li>
  505 + <li>view - object representing current view</li>
  506 + </ul>
468 </description> 507 </description>
469 <defaultvalue>null</defaultvalue> 508 <defaultvalue>null</defaultvalue>
470 </property> 509 </property>
@@ -472,7 +511,14 @@ @@ -472,7 +511,14 @@
472 <name>onItemDragStop</name> 511 <name>onItemDragStop</name>
473 <classname>java.lang.String</classname> 512 <classname>java.lang.String</classname>
474 <description> 513 <description>
475 - <!--TODO add description here--> 514 + JavaScript code for handling event.
  515 + Following data will be available in context:
  516 + <ul>
  517 + <li>item - selected item</li>
  518 + <li>event - javascript event</li>
  519 + <li>ui - jQuery UI object</li>
  520 + <li>view - object representing current view</li>
  521 + </ul>
476 </description> 522 </description>
477 <defaultvalue>null</defaultvalue> 523 <defaultvalue>null</defaultvalue>
478 </property> 524 </property>
@@ -480,7 +526,14 @@ @@ -480,7 +526,14 @@
480 <name>onItemResizeStart</name> 526 <name>onItemResizeStart</name>
481 <classname>java.lang.String</classname> 527 <classname>java.lang.String</classname>
482 <description> 528 <description>
483 - <!--TODO add description here--> 529 + JavaScript code for handling event.
  530 + Following data will be available in context:
  531 + <ul>
  532 + <li>item - selected item</li>
  533 + <li>event - javascript event</li>
  534 + <li>ui - jQuery UI object</li>
  535 + <li>view - object representing current view</li>
  536 + </ul>
484 </description> 537 </description>
485 <defaultvalue>null</defaultvalue> 538 <defaultvalue>null</defaultvalue>
486 </property> 539 </property>
@@ -488,7 +541,14 @@ @@ -488,7 +541,14 @@
488 <name>onItemResizeStop</name> 541 <name>onItemResizeStop</name>
489 <classname>java.lang.String</classname> 542 <classname>java.lang.String</classname>
490 <description> 543 <description>
491 - <!--TODO add description here--> 544 + JavaScript code for handling event.
  545 + Following data will be available in context:
  546 + <ul>
  547 + <li>item - selected item</li>
  548 + <li>event - javascript event</li>
  549 + <li>ui - jQuery UI object</li>
  550 + <li>view - object representing current view</li>
  551 + </ul>
492 </description> 552 </description>
493 <defaultvalue>null</defaultvalue> 553 <defaultvalue>null</defaultvalue>
494 </property> 554 </property>
@@ -496,7 +556,53 @@ @@ -496,7 +556,53 @@
496 <name>onItemDrop</name> 556 <name>onItemDrop</name>
497 <classname>java.lang.String</classname> 557 <classname>java.lang.String</classname>
498 <description> 558 <description>
499 - <!--TODO add description here--> 559 + JavaScript code for handling event.
  560 + Following data will be available in context:
  561 + <ul>
  562 + <li>item - selected item</li>
  563 + <li>dayDelta - holds the number of days the event was moved forward (a positive number) or backwards
  564 + (a negative number)
  565 + </li>
  566 + <li>minuteDelta - holds the number of minutes the event was moved forward (a positive number) or
  567 + backwards (a negative number). Only useful for the agenda views. In other views, 0 is passed in.
  568 + </li>
  569 + <li>allDay - is true if the event has been dropped on a day in month view, or the "all-day" slot in
  570 + the agenda views. It will be false if dropped on a slot in the agenda views (meaning it has been
  571 + assigned a time).
  572 + </li>
  573 + <li>event - javascript event</li>
  574 + <li>ui - jQuery UI object</li>
  575 + <li>view - object representing current view</li>
  576 + </ul>
  577 + </description>
  578 + <defaultvalue>null</defaultvalue>
  579 + </property>
  580 + <property>
  581 + <name>onItemDropComplete</name>
  582 + <classname>java.lang.String</classname>
  583 + <description>
  584 + JavaScript code called when ajax request triggered when item
  585 + is dropped has finished.
  586 + Following data will be available in context:
  587 + <ul>
  588 + <li>item - selected item</li>
  589 + <li>dayDelta - holds the number of days the event was moved forward (a positive number) or backwards
  590 + (a negative number)
  591 + </li>
  592 + <li>minuteDelta - holds the number of minutes the event was moved forward (a positive number) or
  593 + backwards (a negative number). Only useful for the agenda views. In other views, 0 is passed in.
  594 + </li>
  595 + <li>allDay - is true if the event has been dropped on a day in month view, or the "all-day" slot in
  596 + the agenda views. It will be false if dropped on a slot in the agenda views (meaning it has been
  597 + assigned a time).
  598 + </li>
  599 + <li>vetoed - is true if server side listener has raised veto and modification has been reverted</li>
  600 + <li>event - javascript event</li>
  601 + <li>ui - jQuery UI object</li>
  602 + <li>view - object representing current view</li>
  603 + <li>request - ajax request</li>
  604 + <li>data - data returned by ajax request</li>
  605 + </ul>
500 </description> 606 </description>
501 <defaultvalue>null</defaultvalue> 607 <defaultvalue>null</defaultvalue>
502 </property> 608 </property>
@@ -504,7 +610,47 @@ @@ -504,7 +610,47 @@
504 <name>onItemResized</name> 610 <name>onItemResized</name>
505 <classname>java.lang.String</classname> 611 <classname>java.lang.String</classname>
506 <description> 612 <description>
507 - <!--TODO add description here--> 613 + JavaScript code for handling event.
  614 + Following data will be available in context:
  615 + <ul>
  616 + <li>item - selected item</li>
  617 + <li>dayDelta - holds the number of days the event was moved forward (a positive number) or backwards
  618 + (a negative number)holds the number of minutes the event was moved forward (a positive number)
  619 + or backwards (a negative number). Only useful for the agenda views. In other views, 0 is passed
  620 + in.
  621 + </li>
  622 + <li>minuteDelta - holds the number of minutes the event was moved forward (a positive number) or
  623 + backwards (a negative number). Only useful for the agenda views. In other views, 0 is passed in.
  624 + </li>
  625 + <li>event - javascript event</li>
  626 + <li>ui - jQuery UI object</li>
  627 + <li>view - object representing current view</li>
  628 + </ul>
  629 + </description>
  630 + <defaultvalue>null</defaultvalue>
  631 + </property>
  632 + <property>
  633 + <name>onItemResizedComplete</name>
  634 + <classname>java.lang.String</classname>
  635 + <description>
  636 + JavaScript code called when ajax request triggered when item
  637 + is resized has finished.
  638 + Following data will be available in context:
  639 + <ul>
  640 + <li>item - selected item</li>
  641 + <li>dayDelta - holds the number of days the event was moved forward (a positive number) or backwards
  642 + (a negative number)
  643 + </li>
  644 + <li>minuteDelta - holds the number of minutes the event was moved forward (a positive number) or
  645 + backwards (a negative number). Only useful for the agenda views. In other views, 0 is passed in.
  646 + </li>
  647 + <li>vetoed - is true if server side listener has raised veto and modification has been reverted</li>
  648 + <li>event - javascript event</li>
  649 + <li>ui - jQuery UI object</li>
  650 + <li>view - object representing current view</li>
  651 + <li>request - ajax request</li>
  652 + <li>data - data returned by ajax request</li>
  653 + </ul>
508 </description> 654 </description>
509 <defaultvalue>null</defaultvalue> 655 <defaultvalue>null</defaultvalue>
510 </property> 656 </property>
@@ -512,7 +658,13 @@ @@ -512,7 +658,13 @@
512 <name>onItemMouseover</name> 658 <name>onItemMouseover</name>
513 <classname>java.lang.String</classname> 659 <classname>java.lang.String</classname>
514 <description> 660 <description>
515 - <!--TODO add description here--> 661 + JavaScript code for handling event.
  662 + Following data will be available in context:
  663 + <ul>
  664 + <li>item - selected item</li>
  665 + <li>event - javascript event</li>
  666 + <li>view - object representing current view</li>
  667 + </ul>
516 </description> 668 </description>
517 <defaultvalue>null</defaultvalue> 669 <defaultvalue>null</defaultvalue>
518 </property> 670 </property>
@@ -520,15 +672,42 @@ @@ -520,15 +672,42 @@
520 <name>onItemMouseout</name> 672 <name>onItemMouseout</name>
521 <classname>java.lang.String</classname> 673 <classname>java.lang.String</classname>
522 <description> 674 <description>
523 - <!--TODO add description here--> 675 + JavaScript code for handling event.
  676 + Following data will be available in context:
  677 + <ul>
  678 + <li>item - selected item</li>
  679 + <li>event - javascript event</li>
  680 + <li>view - object representing current view</li>
  681 + </ul>
  682 + </description>
  683 + <defaultvalue>null</defaultvalue>
  684 + </property>
  685 + <property>
  686 + <name>onViewChanged</name>
  687 + <classname>java.lang.String</classname>
  688 + <description>
  689 + JavaScript code for handling event.
  690 + <b>Any return instruction will be ignored</b>
  691 + so this code cannot block anything.
  692 + Following data will be available in context:
  693 + <ul>
  694 + <li>view - object representing current view</li>
  695 + </ul>
524 </description> 696 </description>
525 <defaultvalue>null</defaultvalue> 697 <defaultvalue>null</defaultvalue>
526 </property> 698 </property>
527 <property> 699 <property>
528 - <name>onViewDisplay</name> 700 + <name>onViewChangedComplete</name>
529 <classname>java.lang.String</classname> 701 <classname>java.lang.String</classname>
530 <description> 702 <description>
531 - <!--TODO add description here--> 703 + JavaScript code called when ajax request triggered when view
  704 + changes has finished.
  705 + Following data will be available in context:
  706 + <ul>
  707 + <li>view - object representing current view</li>
  708 + <li>request - ajax request</li>
  709 + <li>data - data returned by ajax request</li>
  710 + </ul>
532 </description> 711 </description>
533 <defaultvalue>null</defaultvalue> 712 <defaultvalue>null</defaultvalue>
534 </property> 713 </property>
@@ -536,7 +715,36 @@ @@ -536,7 +715,36 @@
536 <name>onDateSelected</name> 715 <name>onDateSelected</name>
537 <classname>java.lang.String</classname> 716 <classname>java.lang.String</classname>
538 <description> 717 <description>
539 - <!--TODO add description here--> 718 + JavaScript code for handling event.
  719 + Following data will be available in context:
  720 + <ul>
  721 + <li>date - selected date</li>
  722 + <li>allDay - is true if the event has been dropped on a day in month view, or the "all-day" slot in
  723 + the agenda views.
  724 + </li>
  725 + <li>event - javascript event</li>
  726 + <li>view - object representing current view</li>
  727 + </ul>
  728 + </description>
  729 + <defaultvalue>null</defaultvalue>
  730 + </property>
  731 + <property>
  732 + <name>onDateSelectedComplete</name>
  733 + <classname>java.lang.String</classname>
  734 + <description>
  735 + JavaScript code called when ajax request triggered when date
  736 + is selected has finished.
  737 + Following data will be available in context:
  738 + <ul>
  739 + <li>date - selected date</li>
  740 + <li>allDay - is true if the event has been dropped on a day in month view, or the "all-day" slot in
  741 + the agenda views.
  742 + </li>
  743 + <li>event - javascript event</li>
  744 + <li>view - object representing current view</li>
  745 + <li>request - ajax request</li>
  746 + <li>data - data returned by ajax request</li>
  747 + </ul>
540 </description> 748 </description>
541 <defaultvalue>null</defaultvalue> 749 <defaultvalue>null</defaultvalue>
542 </property> 750 </property>
@@ -544,7 +752,67 @@ @@ -544,7 +752,67 @@
544 <name>onDateRangeSelected</name> 752 <name>onDateRangeSelected</name>
545 <classname>java.lang.String</classname> 753 <classname>java.lang.String</classname>
546 <description> 754 <description>
547 - <!--TODO add description here--> 755 + JavaScript code for handling event.
  756 + Following data will be available in context:
  757 + <ul>
  758 + <li>startDate - selection start date</li>
  759 + <li>endDate - selection end date</li>
  760 + <li>allDay - is true if the event has been dropped on a day in month view, or the "all-day" slot in
  761 + the agenda views.
  762 + </li>
  763 + <li>view - object representing current view</li>
  764 + </ul>
  765 + </description>
  766 + <defaultvalue>null</defaultvalue>
  767 + </property>
  768 + <property>
  769 + <name>onDateRangeSelectedComplete</name>
  770 + <classname>java.lang.String</classname>
  771 + <description>
  772 + JavaScript code called when ajax request triggered when date
  773 + range is selected has finished.
  774 + Following data will be available in context:
  775 + <ul>
  776 + <li>startDate - selection start date</li>
  777 + <li>endDate - selection end date</li>
  778 + <li>allDay - is true if the event has been dropped on a day in month view, or the "all-day" slot in
  779 + the agenda views.
  780 + </li>
  781 + <li>view - object representing current view</li>
  782 + <li>request - ajax request</li>
  783 + <li>data - data returned by ajax request</li>
  784 + </ul>
  785 + </description>
  786 + <defaultvalue>null</defaultvalue>
  787 + </property>
  788 + <property>
  789 + <name>onDateRangeChanged</name>
  790 + <classname>java.lang.String</classname>
  791 + <description>
  792 + JavaScript code for handling event.
  793 + <b>Any return instruction will be ignored</b>
  794 + so this code cannot block anything.
  795 + Following data will be available in context:
  796 + <ul>
  797 + <li>startDate - start date</li>
  798 + <li>endDate - end date</li>
  799 + </ul>
  800 + </description>
  801 + <defaultvalue>null</defaultvalue>
  802 + </property>
  803 + <property>
  804 + <name>onDateRangeChangedComplete</name>
  805 + <classname>java.lang.String</classname>
  806 + <description>
  807 + JavaScript code called when ajax request triggered when displayed
  808 + date range is changed has finished.
  809 + Following data will be available in context:
  810 + <ul>
  811 + <li>startDate - selection start date</li>
  812 + <li>endDate - selection end date</li>
  813 + <li>request - ajax request</li>
  814 + <li>data - data returned by ajax request</li>
  815 + </ul>
548 </description> 816 </description>
549 <defaultvalue>null</defaultvalue> 817 <defaultvalue>null</defaultvalue>
550 </property> 818 </property>
@@ -555,7 +823,6 @@ @@ -555,7 +823,6 @@
555 </description> 823 </description>
556 <defaultvalue>null</defaultvalue> 824 <defaultvalue>null</defaultvalue>
557 </property> 825 </property>
558 - <!--TODO what about buttonText and other language dependant stuff? there is so many attributes there-->  
559 826
560 <property elonly="true" attachedstate="true"> 827 <property elonly="true" attachedstate="true">
561 <name>itemMoveListener</name> 828 <name>itemMoveListener</name>
@@ -594,6 +861,10 @@ @@ -594,6 +861,10 @@
594 <classname>javax.faces.el.MethodBinding</classname> 861 <classname>javax.faces.el.MethodBinding</classname>
595 </property> 862 </property>
596 863
  864 + <property exist="false" existintag="false" hidden="true">
  865 + <name>oncomplete</name>
  866 + </property>
  867 +
597 868
598 </component> 869 </component>
599 &listeners; 870 &listeners;
1 package org.richfaces.component; 1 package org.richfaces.component;
2 2
  3 +/**
  4 + * Interface with common attributes of all view components.
  5 + * Saves some lines in UISchedule...View classes.
  6 + *
  7 + * @author Bernard Labno
  8 + */
3 public interface ScheduleCommonViewAttributes { 9 public interface ScheduleCommonViewAttributes {
4 10
5 public String getTimeFormat(); 11 public String getTimeFormat();
1 package org.richfaces.component; 1 package org.richfaces.component;
2 2
  3 +import org.ajax4jsf.component.AjaxActionComponent;
  4 +import org.ajax4jsf.component.AjaxComponent;
3 import org.ajax4jsf.context.AjaxContext; 5 import org.ajax4jsf.context.AjaxContext;
  6 +import org.ajax4jsf.event.AjaxEvent;
4 import org.ajax4jsf.model.DataVisitor; 7 import org.ajax4jsf.model.DataVisitor;
5 import org.ajax4jsf.model.ExtendedDataModel; 8 import org.ajax4jsf.model.ExtendedDataModel;
  9 +import org.ajax4jsf.renderkit.RendererUtils;
6 import org.richfaces.component.event.*; 10 import org.richfaces.component.event.*;
7 import org.richfaces.component.model.DateRange; 11 import org.richfaces.component.model.DateRange;
8 12
@@ -22,16 +26,24 @@ import java.text.DateFormat; @@ -22,16 +26,24 @@ import java.text.DateFormat;
22 import java.text.SimpleDateFormat; 26 import java.text.SimpleDateFormat;
23 import java.util.*; 27 import java.util.*;
24 28
25 -public abstract class UISchedule extends UIComponentBase implements ScheduleCommonViewAttributes, ScheduleListenerEventsProducer { 29 +public abstract class UISchedule extends UIComponentBase implements ScheduleCommonViewAttributes, ScheduleListenerEventsProducer, AjaxComponent {
26 30
27 public static final String COMPONENT_TYPE = "org.richfaces.Schedule"; 31 public static final String COMPONENT_TYPE = "org.richfaces.Schedule";
28 public static final String COMPONENT_FAMILY = "org.richfaces.Schedule"; 32 public static final String COMPONENT_FAMILY = "org.richfaces.Schedule";
  33 + /**
  34 + * Values of view attribute.
  35 + */
29 public static final String VIEW_MONTH = "month"; 36 public static final String VIEW_MONTH = "month";
30 public static final String VIEW_BASIC_WEEK = "basicWeek"; 37 public static final String VIEW_BASIC_WEEK = "basicWeek";
31 public static final String VIEW_AGENDA_WEEK = "agendaWeek"; 38 public static final String VIEW_AGENDA_WEEK = "agendaWeek";
32 public static final String VIEW_BASIC_DAY = "basicDay"; 39 public static final String VIEW_BASIC_DAY = "basicDay";
33 public static final String VIEW_AGENDA_DAY = "agendaDay"; 40 public static final String VIEW_AGENDA_DAY = "agendaDay";
  41 + /**
  42 + * Values of weekMode attribute.
  43 + */
34 public static final String WEEK_MODE_FIXED = "fixed"; 44 public static final String WEEK_MODE_FIXED = "fixed";
  45 + public static final String WEEK_MODE_LIQUID = "liquid";
  46 + public static final String WEEK_MODE_VARIABLE = "variable";
35 private DataModel model; 47 private DataModel model;
36 48
37 public abstract Object getValue(); 49 public abstract Object getValue();
@@ -174,6 +186,10 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -174,6 +186,10 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
174 186
175 public abstract void setOnItemSelected(String onItemSelect); 187 public abstract void setOnItemSelected(String onItemSelect);
176 188
  189 + public abstract String getOnItemSelectedComplete();
  190 +
  191 + public abstract void setOnItemSelectedComplete(String onItemSelectedComplete);
  192 +
177 public abstract String getOnItemDragStart(); 193 public abstract String getOnItemDragStart();
178 194
179 public abstract void setOnItemDragStart(String onItemDragStart); 195 public abstract void setOnItemDragStart(String onItemDragStart);
@@ -186,6 +202,10 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -186,6 +202,10 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
186 202
187 public abstract void setOnItemDrop(String onItemDrop); 203 public abstract void setOnItemDrop(String onItemDrop);
188 204
  205 + public abstract String getOnItemDropComplete();
  206 +
  207 + public abstract void setOnItemDropComplete(String onItemDropComplete);
  208 +
189 public abstract String getOnItemResizeStart(); 209 public abstract String getOnItemResizeStart();
190 210
191 public abstract void setOnItemResizeStart(String onItemResizeStart); 211 public abstract void setOnItemResizeStart(String onItemResizeStart);
@@ -198,6 +218,10 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -198,6 +218,10 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
198 218
199 public abstract void setOnItemResized(String onItemMouseover); 219 public abstract void setOnItemResized(String onItemMouseover);
200 220
  221 + public abstract String getOnItemResizedComplete();
  222 +
  223 + public abstract void setOnItemResizedComplete(String setOnItemResizedComplete);
  224 +
201 public abstract String getOnItemMouseover(); 225 public abstract String getOnItemMouseover();
202 226
203 public abstract void setOnItemMouseover(String onItemMouseover); 227 public abstract void setOnItemMouseover(String onItemMouseover);
@@ -206,18 +230,38 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -206,18 +230,38 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
206 230
207 public abstract void setOnItemMouseout(String onItemMouseout); 231 public abstract void setOnItemMouseout(String onItemMouseout);
208 232
209 - public abstract String getOnViewDisplay(); 233 + public abstract String getOnViewChanged();
  234 +
  235 + public abstract void setOnViewChanged(String onViewChanged);
  236 +
  237 + public abstract String getOnViewChangedComplete();
210 238
211 - public abstract void setOnViewDisplay(String onViewDisplay); 239 + public abstract void setOnViewChangedComplete(String onViewDisplayComplete);
212 240
213 public abstract String getOnDateSelected(); 241 public abstract String getOnDateSelected();
214 242
215 public abstract void setOnDateSelected(String onDaySelected); 243 public abstract void setOnDateSelected(String onDaySelected);
216 244
  245 + public abstract String getOnDateSelectedComplete();
  246 +
  247 + public abstract void setOnDateSelectedComplete(String setOnDateSelectedComplete);
  248 +
217 public abstract String getOnDateRangeSelected(); 249 public abstract String getOnDateRangeSelected();
218 250
219 public abstract void setOnDateRangeSelected(String onDateRangeSelected); 251 public abstract void setOnDateRangeSelected(String onDateRangeSelected);
220 252
  253 + public abstract String getOnDateRangeSelectedComplete();
  254 +
  255 + public abstract void setOnDateRangeSelectedComplete(String onDateRangeSelectedComplete);
  256 +
  257 + public abstract String getOnDateRangeChanged();
  258 +
  259 + public abstract void setOnDateRangeChanged(String onDateRangeChanged);
  260 +
  261 + public abstract String getOnDateRangeChangedComplete();
  262 +
  263 + public abstract void setOnDateRangeChangedComplete(String onDateRangeChangedComplete);
  264 +
221 // TODO do we use MethodBinding or MethodExpression? 265 // TODO do we use MethodBinding or MethodExpression?
222 266
223 public abstract MethodBinding getItemMoveListener(); 267 public abstract MethodBinding getItemMoveListener();
@@ -248,10 +292,35 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -248,10 +292,35 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
248 292
249 public abstract void setDateSelectedListener(MethodBinding listener); 293 public abstract void setDateSelectedListener(MethodBinding listener);
250 294
  295 + public abstract String getWidgetVar();
  296 +
  297 + public abstract void setWidgetVar(String widgetVar);
  298 +
  299 + /**
  300 + * React on various events.
  301 + * Vetoable events are first broadcasted to listeners bound via EL to
  302 + * component attribtues and then if no veto is raised then to the rest of
  303 + * listeners.
  304 + * In case of non vetoable events the order of broadcast is reverse.
  305 + * Vetoable events are: ScheduleItemMoveEvent, ScheduleItemResizeEvent
  306 + * Non-vetoable events: ScheduleDateRangeChangedEvent, ScheduleItemSelectedEvent,
  307 + * ScheduleViewChangedEvent, ScheduleDateSelectedEvent,
  308 + * ScheduleDateRangeSelectedEvent
  309 + * In case of ScheduleDateRangeChangedEvent new items are returned
  310 + * via response data map of ajaxContext.
  311 + * In case of ScheduleItemMoveEvent and ScheduleItemResizeEvent, the
  312 + * decision if veto was raised is sent back to client via response data map
  313 + * of ajaxContext as boolean.
  314 + *
  315 + * @param event broadcasted event
  316 + * @throws AbortProcessingException if broadcasting of particular event
  317 + * should stop
  318 + */
251 @Override 319 @Override
252 public void broadcast(FacesEvent event) throws AbortProcessingException { 320 public void broadcast(FacesEvent event) throws AbortProcessingException {
253 if (event instanceof ScheduleDateRangeChangedEvent) { 321 if (event instanceof ScheduleDateRangeChangedEvent) {
254 super.broadcast(event); 322 super.broadcast(event);
  323 + new AjaxEvent(this).queue();
255 ScheduleDateRangeChangedEvent calendarAjaxEvent = (ScheduleDateRangeChangedEvent) event; 324 ScheduleDateRangeChangedEvent calendarAjaxEvent = (ScheduleDateRangeChangedEvent) event;
256 FacesContext facesContext = getFacesContext(); 325 FacesContext facesContext = getFacesContext();
257 AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext); 326 AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
@@ -273,8 +342,9 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -273,8 +342,9 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
273 Object result = expression.invoke(facesContext, new Object[]{event}); 342 Object result = expression.invoke(facesContext, new Object[]{event});
274 allow = ((Boolean) result); 343 allow = ((Boolean) result);
275 } 344 }
276 - ajaxContext.setResponseData(allow); 345 + ajaxContext.getResponseDataMap().put("_ajax:scheduleData", allow);
277 super.broadcast(event); 346 super.broadcast(event);
  347 + new AjaxEvent(this).queue();
278 } else if (event instanceof ScheduleItemResizeEvent) { 348 } else if (event instanceof ScheduleItemResizeEvent) {
279 FacesContext facesContext = getFacesContext(); 349 FacesContext facesContext = getFacesContext();
280 AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext); 350 AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
@@ -284,10 +354,12 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -284,10 +354,12 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
284 Object result = expression.invoke(facesContext, new Object[]{event}); 354 Object result = expression.invoke(facesContext, new Object[]{event});
285 allow = ((Boolean) result); 355 allow = ((Boolean) result);
286 } 356 }
287 - ajaxContext.setResponseData(allow); 357 + ajaxContext.getResponseDataMap().put("_ajax:scheduleData", allow);
288 super.broadcast(event); 358 super.broadcast(event);
  359 + new AjaxEvent(this).queue();
289 } else if (event instanceof ScheduleItemSelectedEvent) { 360 } else if (event instanceof ScheduleItemSelectedEvent) {
290 super.broadcast(event); 361 super.broadcast(event);
  362 + new AjaxEvent(this).queue();
291 FacesContext facesContext = getFacesContext(); 363 FacesContext facesContext = getFacesContext();
292 MethodBinding expression = getItemSelectedListener(); 364 MethodBinding expression = getItemSelectedListener();
293 if (expression != null) { 365 if (expression != null) {
@@ -295,6 +367,7 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -295,6 +367,7 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
295 } 367 }
296 } else if (event instanceof ScheduleViewChangedEvent) { 368 } else if (event instanceof ScheduleViewChangedEvent) {
297 super.broadcast(event); 369 super.broadcast(event);
  370 + new AjaxEvent(this).queue();
298 FacesContext facesContext = getFacesContext(); 371 FacesContext facesContext = getFacesContext();
299 MethodBinding expression = getViewChangedListener(); 372 MethodBinding expression = getViewChangedListener();
300 if (expression != null) { 373 if (expression != null) {
@@ -302,6 +375,7 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -302,6 +375,7 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
302 } 375 }
303 } else if (event instanceof ScheduleDateSelectedEvent) { 376 } else if (event instanceof ScheduleDateSelectedEvent) {
304 super.broadcast(event); 377 super.broadcast(event);
  378 + new AjaxEvent(this).queue();
305 FacesContext facesContext = getFacesContext(); 379 FacesContext facesContext = getFacesContext();
306 MethodBinding expression = getDateSelectedListener(); 380 MethodBinding expression = getDateSelectedListener();
307 if (expression != null) { 381 if (expression != null) {
@@ -309,11 +383,38 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm @@ -309,11 +383,38 @@ public abstract class UISchedule extends UIComponentBase implements ScheduleComm
309 } 383 }
310 } else if (event instanceof ScheduleDateRangeSelectedEvent) { 384 } else if (event instanceof ScheduleDateRangeSelectedEvent) {
311 super.broadcast(event); 385 super.broadcast(event);
  386 + new AjaxEvent(this).queue();
312 FacesContext facesContext = getFacesContext(); 387 FacesContext facesContext = getFacesContext();
313 MethodBinding expression = getDateRangeSelectedListener(); 388 MethodBinding expression = getDateRangeSelectedListener();
314 if (expression != null) { 389 if (expression != null) {
315 expression.invoke(facesContext, new Object[]{event}); 390 expression.invoke(facesContext, new Object[]{event});
316 } 391 }
  392 + } else if (event instanceof AjaxEvent) {
  393 + FacesContext context = getFacesContext();
  394 + // complete re-Render fields. AjaxEvent deliver before render
  395 + // response.
  396 + AjaxContext.getCurrentInstance(context).addRegionsFromComponent(this);
  397 + // Put data for send in response
  398 + Object data = getData();
  399 + AjaxContext ajaxContext = AjaxContext.getCurrentInstance(context);
  400 + if (null != data) {
  401 + ajaxContext.setResponseData(data);
  402 + }
  403 + String focus = getFocus();
  404 + if (null != focus) {
  405 + // search for component in tree.
  406 + // XXX - use more pourful search, as in h:outputLabel
  407 + // component.
  408 + UIComponent focusComponent = RendererUtils.getInstance().
  409 + findComponentFor(this, focus);
  410 + if (null != focusComponent) {
  411 + focus = focusComponent.getClientId(context);
  412 + }
  413 + ajaxContext.getResponseDataMap().put(AjaxActionComponent.FOCUS_DATA_ID, focus);
  414 + }
  415 + ajaxContext.setOncomplete(getOncomplete());
  416 + } else {
  417 + super.broadcast(event);
317 } 418 }
318 } 419 }
319 420
@@ -2,7 +2,7 @@ package org.richfaces.component; @@ -2,7 +2,7 @@ package org.richfaces.component;
2 2
3 import javax.faces.component.UIComponentBase; 3 import javax.faces.component.UIComponentBase;
4 4
5 -public abstract class UIScheduleBasicDayView extends UIComponentBase implements ScheduleCommonViewAttributes{ 5 +public abstract class UIScheduleBasicDayView extends UIComponentBase implements ScheduleCommonViewAttributes {
6 6
7 public static final String COMPONENT_TYPE = "org.richfaces.ScheduleBasicDayView"; 7 public static final String COMPONENT_TYPE = "org.richfaces.ScheduleBasicDayView";
8 public static final String COMPONENT_FAMILY = "org.richfaces.Schedule"; 8 public static final String COMPONENT_FAMILY = "org.richfaces.Schedule";
1 package org.richfaces.component.event; 1 package org.richfaces.component.event;
2 2
3 -import java.util.Date;  
4 -  
5 import javax.faces.component.UIComponent; 3 import javax.faces.component.UIComponent;
6 -  
7 import javax.faces.event.FacesEvent; 4 import javax.faces.event.FacesEvent;
8 import javax.faces.event.FacesListener; 5 import javax.faces.event.FacesListener;
  6 +import java.util.Date;
9 7
10 public class ScheduleDateRangeChangedEvent extends FacesEvent { 8 public class ScheduleDateRangeChangedEvent extends FacesEvent {
11 9
1 package org.richfaces.component.event; 1 package org.richfaces.component.event;
2 2
3 -import java.util.Date;  
4 import javax.faces.component.UIComponent; 3 import javax.faces.component.UIComponent;
5 import javax.faces.event.FacesEvent; 4 import javax.faces.event.FacesEvent;
6 import javax.faces.event.FacesListener; 5 import javax.faces.event.FacesListener;
  6 +import java.util.Date;
7 7
8 public class ScheduleDateSelectedEvent extends FacesEvent { 8 public class ScheduleDateSelectedEvent extends FacesEvent {
9 9
@@ -2,7 +2,7 @@ package org.richfaces.component.event; @@ -2,7 +2,7 @@ package org.richfaces.component.event;
2 2
3 import javax.faces.event.FacesListener; 3 import javax.faces.event.FacesListener;
4 4
5 -public interface ScheduleItemMoveListener extends FacesListener{ 5 +public interface ScheduleItemMoveListener extends FacesListener {
6 6
7 void itemMove(ScheduleItemMoveEvent event); 7 void itemMove(ScheduleItemMoveEvent event);
8 } 8 }
@@ -2,7 +2,7 @@ package org.richfaces.component.event; @@ -2,7 +2,7 @@ package org.richfaces.component.event;
2 2
3 import javax.faces.event.FacesListener; 3 import javax.faces.event.FacesListener;
4 4
5 -public interface ScheduleItemResizeListener extends FacesListener{ 5 +public interface ScheduleItemResizeListener extends FacesListener {
6 6
7 void itemResize(ScheduleItemResizeEvent event); 7 void itemResize(ScheduleItemResizeEvent event);
8 } 8 }
@@ -2,7 +2,7 @@ package org.richfaces.component.event; @@ -2,7 +2,7 @@ package org.richfaces.component.event;
2 2
3 import javax.faces.event.FacesListener; 3 import javax.faces.event.FacesListener;
4 4
5 -public interface ScheduleViewChangedListener extends FacesListener{ 5 +public interface ScheduleViewChangedListener extends FacesListener {
6 6
7 void viewChanged(ScheduleViewChangedEvent event); 7 void viewChanged(ScheduleViewChangedEvent event);
8 } 8 }
1 package org.richfaces.component.model; 1 package org.richfaces.component.model;
2 2
3 -import java.util.Date;  
4 import org.ajax4jsf.model.Range; 3 import org.ajax4jsf.model.Range;
5 4
  5 +import java.util.Date;
  6 +
6 public class DateRange implements Range { 7 public class DateRange implements Range {
7 8
8 private Date startDate; 9 private Date startDate;
@@ -121,6 +121,10 @@ public abstract class ScheduleRendererBase extends AjaxComponentRendererBase { @@ -121,6 +121,10 @@ public abstract class ScheduleRendererBase extends AjaxComponentRendererBase {
121 ResponseWriter writer = context.getResponseWriter(); 121 ResponseWriter writer = context.getResponseWriter();
122 String clientId = component.getClientId(context); 122 String clientId = component.getClientId(context);
123 Locale locale = context.getViewRoot().getLocale(); 123 Locale locale = context.getViewRoot().getLocale();
  124 + String widgetVar = component.getWidgetVar();
  125 + if (widgetVar != null) {
  126 + writer.writeText("var " + widgetVar + " = ", null);
  127 + }
124 writer.writeText(new JSObject("RichFaces.Schedule", clientId, locale.toString(), 128 writer.writeText(new JSObject("RichFaces.Schedule", clientId, locale.toString(),
125 getOptions(component), 129 getOptions(component),
126 DATE_RANGE_CHANGED_EVENT, 130 DATE_RANGE_CHANGED_EVENT,
@@ -205,18 +209,27 @@ public abstract class ScheduleRendererBase extends AjaxComponentRendererBase { @@ -205,18 +209,27 @@ public abstract class ScheduleRendererBase extends AjaxComponentRendererBase {
205 options.put("header", headerOptions); 209 options.put("header", headerOptions);
206 } 210 }
207 addOptionIfSet("allDayDefault", schedule.getAllDayByDefault(), options); 211 addOptionIfSet("allDayDefault", schedule.getAllDayByDefault(), options);
  212 +
208 addOptionIfSet("onItemSelected", schedule.getOnItemSelected(), options); 213 addOptionIfSet("onItemSelected", schedule.getOnItemSelected(), options);
  214 + addOptionIfSet("onItemSelectedComplete", schedule.getOnItemSelectedComplete(), options);
209 addOptionIfSet("onItemDrop", schedule.getOnItemDrop(), options); 215 addOptionIfSet("onItemDrop", schedule.getOnItemDrop(), options);
  216 + addOptionIfSet("onItemDropComplete", schedule.getOnItemDropComplete(), options);
210 addOptionIfSet("onItemResized", schedule.getOnItemResized(), options); 217 addOptionIfSet("onItemResized", schedule.getOnItemResized(), options);
  218 + addOptionIfSet("onItemResizedComplete", schedule.getOnItemResizedComplete(), options);
211 addOptionIfSet("onItemResizeStart", schedule.getOnItemResizeStart(), options); 219 addOptionIfSet("onItemResizeStart", schedule.getOnItemResizeStart(), options);
212 addOptionIfSet("onItemResizeStop", schedule.getOnItemResizeStop(), options); 220 addOptionIfSet("onItemResizeStop", schedule.getOnItemResizeStop(), options);
213 addOptionIfSet("onItemDragStart", schedule.getOnItemDragStart(), options); 221 addOptionIfSet("onItemDragStart", schedule.getOnItemDragStart(), options);
214 addOptionIfSet("onItemDragStop", schedule.getOnItemDragStop(), options); 222 addOptionIfSet("onItemDragStop", schedule.getOnItemDragStop(), options);
215 addOptionIfSet("onItemMouseover", schedule.getOnItemMouseover(), options); 223 addOptionIfSet("onItemMouseover", schedule.getOnItemMouseover(), options);
216 addOptionIfSet("onItemMouseout", schedule.getOnItemMouseout(), options); 224 addOptionIfSet("onItemMouseout", schedule.getOnItemMouseout(), options);
217 - addOptionIfSet("onViewDisplay", schedule.getOnViewDisplay(), options); 225 + addOptionIfSet("onViewChanged", schedule.getOnViewChanged(), options);
  226 + addOptionIfSet("onViewChangedComplete", schedule.getOnViewChangedComplete(), options);
218 addOptionIfSet("onDateSelected", schedule.getOnDateSelected(), options); 227 addOptionIfSet("onDateSelected", schedule.getOnDateSelected(), options);
  228 + addOptionIfSet("onDateSelectedComplete", schedule.getOnDateSelectedComplete(), options);
219 addOptionIfSet("onDateRangeSelected", schedule.getOnDateRangeSelected(), options); 229 addOptionIfSet("onDateRangeSelected", schedule.getOnDateRangeSelected(), options);
  230 + addOptionIfSet("onDateRangeSelectedComplete", schedule.getOnDateRangeSelectedComplete(), options);
  231 + addOptionIfSet("onDateRangeChanged", schedule.getOnDateRangeChanged(), options);
  232 + addOptionIfSet("onDateRangeChangedComplete", schedule.getOnDateRangeChangedComplete(), options);
220 if (schedule.getDate() != null) { 233 if (schedule.getDate() != null) {
221 Calendar calendar = Calendar.getInstance(); 234 Calendar calendar = Calendar.getInstance();
222 calendar.setTime(schedule.getDate()); 235 calendar.setTime(schedule.getDate());
1 package org.richfaces.taglib; 1 package org.richfaces.taglib;
2 2
3 import com.sun.facelets.FaceletContext; 3 import com.sun.facelets.FaceletContext;
4 -import com.sun.facelets.tag.MetaRule;  
5 -import com.sun.facelets.tag.MetaRuleset;  
6 -import com.sun.facelets.tag.Metadata;  
7 -import com.sun.facelets.tag.MetadataTarget;  
8 -import com.sun.facelets.tag.TagAttribute; 4 +import com.sun.facelets.tag.*;
9 import com.sun.facelets.tag.jsf.ComponentConfig; 5 import com.sun.facelets.tag.jsf.ComponentConfig;
10 import com.sun.facelets.tag.jsf.ComponentHandler; 6 import com.sun.facelets.tag.jsf.ComponentHandler;
11 -import javax.faces.component.UIComponent;  
12 -import javax.faces.el.MethodBinding;  
13 import org.richfaces.event.NodeExpandedEvent; 7 import org.richfaces.event.NodeExpandedEvent;
14 import org.richfaces.event.NodeSelectedEvent; 8 import org.richfaces.event.NodeSelectedEvent;
15 9
  10 +import javax.faces.component.UIComponent;
  11 +import javax.faces.el.MethodBinding;
  12 +
16 public class ScheduleTagHandlerBase extends ComponentHandler { 13 public class ScheduleTagHandlerBase extends ComponentHandler {
17 14
18 private final static String DATE_RANGE_CHANGED_LISTENER = "dateRangeChangedListener"; 15 private final static String DATE_RANGE_CHANGED_LISTENER = "dateRangeChangedListener";
@@ -37,10 +37,10 @@ org.richfaces.component.UISchedule.dayNamesShort.WEDNESDAY=Wed @@ -37,10 +37,10 @@ org.richfaces.component.UISchedule.dayNamesShort.WEDNESDAY=Wed
37 org.richfaces.component.UISchedule.dayNamesShort.THURSDAY=Thu 37 org.richfaces.component.UISchedule.dayNamesShort.THURSDAY=Thu
38 org.richfaces.component.UISchedule.dayNamesShort.FRIDAY=Fri 38 org.richfaces.component.UISchedule.dayNamesShort.FRIDAY=Fri
39 org.richfaces.component.UISchedule.dayNamesShort.SATURDAY=Sat 39 org.richfaces.component.UISchedule.dayNamesShort.SATURDAY=Sat
40 -org.richfaces.component.UISchedule.buttonTexts.prev=&nbsp;&#9668;&nbsp;  
41 -org.richfaces.component.UISchedule.buttonTexts.next=&nbsp;&#9658;&nbsp;  
42 -org.richfaces.component.UISchedule.buttonTexts.prevYear=&nbsp;&lt;&lt;&nbsp;  
43 -org.richfaces.component.UISchedule.buttonTexts.nextYear=&nbsp;&gt;&gt;&nbsp; 40 +org.richfaces.component.UISchedule.buttonTexts.prev=&#160;&#9668;&#160;
  41 +org.richfaces.component.UISchedule.buttonTexts.next=&#160;&#9658;&#160;
  42 +org.richfaces.component.UISchedule.buttonTexts.prevYear=&#160;&#60;&#60;&#160;
  43 +org.richfaces.component.UISchedule.buttonTexts.nextYear=&#160;&#62;&#62;&#160;
44 org.richfaces.component.UISchedule.buttonTexts.today=today 44 org.richfaces.component.UISchedule.buttonTexts.today=today
45 org.richfaces.component.UISchedule.buttonTexts.month=month 45 org.richfaces.component.UISchedule.buttonTexts.month=month
46 org.richfaces.component.UISchedule.buttonTexts.week=week 46 org.richfaces.component.UISchedule.buttonTexts.week=week
@@ -37,10 +37,10 @@ org.richfaces.component.UISchedule.dayNamesShort.WEDNESDAY=\u015Aro @@ -37,10 +37,10 @@ org.richfaces.component.UISchedule.dayNamesShort.WEDNESDAY=\u015Aro
37 org.richfaces.component.UISchedule.dayNamesShort.THURSDAY=Czw 37 org.richfaces.component.UISchedule.dayNamesShort.THURSDAY=Czw
38 org.richfaces.component.UISchedule.dayNamesShort.FRIDAY=Pi\u0105 38 org.richfaces.component.UISchedule.dayNamesShort.FRIDAY=Pi\u0105
39 org.richfaces.component.UISchedule.dayNamesShort.SATURDAY=Sob 39 org.richfaces.component.UISchedule.dayNamesShort.SATURDAY=Sob
40 -org.richfaces.component.UISchedule.buttonTexts.prev=&nbsp;&#9668;&nbsp;  
41 -org.richfaces.component.UISchedule.buttonTexts.next=&nbsp;&#9658;&nbsp;  
42 -org.richfaces.component.UISchedule.buttonTexts.prevYear=&nbsp;&lt;&lt;&nbsp;  
43 -org.richfaces.component.UISchedule.buttonTexts.nextYear=&nbsp;&gt;&gt;&nbsp; 40 +org.richfaces.component.UISchedule.buttonTexts.prev=&#160;&#9668;&#160;
  41 +org.richfaces.component.UISchedule.buttonTexts.next=&#160;&#9658;&#160;
  42 +org.richfaces.component.UISchedule.buttonTexts.prevYear=&#160;&#60;&#60;&#160;
  43 +org.richfaces.component.UISchedule.buttonTexts.nextYear=&#160;&#62;&#62;&#160;
44 org.richfaces.component.UISchedule.buttonTexts.today=Dzi\u015B 44 org.richfaces.component.UISchedule.buttonTexts.today=Dzi\u015B
45 org.richfaces.component.UISchedule.buttonTexts.month=Miesi\u0105c 45 org.richfaces.component.UISchedule.buttonTexts.month=Miesi\u0105c
46 org.richfaces.component.UISchedule.buttonTexts.week=Tydzie\u0144 46 org.richfaces.component.UISchedule.buttonTexts.week=Tydzie\u0144
@@ -10,566 +10,555 @@ @@ -10,566 +10,555 @@
10 * TODO adjust class names to richfaces naming conventions 10 * TODO adjust class names to richfaces naming conventions
11 */ 11 */
12 12
13 -  
14 .fc, 13 .fc,
15 .fc .fc-header, 14 .fc .fc-header,
16 .fc .fc-content { 15 .fc .fc-content {
17 - font-size: 1em;  
18 - }  
19 - 16 + font-size: 1em;
  17 +}
  18 +
20 .fc { 19 .fc {
21 - direction: ltr;  
22 - text-align: left;  
23 - }  
24 -  
25 -.fc table {  
26 - border-collapse: collapse;  
27 - border-spacing: 0;  
28 - }  
29 -  
30 -.fc td, .fc th {  
31 - padding: 0;  
32 - vertical-align: top;  
33 - } 20 + direction: ltr;
  21 + text-align: left;
  22 +}
34 23
  24 +.fc table {
  25 + border-collapse: collapse;
  26 + border-spacing: 0;
  27 +}
35 28
  29 +.fc td, .fc th {
  30 + padding: 0;
  31 + vertical-align: top;
  32 +}
36 33
37 /* Header 34 /* Header
38 ------------------------------------------------------------------------*/ 35 ------------------------------------------------------------------------*/
39 - 36 +
40 table.fc-header { 37 table.fc-header {
41 - width: 100%;  
42 - }  
43 - 38 + width: 100%;
  39 +}
  40 +
44 .fc-header-left { 41 .fc-header-left {
45 - width: 25%;  
46 - }  
47 - 42 + width: 25%;
  43 +}
  44 +
48 .fc-header-left table { 45 .fc-header-left table {
49 - float: left;  
50 - }  
51 - 46 + float: left;
  47 +}
  48 +
52 .fc-header-center { 49 .fc-header-center {
53 - width: 50%;  
54 - text-align: center;  
55 - }  
56 - 50 + width: 50%;
  51 + text-align: center;
  52 +}
  53 +
57 .fc-header-center table { 54 .fc-header-center table {
58 - margin: 0 auto;  
59 - }  
60 - 55 + margin: 0 auto;
  56 +}
  57 +
61 .fc-header-right { 58 .fc-header-right {
62 - width: 25%;  
63 - }  
64 - 59 + width: 25%;
  60 +}
  61 +
65 .fc-header-right table { 62 .fc-header-right table {
66 - float: right;  
67 - }  
68 - 63 + float: right;
  64 +}
  65 +
69 .fc-header-title { 66 .fc-header-title {
70 - margin-top: 0;  
71 - white-space: nowrap;  
72 - }  
73 - 67 + margin-top: 0;
  68 + white-space: nowrap;
  69 +}
  70 +
74 .fc-header-space { 71 .fc-header-space {
75 - padding-left: 10px;  
76 - }  
77 - 72 + padding-left: 10px;
  73 +}
  74 +
78 /* right-to-left */ 75 /* right-to-left */
79 76
80 .fc-rtl .fc-header-title { 77 .fc-rtl .fc-header-title {
81 - direction: rtl;  
82 - }  
83 -  
84 - 78 + direction: rtl;
  79 +}
85 80
86 /* Buttons 81 /* Buttons
87 ------------------------------------------------------------------------*/ 82 ------------------------------------------------------------------------*/
88 83
89 .fc-header .fc-state-default, 84 .fc-header .fc-state-default,
90 .fc-header .ui-state-default { 85 .fc-header .ui-state-default {
91 - margin-bottom: 1em;  
92 - cursor: pointer;  
93 - }  
94 - 86 + margin-bottom: 1em;
  87 + cursor: pointer;
  88 +}
  89 +
95 .fc-header .fc-state-default { 90 .fc-header .fc-state-default {
96 - border-width: 1px 0;  
97 - padding: 0 1px;  
98 - }  
99 - 91 + border-width: 1px 0;
  92 + padding: 0 1px;
  93 +}
  94 +
100 .fc-header .fc-state-default, 95 .fc-header .fc-state-default,
101 .fc-header .fc-state-default a { 96 .fc-header .fc-state-default a {
102 - border-style: solid;  
103 - }  
104 - 97 + border-style: solid;
  98 +}
  99 +
105 .fc-header .fc-state-default a { 100 .fc-header .fc-state-default a {
106 - display: block;  
107 - border-width: 0 1px;  
108 - margin: 0 -1px;  
109 - width: 100%;  
110 - text-decoration: none;  
111 - }  
112 - 101 + display: block;
  102 + border-width: 0 1px;
  103 + margin: 0 -1px;
  104 + width: 100%;
  105 + text-decoration: none;
  106 +}
  107 +
113 .fc-header .fc-state-default span { 108 .fc-header .fc-state-default span {
114 - display: block;  
115 - border-style: solid;  
116 - border-width: 1px 0 1px 1px;  
117 - padding: 3px 5px;  
118 - }  
119 - 109 + display: block;
  110 + border-style: solid;
  111 + border-width: 1px 0 1px 1px;
  112 + padding: 3px 5px;
  113 +}
  114 +
120 .fc-header .ui-state-default { 115 .fc-header .ui-state-default {
121 - padding: 4px 6px;  
122 - }  
123 - 116 + padding: 4px 6px;
  117 +}
  118 +
124 .fc-header .fc-state-default span, 119 .fc-header .fc-state-default span,
125 .fc-header .ui-state-default span { 120 .fc-header .ui-state-default span {
126 - white-space: nowrap;  
127 - }  
128 - 121 + white-space: nowrap;
  122 +}
  123 +
129 /* for adjacent buttons */ 124 /* for adjacent buttons */
130 - 125 +
131 .fc-header .fc-no-right { 126 .fc-header .fc-no-right {
132 - padding-right: 0;  
133 - }  
134 - 127 + padding-right: 0;
  128 +}
  129 +
135 .fc-header .fc-no-right a { 130 .fc-header .fc-no-right a {
136 - margin-right: 0;  
137 - border-right: 0;  
138 - }  
139 - 131 + margin-right: 0;
  132 + border-right: 0;
  133 +}
  134 +
140 .fc-header .ui-no-right { 135 .fc-header .ui-no-right {
141 - border-right: 0;  
142 - }  
143 - 136 + border-right: 0;
  137 +}
  138 +
144 /* for fake rounded corners */ 139 /* for fake rounded corners */
145 - 140 +
146 .fc-header .fc-corner-left { 141 .fc-header .fc-corner-left {
147 - margin-left: 1px;  
148 - padding-left: 0;  
149 - }  
150 - 142 + margin-left: 1px;
  143 + padding-left: 0;
  144 +}
  145 +
151 .fc-header .fc-corner-right { 146 .fc-header .fc-corner-right {
152 - margin-right: 1px;  
153 - padding-right: 0;  
154 - }  
155 - 147 + margin-right: 1px;
  148 + padding-right: 0;
  149 +}
  150 +
156 /* DEFAULT button COLORS */ 151 /* DEFAULT button COLORS */
157 - 152 +
158 .fc-header .fc-state-default, 153 .fc-header .fc-state-default,
159 .fc-header .fc-state-default a { 154 .fc-header .fc-state-default a {
160 - border-color: #777; /* outer border */  
161 - color: #333;  
162 - } 155 + border-color: #777; /* outer border */
  156 + color: #333;
  157 +}
163 158
164 .fc-header .fc-state-default span { 159 .fc-header .fc-state-default span {
165 - border-color: #fff #fff #d1d1d1; /* inner border */  
166 - background: #e8e8e8;  
167 - }  
168 - 160 + border-color: #fff #fff #d1d1d1; /* inner border */
  161 + background: #e8e8e8;
  162 +}
  163 +
169 /* PRESSED button COLORS (down and active) */ 164 /* PRESSED button COLORS (down and active) */
170 - 165 +
171 .fc-header .fc-state-active a { 166 .fc-header .fc-state-active a {
172 - color: #fff;  
173 - }  
174 - 167 + color: #fff;
  168 +}
  169 +
175 .fc-header .fc-state-down span, 170 .fc-header .fc-state-down span,
176 .fc-header .fc-state-active span { 171 .fc-header .fc-state-active span {
177 - background: #888;  
178 - border-color: #808080 #808080 #909090; /* inner border */  
179 - }  
180 - 172 + background: #888;
  173 + border-color: #808080 #808080 #909090; /* inner border */
  174 +}
  175 +
181 /* DISABLED button COLORS */ 176 /* DISABLED button COLORS */
182 - 177 +
183 .fc-header .fc-state-disabled a { 178 .fc-header .fc-state-disabled a {
184 - color: #999;  
185 - }  
186 - 179 + color: #999;
  180 +}
  181 +
187 .fc-header .fc-state-disabled, 182 .fc-header .fc-state-disabled,
188 .fc-header .fc-state-disabled a { 183 .fc-header .fc-state-disabled a {
189 - border-color: #ccc; /* outer border */  
190 - }  
191 - 184 + border-color: #ccc; /* outer border */
  185 +}
  186 +
192 .fc-header .fc-state-disabled span { 187 .fc-header .fc-state-disabled span {
193 - border-color: #fff #fff #f0f0f0; /* inner border */  
194 - background: #f0f0f0;  
195 - }  
196 -  
197 -  
198 - 188 + border-color: #fff #fff #f0f0f0; /* inner border */
  189 + background: #f0f0f0;
  190 +}
  191 +
199 /* Content Area & Global Cell Styles 192 /* Content Area & Global Cell Styles
200 ------------------------------------------------------------------------*/ 193 ------------------------------------------------------------------------*/
201 - 194 +
202 .fc-widget-content { 195 .fc-widget-content {
203 - border: 1px solid #ccc; /* outer border color */  
204 - }  
205 - 196 + border: 1px solid #ccc; /* outer border color */
  197 +}
  198 +
206 .fc-content { 199 .fc-content {
207 - clear: both;  
208 - }  
209 - 200 + clear: both;
  201 +}
  202 +
210 .fc-content .fc-state-default { 203 .fc-content .fc-state-default {
211 - border-style: solid;  
212 - border-color: #ccc; /* inner border color */  
213 - }  
214 -  
215 -.fc-content .fc-state-highlight { /* today */  
216 - background: #ffc;  
217 - }  
218 - 204 + border-style: solid;
  205 + border-color: #ccc; /* inner border color */
  206 +}
  207 +
  208 +.fc-content .fc-state-highlight {
  209 +/* today */
  210 + background: #ffc;
  211 +}
  212 +
219 .fc-content .fc-not-today { 213 .fc-content .fc-not-today {
220 - background: none;  
221 - }  
222 -  
223 -.fc-cell-overlay { /* semi-transparent rectangle while dragging */  
224 - background: #9cf;  
225 - opacity: .2;  
226 - filter: alpha(opacity=20); /* for IE */  
227 - }  
228 -  
229 -.fc-view { /* prevents dragging outside of widget */  
230 - width: 100%;  
231 - overflow: hidden;  
232 - }  
233 -  
234 -  
235 - 214 + background: none;
  215 +}
  216 +
  217 +.fc-cell-overlay {
  218 +/* semi-transparent rectangle while dragging */
  219 + background: #9cf;
  220 + opacity: .2;
  221 + filter: alpha(opacity = 20); /* for IE */
  222 +}
  223 +
  224 +.fc-view {
  225 +/* prevents dragging outside of widget */
  226 + width: 100%;
  227 + overflow: hidden;
  228 +}
  229 +
236 /* Global Event Styles 230 /* Global Event Styles
237 ------------------------------------------------------------------------*/ 231 ------------------------------------------------------------------------*/
238 232
239 .fc-event, 233 .fc-event,
240 .fc-agenda .fc-event-time, 234 .fc-agenda .fc-event-time,
241 .fc-event a { 235 .fc-event a {
242 - border-style: solid;  
243 - border-color: #36c; /* default BORDER color (probably the same as background-color) */  
244 - background-color: #36c; /* default BACKGROUND color */  
245 - color: #fff; /* default TEXT color */  
246 - }  
247 -  
248 - /* Use the 'className' CalEvent property and the following  
249 - * example CSS to change event color on a per-event basis:  
250 - *  
251 - * .myclass,  
252 - * .fc-agenda .myclass .fc-event-time,  
253 - * .myclass a {  
254 - * background-color: black;  
255 - * border-color: black;  
256 - * color: red;  
257 - * }  
258 - */  
259 - 236 + border-style: solid;
  237 + border-color: #36c; /* default BORDER color (probably the same as background-color) */
  238 + background-color: #36c; /* default BACKGROUND color */
  239 + color: #fff; /* default TEXT color */
  240 +}
  241 +
  242 +/* Use the 'className' CalEvent property and the following
  243 + * example CSS to change event color on a per-event basis:
  244 + *
  245 + * .myclass,
  246 + * .fc-agenda .myclass .fc-event-time,
  247 + * .myclass a {
  248 + * background-color: black;
  249 + * border-color: black;
  250 + * color: red;
  251 + * }
  252 + */
  253 +
260 .fc-event { 254 .fc-event {
261 - text-align: left;  
262 - }  
263 - 255 + text-align: left;
  256 +}
  257 +
264 .fc-event a { 258 .fc-event a {
265 - overflow: hidden;  
266 - font-size: .85em;  
267 - text-decoration: none;  
268 - cursor: pointer;  
269 - }  
270 - 259 + overflow: hidden;
  260 + font-size: .85em;
  261 + text-decoration: none;
  262 + cursor: pointer;
  263 +}
  264 +
271 .fc-event-editable { 265 .fc-event-editable {
272 - cursor: pointer;  
273 - }  
274 - 266 + cursor: pointer;
  267 +}
  268 +
275 .fc-event-time, 269 .fc-event-time,
276 .fc-event-title { 270 .fc-event-title {
277 - padding: 0 1px;  
278 - }  
279 - 271 + padding: 0 1px;
  272 +}
  273 +
280 /* for fake rounded corners */ 274 /* for fake rounded corners */
281 275
282 .fc-event a { 276 .fc-event a {
283 - display: block;  
284 - position: relative;  
285 - width: 100%;  
286 - height: 100%;  
287 - }  
288 - 277 + display: block;
  278 + position: relative;
  279 + width: 100%;
  280 + height: 100%;
  281 +}
  282 +
289 /* right-to-left */ 283 /* right-to-left */
290 284
291 .fc-rtl .fc-event a { 285 .fc-rtl .fc-event a {
292 - text-align: right;  
293 - }  
294 - 286 + text-align: right;
  287 +}
  288 +
295 /* resizable */ 289 /* resizable */
296 - 290 +
297 .fc .ui-resizable-handle { 291 .fc .ui-resizable-handle {
298 - display: block;  
299 - position: absolute;  
300 - z-index: 99999;  
301 - border: 0 !important; /* important overrides pre jquery ui 1.7 styles */  
302 - background: url(data:image/gif;base64,AAAA) !important; /* hover fix for IE */  
303 - }  
304 -  
305 -  
306 - 292 + display: block;
  293 + position: absolute;
  294 + z-index: 99999;
  295 + border: 0 !important; /* important overrides pre jquery ui 1.7 styles */
  296 + background: url(data:image/gif;base64,AAAA) !important; /* hover fix for IE */
  297 +}
  298 +
307 /* Horizontal Events 299 /* Horizontal Events
308 ------------------------------------------------------------------------*/ 300 ------------------------------------------------------------------------*/
309 301
310 .fc-event-hori { 302 .fc-event-hori {
311 - border-width: 1px 0;  
312 - margin-bottom: 1px;  
313 - }  
314 - 303 + border-width: 1px 0;
  304 + margin-bottom: 1px;
  305 +}
  306 +
315 .fc-event-hori a { 307 .fc-event-hori a {
316 - border-width: 0;  
317 - }  
318 - 308 + border-width: 0;
  309 +}
  310 +
319 /* for fake rounded corners */ 311 /* for fake rounded corners */
320 - 312 +
321 .fc-content .fc-corner-left { 313 .fc-content .fc-corner-left {
322 - margin-left: 1px;  
323 - }  
324 - 314 + margin-left: 1px;
  315 +}
  316 +
325 .fc-content .fc-corner-left a { 317 .fc-content .fc-corner-left a {
326 - margin-left: -1px;  
327 - border-left-width: 1px;  
328 - }  
329 - 318 + margin-left: -1px;
  319 + border-left-width: 1px;
  320 +}
  321 +
330 .fc-content .fc-corner-right { 322 .fc-content .fc-corner-right {
331 - margin-right: 1px;  
332 - }  
333 - 323 + margin-right: 1px;
  324 +}
  325 +
334 .fc-content .fc-corner-right a { 326 .fc-content .fc-corner-right a {
335 - margin-right: -1px;  
336 - border-right-width: 1px;  
337 - }  
338 - 327 + margin-right: -1px;
  328 + border-right-width: 1px;
  329 +}
  330 +
339 /* resizable */ 331 /* resizable */
340 - 332 +
341 .fc-event-hori .ui-resizable-e { 333 .fc-event-hori .ui-resizable-e {
342 - top: 0 !important; /* importants override pre jquery ui 1.7 styles */  
343 - right: -3px !important;  
344 - width: 7px !important;  
345 - height: 100% !important;  
346 - cursor: e-resize;  
347 - }  
348 - 334 + top: 0 !important; /* importants override pre jquery ui 1.7 styles */
  335 + right: -3px !important;
  336 + width: 7px !important;
  337 + height: 100% !important;
  338 + cursor: e-resize;
  339 +}
  340 +
349 .fc-event-hori .ui-resizable-w { 341 .fc-event-hori .ui-resizable-w {
350 - top: 0 !important;  
351 - left: -3px !important;  
352 - width: 7px !important;  
353 - height: 100% !important;  
354 - cursor: w-resize;  
355 - }  
356 - 342 + top: 0 !important;
  343 + left: -3px !important;
  344 + width: 7px !important;
  345 + height: 100% !important;
  346 + cursor: w-resize;
  347 +}
  348 +
357 .fc-event-hori .ui-resizable-handle { 349 .fc-event-hori .ui-resizable-handle {
358 - _padding-bottom: 14px; /* IE6 had 0 height */  
359 - }  
360 -  
361 - 350 + _padding-bottom: 14px; /* IE6 had 0 height */
  351 +}
362 352
363 /* Month View, Basic Week View, Basic Day View 353 /* Month View, Basic Week View, Basic Day View
364 ------------------------------------------------------------------------*/ 354 ------------------------------------------------------------------------*/
365 355
366 .fc-grid table { 356 .fc-grid table {
367 - width: 100%;  
368 - }  
369 - 357 + width: 100%;
  358 +}
  359 +
370 .fc .fc-grid th { 360 .fc .fc-grid th {
371 - border-width: 0 0 0 1px;  
372 - text-align: center;  
373 - }  
374 - 361 + border-width: 0 0 0 1px;
  362 + text-align: center;
  363 +}
  364 +
375 .fc .fc-grid td { 365 .fc .fc-grid td {
376 - border-width: 1px 0 0 1px;  
377 - }  
378 - 366 + border-width: 1px 0 0 1px;
  367 +}
  368 +
379 .fc-grid th.fc-leftmost, 369 .fc-grid th.fc-leftmost,
380 .fc-grid td.fc-leftmost { 370 .fc-grid td.fc-leftmost {
381 - border-left: 0;  
382 - }  
383 - 371 + border-left: 0;
  372 +}
  373 +
384 .fc-grid .fc-day-number { 374 .fc-grid .fc-day-number {
385 - float: right;  
386 - padding: 0 2px;  
387 - }  
388 - 375 + float: right;
  376 + padding: 0 2px;
  377 +}
  378 +
389 .fc-grid .fc-other-month .fc-day-number { 379 .fc-grid .fc-other-month .fc-day-number {
390 - opacity: 0.3;  
391 - filter: alpha(opacity=30); /* for IE */  
392 - /* opacity with small font can sometimes look too faded  
393 - might want to set the 'color' property instead  
394 - making day-numbers bold also fixes the problem */  
395 - }  
396 - 380 + opacity: 0.3;
  381 + filter: alpha(opacity = 30); /* for IE */
  382 + /* opacity with small font can sometimes look too faded
  383 + might want to set the 'color' property instead
  384 + making day-numbers bold also fixes the problem */
  385 +}
  386 +
397 .fc-grid .fc-day-content { 387 .fc-grid .fc-day-content {
398 - clear: both;  
399 - padding: 2px 2px 0; /* distance between events and day edges */  
400 - }  
401 - 388 + clear: both;
  389 + padding: 2px 2px 0; /* distance between events and day edges */
  390 +}
  391 +
402 /* event styles */ 392 /* event styles */
403 - 393 +
404 .fc-grid .fc-event-time { 394 .fc-grid .fc-event-time {
405 - font-weight: bold;  
406 - }  
407 - 395 + font-weight: bold;
  396 +}
  397 +
408 /* right-to-left */ 398 /* right-to-left */
409 399
410 .fc-rtl .fc-grid { 400 .fc-rtl .fc-grid {
411 - direction: rtl;  
412 - }  
413 - 401 + direction: rtl;
  402 +}
  403 +
414 .fc-rtl .fc-grid .fc-day-number { 404 .fc-rtl .fc-grid .fc-day-number {
415 - float: left;  
416 - }  
417 - 405 + float: left;
  406 +}
  407 +
418 .fc-rtl .fc-grid .fc-event-time { 408 .fc-rtl .fc-grid .fc-event-time {
419 - float: right;  
420 - }  
421 - 409 + float: right;
  410 +}
  411 +
422 /* Agenda Week View, Agenda Day View 412 /* Agenda Week View, Agenda Day View
423 ------------------------------------------------------------------------*/ 413 ------------------------------------------------------------------------*/
424 414
425 .fc .fc-agenda th, 415 .fc .fc-agenda th,
426 .fc .fc-agenda td { 416 .fc .fc-agenda td {
427 - border-width: 1px 0 0 1px;  
428 - }  
429 - 417 + border-width: 1px 0 0 1px;
  418 +}
  419 +
430 .fc .fc-agenda .fc-leftmost { 420 .fc .fc-agenda .fc-leftmost {
431 - border-left: 0;  
432 - }  
433 - 421 + border-left: 0;
  422 +}
  423 +
434 .fc-agenda tr.fc-first th, 424 .fc-agenda tr.fc-first th,
435 .fc-agenda tr.fc-first td { 425 .fc-agenda tr.fc-first td {
436 - border-top: 0;  
437 - }  
438 - 426 + border-top: 0;
  427 +}
  428 +
439 .fc-agenda-head tr.fc-last th { 429 .fc-agenda-head tr.fc-last th {
440 - border-bottom-width: 1px;  
441 - }  
442 - 430 + border-bottom-width: 1px;
  431 +}
  432 +
443 .fc .fc-agenda-head td, 433 .fc .fc-agenda-head td,
444 .fc .fc-agenda-body td { 434 .fc .fc-agenda-body td {
445 - background: none;  
446 - }  
447 - 435 + background: none;
  436 +}
  437 +
448 .fc-agenda-head th { 438 .fc-agenda-head th {
449 - text-align: center;  
450 - }  
451 - 439 + text-align: center;
  440 +}
  441 +
452 /* the time axis running down the left side */ 442 /* the time axis running down the left side */
453 - 443 +
454 .fc-agenda .fc-axis { 444 .fc-agenda .fc-axis {
455 - width: 50px;  
456 - padding: 0 4px;  
457 - vertical-align: middle;  
458 - white-space: nowrap;  
459 - text-align: right;  
460 - font-weight: normal;  
461 - }  
462 - 445 + width: 50px;
  446 + padding: 0 4px;
  447 + vertical-align: middle;
  448 + white-space: nowrap;
  449 + text-align: right;
  450 + font-weight: normal;
  451 +}
  452 +
463 /* all-day event cells at top */ 453 /* all-day event cells at top */
464 - 454 +
465 .fc-agenda-head tr.fc-all-day th { 455 .fc-agenda-head tr.fc-all-day th {
466 - height: 35px;  
467 - }  
468 - 456 + height: 35px;
  457 +}
  458 +
469 .fc-agenda-head td { 459 .fc-agenda-head td {
470 - padding-bottom: 10px;  
471 - }  
472 - 460 + padding-bottom: 10px;
  461 +}
  462 +
473 .fc .fc-divider div { 463 .fc .fc-divider div {
474 - font-size: 1px; /* for IE6/7 */  
475 - height: 2px;  
476 - }  
477 - 464 + font-size: 1px; /* for IE6/7 */
  465 + height: 2px;
  466 +}
  467 +
478 .fc .fc-divider .fc-state-default { 468 .fc .fc-divider .fc-state-default {
479 - background: #eee; /* color for divider between all-day and time-slot events */  
480 - } 469 + background: #eee; /* color for divider between all-day and time-slot events */
  470 +}
481 471
482 /* body styles */ 472 /* body styles */
483 - 473 +
484 .fc .fc-agenda-body td div { 474 .fc .fc-agenda-body td div {
485 - height: 20px; /* slot height */  
486 - }  
487 - 475 + height: 20px; /* slot height */
  476 +}
  477 +
488 .fc .fc-agenda-body tr.fc-minor th, 478 .fc .fc-agenda-body tr.fc-minor th,
489 .fc .fc-agenda-body tr.fc-minor td { 479 .fc .fc-agenda-body tr.fc-minor td {
490 - border-top-style: dotted;  
491 - }  
492 -  
493 -.fc-agenda .fc-day-content {  
494 - padding: 2px 2px 0; /* distance between events and day edges */  
495 - }  
496 - 480 + border-top-style: dotted;
  481 +}
497 482
  483 +.fc-agenda .fc-day-content {
  484 + padding: 2px 2px 0; /* distance between events and day edges */
  485 +}
498 486
499 /* Vertical Events 487 /* Vertical Events
500 ------------------------------------------------------------------------*/ 488 ------------------------------------------------------------------------*/
501 489
502 .fc-event-vert { 490 .fc-event-vert {
503 - border-width: 0 1px;  
504 - }  
505 - 491 + border-width: 0 1px;
  492 +}
  493 +
506 .fc-event-vert a { 494 .fc-event-vert a {
507 - border-width: 0;  
508 - }  
509 - 495 + border-width: 0;
  496 +}
  497 +
510 /* for fake rounded corners */ 498 /* for fake rounded corners */
511 - 499 +
512 .fc-content .fc-corner-top { 500 .fc-content .fc-corner-top {
513 - margin-top: 1px;  
514 - }  
515 - 501 + margin-top: 1px;
  502 +}
  503 +
516 .fc-content .fc-corner-top a { 504 .fc-content .fc-corner-top a {
517 - margin-top: -1px;  
518 - border-top-width: 1px;  
519 - }  
520 - 505 + margin-top: -1px;
  506 + border-top-width: 1px;
  507 +}
  508 +
521 .fc-content .fc-corner-bottom { 509 .fc-content .fc-corner-bottom {
522 - margin-bottom: 1px;  
523 - }  
524 - 510 + margin-bottom: 1px;
  511 +}
  512 +
525 .fc-content .fc-corner-bottom a { 513 .fc-content .fc-corner-bottom a {
526 - margin-bottom: -1px;  
527 - border-bottom-width: 1px;  
528 - }  
529 - 514 + margin-bottom: -1px;
  515 + border-bottom-width: 1px;
  516 +}
  517 +
530 /* event content */ 518 /* event content */
531 - 519 +
532 .fc-event-vert span { 520 .fc-event-vert span {
533 - display: block;  
534 - position: relative;  
535 - z-index: 2;  
536 - }  
537 - 521 + display: block;
  522 + position: relative;
  523 + z-index: 2;
  524 +}
  525 +
538 .fc-event-vert span.fc-event-time { 526 .fc-event-vert span.fc-event-time {
539 - white-space: nowrap;  
540 - _white-space: normal;  
541 - overflow: hidden;  
542 - border: 0;  
543 - font-size: 10px;  
544 - }  
545 - 527 + white-space: nowrap;
  528 + _white-space: normal;
  529 + overflow: hidden;
  530 + border: 0;
  531 + font-size: 10px;
  532 +}
  533 +
546 .fc-event-vert span.fc-event-title { 534 .fc-event-vert span.fc-event-title {
547 - line-height: 13px;  
548 - }  
549 -  
550 -.fc-event-vert span.fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */  
551 - position: absolute;  
552 - z-index: 1;  
553 - top: 0;  
554 - left: 0;  
555 - width: 100%;  
556 - height: 100%;  
557 - background: #fff;  
558 - opacity: .3;  
559 - filter: alpha(opacity=30); /* for IE */  
560 - }  
561 - 535 + line-height: 13px;
  536 +}
  537 +
  538 +.fc-event-vert span.fc-event-bg {
  539 +/* makes the event lighter w/ a semi-transparent overlay */
  540 + position: absolute;
  541 + z-index: 1;
  542 + top: 0;
  543 + left: 0;
  544 + width: 100%;
  545 + height: 100%;
  546 + background: #fff;
  547 + opacity: .3;
  548 + filter: alpha(opacity = 30); /* for IE */
  549 +}
  550 +
562 /* resizable */ 551 /* resizable */
563 - 552 +
564 .fc-event-vert .ui-resizable-s { 553 .fc-event-vert .ui-resizable-s {
565 - bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */  
566 - width: 100% !important;  
567 - height: 8px !important;  
568 - line-height: 8px !important;  
569 - font-size: 11px !important;  
570 - font-family: monospace;  
571 - text-align: center;  
572 - cursor: s-resize;  
573 - } 554 + bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */
  555 + width: 100% !important;
  556 + height: 8px !important;
  557 + line-height: 8px !important;
  558 + font-size: 11px !important;
  559 + font-family: monospace;
  560 + text-align: center;
  561 + cursor: s-resize;
  562 +}
574 563
575 564
@@ -12,60 +12,60 @@ @@ -12,60 +12,60 @@
12 12
13 (function($) { 13 (function($) {
14 14
15 - $.fullCalendar.gcalFeed = function(feedUrl, options) {  
16 -  
17 - feedUrl = feedUrl.replace(/\/basic$/, '/full');  
18 - options = options || {};  
19 -  
20 - return function(start, end, callback) {  
21 - var params = {  
22 - 'start-min': $.fullCalendar.formatDate(start, 'u'),  
23 - 'start-max': $.fullCalendar.formatDate(end, 'u'),  
24 - 'singleevents': true,  
25 - 'max-results': 9999  
26 - };  
27 - var ctz = options.currentTimezone;  
28 - if (ctz) {  
29 - params.ctz = ctz = ctz.replace(' ', '_');  
30 - }  
31 - $.getJSON(feedUrl + "?alt=json-in-script&callback=?", params, function(data) {  
32 - var events = [];  
33 - if (data.feed.entry) {  
34 - $.each(data.feed.entry, function(i, entry) {  
35 - var startStr = entry['gd$when'][0]['startTime'],  
36 - start = $.fullCalendar.parseISO8601(startStr, true),  
37 - end = $.fullCalendar.parseISO8601(entry['gd$when'][0]['endTime'], true),  
38 - allDay = startStr.indexOf('T') == -1,  
39 - url;  
40 - $.each(entry.link, function() {  
41 - if (this.type == 'text/html') {  
42 - url = this.href;  
43 - if (ctz) {  
44 - url += (url.indexOf('?') == -1 ? '?' : '&') + 'ctz=' + ctz;  
45 - }  
46 - }  
47 - });  
48 - if (allDay) {  
49 - $.fullCalendar.addDays(end, -1); // make inclusive  
50 - }  
51 - events.push({  
52 - id: entry['gCal$uid']['value'],  
53 - title: entry['title']['$t'],  
54 - url: url,  
55 - start: start,  
56 - end: end,  
57 - allDay: allDay,  
58 - location: entry['gd$where'][0]['valueString'],  
59 - description: entry['content']['$t'],  
60 - className: options.className,  
61 - editable: options.editable || false  
62 - });  
63 - });  
64 - }  
65 - callback(events);  
66 - });  
67 - }  
68 -  
69 - } 15 + $.fullCalendar.gcalFeed = function(feedUrl, options) {
  16 +
  17 + feedUrl = feedUrl.replace(/\/basic$/, '/full');
  18 + options = options || {};
  19 +
  20 + return function(start, end, callback) {
  21 + var params = {
  22 + 'start-min': $.fullCalendar.formatDate(start, 'u'),
  23 + 'start-max': $.fullCalendar.formatDate(end, 'u'),
  24 + 'singleevents': true,
  25 + 'max-results': 9999
  26 + };
  27 + var ctz = options.currentTimezone;
  28 + if (ctz) {
  29 + params.ctz = ctz = ctz.replace(' ', '_');
  30 + }
  31 + $.getJSON(feedUrl + "?alt=json-in-script&callback=?", params, function(data) {
  32 + var events = [];
  33 + if (data.feed.entry) {
  34 + $.each(data.feed.entry, function(i, entry) {
  35 + var startStr = entry['gd$when'][0]['startTime'],
  36 + start = $.fullCalendar.parseISO8601(startStr, true),
  37 + end = $.fullCalendar.parseISO8601(entry['gd$when'][0]['endTime'], true),
  38 + allDay = startStr.indexOf('T') == -1,
  39 + url;
  40 + $.each(entry.link, function() {
  41 + if (this.type == 'text/html') {
  42 + url = this.href;
  43 + if (ctz) {
  44 + url += (url.indexOf('?') == -1 ? '?' : '&') + 'ctz=' + ctz;
  45 + }
  46 + }
  47 + });
  48 + if (allDay) {
  49 + $.fullCalendar.addDays(end, -1); // make inclusive
  50 + }
  51 + events.push({
  52 + id: entry['gCal$uid']['value'],
  53 + title: entry['title']['$t'],
  54 + url: url,
  55 + start: start,
  56 + end: end,
  57 + allDay: allDay,
  58 + location: entry['gd$where'][0]['valueString'],
  59 + description: entry['content']['$t'],
  60 + className: options.className,
  61 + editable: options.editable || false
  62 + });
  63 + });
  64 + }
  65 + callback(events);
  66 + });
  67 + }
  68 +
  69 + }
70 70
71 })(jQuery); 71 })(jQuery);
@@ -41,6 +41,12 @@ window.RichFaces.Schedule = (function() { @@ -41,6 +41,12 @@ window.RichFaces.Schedule = (function() {
41 return; 41 return;
42 } 42 }
43 } 43 }
  44 + if (options.onDateRangeChanged != null) {
  45 + RichFaces.Schedule.eval("(function(){" + options.onDateRangeChanged + "})()", {
  46 + 'startDate':startDate,
  47 + 'endDate':endDate
  48 + });
  49 + }
44 if (_this.submitEventFunction != null) { 50 if (_this.submitEventFunction != null) {
45 _this.submitEventFunction({} /* stub event */, 51 _this.submitEventFunction({} /* stub event */,
46 null, 52 null,
@@ -54,32 +60,58 @@ window.RichFaces.Schedule = (function() { @@ -54,32 +60,58 @@ window.RichFaces.Schedule = (function() {
54 if (scheduleData != undefined) { 60 if (scheduleData != undefined) {
55 callback(scheduleData); 61 callback(scheduleData);
56 } 62 }
  63 + if (options.onDateRangeChangedComplete != null) {
  64 + RichFaces.Schedule.eval("(function(){" + options.onDateRangeChangedComplete + "})()", {
  65 + 'startDate':startDate,
  66 + 'endDate':endDate,
  67 + 'request':request,
  68 + 'data':data,
  69 + 'items':scheduleData
  70 + });
  71 + }
57 } 72 }
58 ); 73 );
59 } 74 }
60 }; 75 };
61 - var itemDragStart = function(item, event) { 76 + var itemDragStart = function(item, event, ui, view) {
62 if (options.onItemDragStart != null) { 77 if (options.onItemDragStart != null) {
63 - eval("(function(){" + options.onItemDragStart + "})()"); 78 + RichFaces.Schedule.eval("(function(){" + options.onItemDragStart + "})()", {
  79 + 'item':item,
  80 + 'event':event,
  81 + 'ui':ui,
  82 + 'view':view
  83 + });
64 } 84 }
65 }; 85 };
66 - var itemDragStop = function(item, event) { 86 + var itemDragStop = function(item, event, ui, view) {
67 if (options.onItemDragStop != null) { 87 if (options.onItemDragStop != null) {
68 - eval("(function(){" + options.onItemDragStop + "})()"); 88 + RichFaces.Schedule.eval("(function(){" + options.onItemDragStop + "})()", {
  89 + 'item':item,
  90 + 'event':event,
  91 + 'ui':ui,
  92 + 'view':view
  93 + });
69 } 94 }
70 }; 95 };
71 - var itemDrop = function(item, dayDelta, minuteDelta, allDay, revertFunc, event) { 96 + var itemDrop = function(item, dayDelta, minuteDelta, allDay, revertFunc, event, ui, view) {
  97 + var result;
72 if (options.onItemDrop != null) { 98 if (options.onItemDrop != null) {
73 - var result = eval("(function(){" + options.onItemDrop + "})()");  
74 - if (result != null) {  
75 - if (result === false) {  
76 - revertFunc();  
77 - } 99 + result = RichFaces.Schedule.eval("(function(){" + options.onItemDrop + "})()", {
  100 + 'item':item,
  101 + 'dayDelta':dayDelta,
  102 + 'minuteDelta':minuteDelta,
  103 + 'allDay':allDay,
  104 + 'event':event,
  105 + 'ui':ui,
  106 + 'view':view
  107 + });
  108 + if (result === false) {
  109 + revertFunc();
78 return; 110 return;
79 } 111 }
80 } 112 }
81 if (_this.submitEventFunction != null) { 113 if (_this.submitEventFunction != null) {
82 - _this.submitEventFunction({} /* stub event */, 114 + _this.submitEventFunction(event,
83 null, 115 null,
84 itemMovedEventName, 116 itemMovedEventName,
85 item.id, 117 item.id,
@@ -87,25 +119,49 @@ window.RichFaces.Schedule = (function() { @@ -87,25 +119,49 @@ window.RichFaces.Schedule = (function() {
87 null, 119 null,
88 dayDelta, minuteDelta, allDay, 120 dayDelta, minuteDelta, allDay,
89 function(request, event, data) { 121 function(request, event, data) {
90 - if (data != undefined && data !== true) { 122 + var decision = request.getJSON('_ajax:scheduleData');
  123 + var vetoed = false;
  124 + if (decision != undefined && decision !== true) {
91 revertFunc(); 125 revertFunc();
  126 + vetoed = true;
  127 + }
  128 + if (options.onItemDropComplete != null) {
  129 + RichFaces.Schedule.eval("(function(){" + options.onItemDropComplete + "})()", {
  130 + 'item':item,
  131 + 'dayDelta':dayDelta,
  132 + 'minuteDelta':minuteDelta,
  133 + 'allDay':allDay,
  134 + 'event':event,
  135 + 'ui':ui,
  136 + 'view':view,
  137 + 'request':request,
  138 + 'data':data,
  139 + 'vetoed':vetoed
  140 + });
92 } 141 }
93 } 142 }
94 ); 143 );
95 } 144 }
  145 + return;
96 }; 146 };
97 - var itemResized = function(item, dayDelta, minuteDelta, revertFunc, event) { 147 + var itemResized = function(item, dayDelta, minuteDelta, revertFunc, event, ui, view) {
  148 + var result;
98 if (options.onItemResized != null) { 149 if (options.onItemResized != null) {
99 - var result = eval("(function(){" + options.onItemResized + "})()");  
100 - if (result != null) {  
101 - if (result === false) {  
102 - revertFunc();  
103 - } 150 + result = RichFaces.Schedule.eval("(function(){" + options.onItemResized + "})()", {
  151 + 'item':item,
  152 + 'dayDelta':dayDelta,
  153 + 'minuteDelta':minuteDelta,
  154 + 'event':event,
  155 + 'ui':ui,
  156 + 'view':view
  157 + });
  158 + if (result === false) {
  159 + revertFunc();
104 return; 160 return;
105 } 161 }
106 } 162 }
107 if (_this.submitEventFunction != null) { 163 if (_this.submitEventFunction != null) {
108 - _this.submitEventFunction({} /* stub event */, 164 + _this.submitEventFunction(event,
109 null, 165 null,
110 itemResizedEventName, 166 itemResizedEventName,
111 item.id, 167 item.id,
@@ -113,93 +169,181 @@ window.RichFaces.Schedule = (function() { @@ -113,93 +169,181 @@ window.RichFaces.Schedule = (function() {
113 null, 169 null,
114 dayDelta, minuteDelta, null, 170 dayDelta, minuteDelta, null,
115 function(request, event, data) { 171 function(request, event, data) {
116 - if (data != undefined && data !== true) { 172 + var decision = request.getJSON('_ajax:scheduleData');
  173 + var vetoed = false;
  174 + if (decision != undefined && decision !== true) {
117 revertFunc(); 175 revertFunc();
  176 + vetoed = true;
  177 + }
  178 + if (options.onItemResizedComplete != null) {
  179 + RichFaces.Schedule.eval("(function(){" + options.onItemResizedComplete + "})()", {
  180 + 'item':item,
  181 + 'dayDelta':dayDelta,
  182 + 'minuteDelta':minuteDelta,
  183 + 'event':event,
  184 + 'ui':ui,
  185 + 'view':view,
  186 + 'request':request,
  187 + 'data':data,
  188 + 'vetoed':vetoed
  189 + });
118 } 190 }
119 } 191 }
120 ); 192 );
121 } 193 }
122 }; 194 };
123 - var itemResizeStart = function(item, event) { 195 + var itemResizeStart = function(item, event, ui, view) {
124 if (options.onItemResizeStart != null) { 196 if (options.onItemResizeStart != null) {
125 - eval("(function(){" + options.onItemResizeStart + "})()"); 197 + RichFaces.Schedule.eval("(function(){" + options.onItemResizeStart + "})()", {
  198 + 'item':item,
  199 + 'event':event,
  200 + 'ui':ui,
  201 + 'view':view
  202 + });
126 } 203 }
127 }; 204 };
128 - var itemResizeStop = function(item, event) { 205 + var itemResizeStop = function(item, event, ui, view) {
129 if (options.onItemResizeStop != null) { 206 if (options.onItemResizeStop != null) {
130 - eval("(function(){" + options.onItemResizeStop + "})()"); 207 + RichFaces.Schedule.eval("(function(){" + options.onItemResizeStop + "})()", {
  208 + 'item':item,
  209 + 'event':event,
  210 + 'ui':ui,
  211 + 'view':view
  212 + });
131 } 213 }
132 }; 214 };
133 - var itemMouseover = function(item) { 215 + var itemMouseover = function(item, event, view) {
134 if (options.onItemMouseover != null) { 216 if (options.onItemMouseover != null) {
135 - eval("(function(){" + options.onItemMouseover + "})()"); 217 + RichFaces.Schedule.eval("(function(){" + options.onItemMouseover + "})()", {
  218 + 'item':item,
  219 + 'event':event,
  220 + 'view':view
  221 + });
136 } 222 }
137 }; 223 };
138 - var itemMouseout = function(item) { 224 + var itemMouseout = function(item, event, view) {
139 if (options.onItemMouseout != null) { 225 if (options.onItemMouseout != null) {
140 - eval("(function(){" + options.onItemMouseout + "})()"); 226 + RichFaces.Schedule.eval("(function(){" + options.onItemMouseout + "})()", {
  227 + 'item':item,
  228 + 'event':event,
  229 + 'view':view
  230 + });
141 } 231 }
142 }; 232 };
143 - var itemClick = function(item, event) { 233 + var itemClick = function(item, event, view) {
  234 + var result;
144 if (options.onItemSelected != null) { 235 if (options.onItemSelected != null) {
145 - var result = eval("(function(){" + options.onItemSelected + "})()");  
146 - if (result != null) {  
147 - return;  
148 - } 236 + result = RichFaces.Schedule.eval("(function(){" + options.onItemSelected + "})()", {
  237 + 'item':item,
  238 + 'event':event,
  239 + 'view':view
  240 + });
  241 + }
  242 + if (result === false) {
  243 + return false;
149 } 244 }
150 if (_this.submitEventFunction != null) { 245 if (_this.submitEventFunction != null) {
151 - _this.submitEventFunction({}, 246 + _this.submitEventFunction(event,
152 null, 247 null,
153 itemSelectedEventName, 248 itemSelectedEventName,
154 item.id, 249 item.id,
155 - null, null, null, null, null, null 250 + null, null, null, null, null, function(request, event, data) {
  251 + if (options.onItemSelectedComplete != null) {
  252 + RichFaces.Schedule.eval("(function(){" + options.onItemSelectedComplete + "})()", {
  253 + 'item':item,
  254 + 'event':event,
  255 + 'view':view,
  256 + 'request':request,
  257 + 'data':data
  258 + });
  259 + }
  260 + }
156 ); 261 );
157 } 262 }
  263 + return result;
158 }; 264 };
159 - var dayClick = function(date, allDay, event) { 265 + var dayClick = function(date, allDay, event, view) {
  266 + var result;
160 if (options.onDateSelected != null) { 267 if (options.onDateSelected != null) {
161 - var result = eval("(function(){" + options.onDateSelected + "})()");  
162 - if (result != null) {  
163 - throw "return not allowed in onDaySelect";  
164 - } 268 + result = RichFaces.Schedule.eval("(function(){" + options.onDateSelected + "})()", {
  269 + 'date':date,
  270 + 'allDay':allDay,
  271 + 'event':event,
  272 + 'view':view
  273 + });
  274 + }
  275 + if (result === false) {
  276 + return false;
165 } 277 }
166 if (_this.submitEventFunction != null) { 278 if (_this.submitEventFunction != null) {
167 - _this.submitEventFunction({}, 279 + _this.submitEventFunction(event,
168 null, 280 null,
169 daySelectedEventName, 281 daySelectedEventName,
170 - null, formatDateParam(date), null, null, null, allDay, null 282 + null, formatDateParam(date), null, null, null, allDay, function(request, event, data) {
  283 + if (options.onDateSelectedComplete != null) {
  284 + RichFaces.Schedule.eval("(function(){" + options.onDateSelectedComplete + "})()", {
  285 + 'date':date,
  286 + 'allDay':allDay,
  287 + 'request':request,
  288 + 'event':event,
  289 + 'view':view,
  290 + 'data':data
  291 + });
  292 + }
  293 + }
171 ); 294 );
172 } 295 }
  296 + return result;
173 }; 297 };
174 var selectedView; 298 var selectedView;
175 - //TODO how to hide all (except for view param) scopeChain from code in options.onViewDisplay?  
176 - var viewDisplay = function(view) {  
177 - if (options.onViewDisplay != null) {  
178 - var result = eval("(function(){" + options.onViewDisplay + "})()");  
179 - if (result != null) {  
180 - throw "return not allowed in onViewDisplay";  
181 - }  
182 - } 299 + var viewChanged = function(view) {
183 if (selectedView != view && selectedView != undefined) { 300 if (selectedView != view && selectedView != undefined) {
  301 + if (options.onViewChanged != null) {
  302 + RichFaces.Schedule.eval("(function(){" + options.onViewChanged + "})()", {
  303 + 'view':view
  304 + });
  305 + }
184 if (_this.submitEventFunction != null) { 306 if (_this.submitEventFunction != null) {
185 _this.submitEventFunction({}, 307 _this.submitEventFunction({},
186 view.name, 308 view.name,
187 viewChangedEventName, 309 viewChangedEventName,
188 - null, null, null, null, null, null, null 310 + null, null, null, null, null, null, function(request, event, data) {
  311 + if (options.onViewChangedComplete != null) {
  312 + RichFaces.Schedule.eval("(function(){" + options.onViewChangedComplete + "})()", {
  313 + 'view':view,
  314 + 'request':request,
  315 + 'data':data
  316 + });
  317 + }
  318 + }
189 ); 319 );
190 } 320 }
191 } 321 }
192 selectedView = view; 322 selectedView = view;
193 }; 323 };
194 - var onDateRangeSelected = function(startDate, endDate, allDay) { 324 + var onDateRangeSelected = function(startDate, endDate, allDay, view) {
195 if (!component.fullCalendar('option', 'selectable')) { 325 if (!component.fullCalendar('option', 'selectable')) {
196 - return; 326 + return false;
197 } 327 }
  328 + var result;
198 if (options.onDateRangeSelected != null) { 329 if (options.onDateRangeSelected != null) {
199 - var result = eval("(function(){" + options.onDateRangeSelected + "})()");  
200 - if (result != null) {  
201 - return;  
202 - } 330 + result = RichFaces.Schedule.eval("(function(){" + options.onDateRangeSelected + "})()", {
  331 + 'startDate':startDate,
  332 + 'endDate':endDate,
  333 + 'allDay':allDay,
  334 + 'view':view
  335 + });
  336 + }
  337 + if (result === false) {
  338 + /**
  339 + * Unselect must be in all three places below in order to
  340 + * avoid situation where, while event is being sent via ajax
  341 + * to server, client side selection disapeares.
  342 + * Current implementation shortens delay between selection
  343 + * disapearing and potentialy created event appearing.
  344 + */
  345 + component.fullCalendar('unselect');
  346 + return false;
203 } 347 }
204 if (_this.submitEventFunction != null) { 348 if (_this.submitEventFunction != null) {
205 _this.submitEventFunction({}, 349 _this.submitEventFunction({},
@@ -209,11 +353,22 @@ window.RichFaces.Schedule = (function() { @@ -209,11 +353,22 @@ window.RichFaces.Schedule = (function() {
209 function(request, event, data) { 353 function(request, event, data) {
210 component.fullCalendar('refetchEvents'); 354 component.fullCalendar('refetchEvents');
211 component.fullCalendar('unselect'); 355 component.fullCalendar('unselect');
  356 + if (options.onDateRangeSelected != null) {
  357 + RichFaces.Schedule.eval("(function(){" + options.onDateRangeSelectedComplete + "})()", {
  358 + 'startDate':startDate,
  359 + 'endDate':endDate,
  360 + 'allDay':allDay,
  361 + 'view':view,
  362 + 'request':request,
  363 + 'data':data
  364 + });
  365 + }
212 } 366 }
213 ); 367 );
214 } else { 368 } else {
215 component.fullCalendar('unselect'); 369 component.fullCalendar('unselect');
216 } 370 }
  371 + return result;
217 }; 372 };
218 options = jQuery.extend({ 373 options = jQuery.extend({
219 events: fillCalendarFunction, 374 events: fillCalendarFunction,
@@ -226,14 +381,26 @@ window.RichFaces.Schedule = (function() { @@ -226,14 +381,26 @@ window.RichFaces.Schedule = (function() {
226 eventClick: itemClick, 381 eventClick: itemClick,
227 eventMouseover: itemMouseover, 382 eventMouseover: itemMouseover,
228 eventMouseout: itemMouseout, 383 eventMouseout: itemMouseout,
229 - viewDisplay: viewDisplay, 384 + viewDisplay: viewChanged,
230 dayClick: dayClick, 385 dayClick: dayClick,
231 select: onDateRangeSelected 386 select: onDateRangeSelected
232 }, options); 387 }, options);
233 jQuery(document).ready(function() { 388 jQuery(document).ready(function() {
234 component = jQuery(elt).fullCalendar(options); 389 component = jQuery(elt).fullCalendar(options);
  390 + elt.component = _this;
  391 + _this.component = component;
235 }); 392 });
236 }; 393 };
237 394
238 }()); 395 }());
239 -window.RichFaces.Schedule.prototype.messages = {};  
  396 +window.RichFaces.Schedule.prototype.refetchItems = function() {
  397 + this.component.fullCalendar('refetchEvents');
  398 +};
  399 +window.RichFaces.Schedule.prototype.messages = {};
  400 +window.RichFaces.Schedule.eval = function(template, object) {
  401 + var value = '';
  402 + with (object) {
  403 + value = eval(template);
  404 + }
  405 + return value;
  406 +};
@@ -7,513 +7,530 @@ @@ -7,513 +7,530 @@
7 * 7 *
8 * http://docs.jquery.com/UI 8 * http://docs.jquery.com/UI
9 */ 9 */
10 -;jQuery.ui || (function($) {  
11 -  
12 -var _remove = $.fn.remove,  
13 - isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);  
14 -  
15 -//Helper functions and ui object  
16 -$.ui = {  
17 - version: "1.7.2",  
18 -  
19 - // $.ui.plugin is deprecated. Use the proxy pattern instead.  
20 - plugin: {  
21 - add: function(module, option, set) {  
22 - var proto = $.ui[module].prototype;  
23 - for(var i in set) {  
24 - proto.plugins[i] = proto.plugins[i] || [];  
25 - proto.plugins[i].push([option, set[i]]);  
26 - }  
27 - },  
28 - call: function(instance, name, args) {  
29 - var set = instance.plugins[name];  
30 - if(!set || !instance.element[0].parentNode) { return; }  
31 -  
32 - for (var i = 0; i < set.length; i++) {  
33 - if (instance.options[set[i][0]]) {  
34 - set[i][1].apply(instance.element, args);  
35 - }  
36 - }  
37 - }  
38 - },  
39 -  
40 - contains: function(a, b) {  
41 - return document.compareDocumentPosition  
42 - ? a.compareDocumentPosition(b) & 16  
43 - : a !== b && a.contains(b);  
44 - },  
45 -  
46 - hasScroll: function(el, a) {  
47 -  
48 - //If overflow is hidden, the element might have extra content, but the user wants to hide it  
49 - if ($(el).css('overflow') == 'hidden') { return false; }  
50 -  
51 - var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',  
52 - has = false;  
53 -  
54 - if (el[scroll] > 0) { return true; }  
55 -  
56 - // TODO: determine which cases actually cause this to happen  
57 - // if the element doesn't have the scroll set, see if it's possible to  
58 - // set the scroll  
59 - el[scroll] = 1;  
60 - has = (el[scroll] > 0);  
61 - el[scroll] = 0;  
62 - return has;  
63 - },  
64 -  
65 - isOverAxis: function(x, reference, size) {  
66 - //Determines when x coordinate is over "b" element axis  
67 - return (x > reference) && (x < (reference + size));  
68 - },  
69 -  
70 - isOver: function(y, x, top, left, height, width) {  
71 - //Determines when x, y coordinates is over "b" element  
72 - return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);  
73 - },  
74 -  
75 - keyCode: {  
76 - BACKSPACE: 8,  
77 - CAPS_LOCK: 20,  
78 - COMMA: 188,  
79 - CONTROL: 17,  
80 - DELETE: 46,  
81 - DOWN: 40,  
82 - END: 35,  
83 - ENTER: 13,  
84 - ESCAPE: 27,  
85 - HOME: 36,  
86 - INSERT: 45,  
87 - LEFT: 37,  
88 - NUMPAD_ADD: 107,  
89 - NUMPAD_DECIMAL: 110,  
90 - NUMPAD_DIVIDE: 111,  
91 - NUMPAD_ENTER: 108,  
92 - NUMPAD_MULTIPLY: 106,  
93 - NUMPAD_SUBTRACT: 109,  
94 - PAGE_DOWN: 34,  
95 - PAGE_UP: 33,  
96 - PERIOD: 190,  
97 - RIGHT: 39,  
98 - SHIFT: 16,  
99 - SPACE: 32,  
100 - TAB: 9,  
101 - UP: 38  
102 - }  
103 -};  
104 -  
105 -// WAI-ARIA normalization  
106 -if (isFF2) {  
107 - var attr = $.attr,  
108 - removeAttr = $.fn.removeAttr,  
109 - ariaNS = "http://www.w3.org/2005/07/aaa",  
110 - ariaState = /^aria-/,  
111 - ariaRole = /^wairole:/;  
112 -  
113 - $.attr = function(elem, name, value) {  
114 - var set = value !== undefined;  
115 -  
116 - return (name == 'role'  
117 - ? (set  
118 - ? attr.call(this, elem, name, "wairole:" + value)  
119 - : (attr.apply(this, arguments) || "").replace(ariaRole, ""))  
120 - : (ariaState.test(name)  
121 - ? (set  
122 - ? elem.setAttributeNS(ariaNS,  
123 - name.replace(ariaState, "aaa:"), value)  
124 - : attr.call(this, elem, name.replace(ariaState, "aaa:")))  
125 - : attr.apply(this, arguments)));  
126 - };  
127 -  
128 - $.fn.removeAttr = function(name) {  
129 - return (ariaState.test(name)  
130 - ? this.each(function() {  
131 - this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));  
132 - }) : removeAttr.call(this, name));  
133 - };  
134 -}  
135 -  
136 -//jQuery plugins  
137 -$.fn.extend({  
138 - remove: function() {  
139 - // Safari has a native remove event which actually removes DOM elements,  
140 - // so we have to use triggerHandler instead of trigger (#3037).  
141 - $("*", this).add(this).each(function() {  
142 - $(this).triggerHandler("remove");  
143 - });  
144 - return _remove.apply(this, arguments );  
145 - },  
146 -  
147 - enableSelection: function() {  
148 - return this  
149 - .attr('unselectable', 'off')  
150 - .css('MozUserSelect', '')  
151 - .unbind('selectstart.ui');  
152 - },  
153 -  
154 - disableSelection: function() {  
155 - return this  
156 - .attr('unselectable', 'on')  
157 - .css('MozUserSelect', 'none')  
158 - .bind('selectstart.ui', function() { return false; });  
159 - },  
160 -  
161 - scrollParent: function() {  
162 - var scrollParent;  
163 - if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {  
164 - scrollParent = this.parents().filter(function() {  
165 - return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));  
166 - }).eq(0);  
167 - } else {  
168 - scrollParent = this.parents().filter(function() {  
169 - return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));  
170 - }).eq(0);  
171 - }  
172 -  
173 - return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;  
174 - }  
175 -});  
176 -  
177 -  
178 -//Additional selectors  
179 -$.extend($.expr[':'], {  
180 - data: function(elem, i, match) {  
181 - return !!$.data(elem, match[3]);  
182 - },  
183 -  
184 - focusable: function(element) {  
185 - var nodeName = element.nodeName.toLowerCase(),  
186 - tabIndex = $.attr(element, 'tabindex');  
187 - return (/input|select|textarea|button|object/.test(nodeName)  
188 - ? !element.disabled  
189 - : 'a' == nodeName || 'area' == nodeName  
190 - ? element.href || !isNaN(tabIndex)  
191 - : !isNaN(tabIndex))  
192 - // the element and all of its ancestors must be visible  
193 - // the browser may report that the area is hidden  
194 - && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;  
195 - },  
196 -  
197 - tabbable: function(element) {  
198 - var tabIndex = $.attr(element, 'tabindex');  
199 - return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');  
200 - }  
201 -});  
202 -  
203 -  
204 -// $.widget is a factory to create jQuery plugins  
205 -// taking some boilerplate code out of the plugin code  
206 -function getter(namespace, plugin, method, args) {  
207 - function getMethods(type) {  
208 - var methods = $[namespace][plugin][type] || [];  
209 - return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);  
210 - }  
211 -  
212 - var methods = getMethods('getter');  
213 - if (args.length == 1 && typeof args[0] == 'string') {  
214 - methods = methods.concat(getMethods('getterSetter'));  
215 - }  
216 - return ($.inArray(method, methods) != -1);  
217 -}  
218 -  
219 -$.widget = function(name, prototype) {  
220 - var namespace = name.split(".")[0];  
221 - name = name.split(".")[1];  
222 -  
223 - // create plugin method  
224 - $.fn[name] = function(options) {  
225 - var isMethodCall = (typeof options == 'string'),  
226 - args = Array.prototype.slice.call(arguments, 1);  
227 -  
228 - // prevent calls to internal methods  
229 - if (isMethodCall && options.substring(0, 1) == '_') {  
230 - return this;  
231 - }  
232 -  
233 - // handle getter methods  
234 - if (isMethodCall && getter(namespace, name, options, args)) {  
235 - var instance = $.data(this[0], name);  
236 - return (instance ? instance[options].apply(instance, args)  
237 - : undefined);  
238 - }  
239 -  
240 - // handle initialization and non-getter methods  
241 - return this.each(function() {  
242 - var instance = $.data(this, name);  
243 -  
244 - // constructor  
245 - (!instance && !isMethodCall &&  
246 - $.data(this, name, new $[namespace][name](this, options))._init());  
247 -  
248 - // method call  
249 - (instance && isMethodCall && $.isFunction(instance[options]) &&  
250 - instance[options].apply(instance, args));  
251 - });  
252 - };  
253 -  
254 - // create widget constructor  
255 - $[namespace] = $[namespace] || {};  
256 - $[namespace][name] = function(element, options) {  
257 - var self = this;  
258 -  
259 - this.namespace = namespace;  
260 - this.widgetName = name;  
261 - this.widgetEventPrefix = $[namespace][name].eventPrefix || name;  
262 - this.widgetBaseClass = namespace + '-' + name;  
263 -  
264 - this.options = $.extend({},  
265 - $.widget.defaults,  
266 - $[namespace][name].defaults,  
267 - $.metadata && $.metadata.get(element)[name],  
268 - options);  
269 -  
270 - this.element = $(element)  
271 - .bind('setData.' + name, function(event, key, value) {  
272 - if (event.target == element) {  
273 - return self._setData(key, value);  
274 - }  
275 - })  
276 - .bind('getData.' + name, function(event, key) {  
277 - if (event.target == element) {  
278 - return self._getData(key);  
279 - }  
280 - })  
281 - .bind('remove', function() {  
282 - return self.destroy();  
283 - });  
284 - };  
285 -  
286 - // add widget prototype  
287 - $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);  
288 -  
289 - // TODO: merge getter and getterSetter properties from widget prototype  
290 - // and plugin prototype  
291 - $[namespace][name].getterSetter = 'option';  
292 -};  
293 -  
294 -$.widget.prototype = {  
295 - _init: function() {},  
296 - destroy: function() {  
297 - this.element.removeData(this.widgetName)  
298 - .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')  
299 - .removeAttr('aria-disabled');  
300 - },  
301 -  
302 - option: function(key, value) {  
303 - var options = key,  
304 - self = this;  
305 -  
306 - if (typeof key == "string") {  
307 - if (value === undefined) {  
308 - return this._getData(key);  
309 - }  
310 - options = {};  
311 - options[key] = value;  
312 - }  
313 -  
314 - $.each(options, function(key, value) {  
315 - self._setData(key, value);  
316 - });  
317 - },  
318 - _getData: function(key) {  
319 - return this.options[key];  
320 - },  
321 - _setData: function(key, value) {  
322 - this.options[key] = value;  
323 -  
324 - if (key == 'disabled') {  
325 - this.element  
326 - [value ? 'addClass' : 'removeClass'](  
327 - this.widgetBaseClass + '-disabled' + ' ' +  
328 - this.namespace + '-state-disabled')  
329 - .attr("aria-disabled", value);  
330 - }  
331 - },  
332 -  
333 - enable: function() {  
334 - this._setData('disabled', false);  
335 - },  
336 - disable: function() {  
337 - this._setData('disabled', true);  
338 - },  
339 -  
340 - _trigger: function(type, event, data) {  
341 - var callback = this.options[type],  
342 - eventName = (type == this.widgetEventPrefix  
343 - ? type : this.widgetEventPrefix + type);  
344 -  
345 - event = $.Event(event);  
346 - event.type = eventName;  
347 -  
348 - // copy original event properties over to the new event  
349 - // this would happen if we could call $.event.fix instead of $.Event  
350 - // but we don't have a way to force an event to be fixed multiple times  
351 - if (event.originalEvent) {  
352 - for (var i = $.event.props.length, prop; i;) {  
353 - prop = $.event.props[--i];  
354 - event[prop] = event.originalEvent[prop];  
355 - }  
356 - }  
357 -  
358 - this.element.trigger(event, data);  
359 -  
360 - return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false  
361 - || event.isDefaultPrevented());  
362 - }  
363 -};  
364 -  
365 -$.widget.defaults = {  
366 - disabled: false  
367 -};  
368 -  
369 -  
370 -/** Mouse Interaction Plugin **/  
371 -  
372 -$.ui.mouse = {  
373 - _mouseInit: function() {  
374 - var self = this;  
375 -  
376 - this.element  
377 - .bind('mousedown.'+this.widgetName, function(event) {  
378 - return self._mouseDown(event);  
379 - })  
380 - .bind('click.'+this.widgetName, function(event) {  
381 - if(self._preventClickEvent) {  
382 - self._preventClickEvent = false;  
383 - event.stopImmediatePropagation();  
384 - return false;  
385 - }  
386 - });  
387 -  
388 - // Prevent text selection in IE  
389 - if ($.browser.msie) {  
390 - this._mouseUnselectable = this.element.attr('unselectable');  
391 - this.element.attr('unselectable', 'on');  
392 - }  
393 -  
394 - this.started = false;  
395 - },  
396 -  
397 - // TODO: make sure destroying one instance of mouse doesn't mess with  
398 - // other instances of mouse  
399 - _mouseDestroy: function() {  
400 - this.element.unbind('.'+this.widgetName);  
401 -  
402 - // Restore text selection in IE  
403 - ($.browser.msie  
404 - && this.element.attr('unselectable', this._mouseUnselectable));  
405 - },  
406 -  
407 - _mouseDown: function(event) {  
408 - // don't let more than one widget handle mouseStart  
409 - // TODO: figure out why we have to use originalEvent  
410 - event.originalEvent = event.originalEvent || {};  
411 - if (event.originalEvent.mouseHandled) { return; }  
412 -  
413 - // we may have missed mouseup (out of window)  
414 - (this._mouseStarted && this._mouseUp(event));  
415 -  
416 - this._mouseDownEvent = event;  
417 -  
418 - var self = this,  
419 - btnIsLeft = (event.which == 1),  
420 - elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);  
421 - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {  
422 - return true;  
423 - }  
424 -  
425 - this.mouseDelayMet = !this.options.delay;  
426 - if (!this.mouseDelayMet) {  
427 - this._mouseDelayTimer = setTimeout(function() {  
428 - self.mouseDelayMet = true;  
429 - }, this.options.delay);  
430 - }  
431 -  
432 - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {  
433 - this._mouseStarted = (this._mouseStart(event) !== false);  
434 - if (!this._mouseStarted) {  
435 - event.preventDefault();  
436 - return true;  
437 - }  
438 - }  
439 -  
440 - // these delegates are required to keep context  
441 - this._mouseMoveDelegate = function(event) {  
442 - return self._mouseMove(event);  
443 - };  
444 - this._mouseUpDelegate = function(event) {  
445 - return self._mouseUp(event);  
446 - };  
447 - $(document)  
448 - .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)  
449 - .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);  
450 -  
451 - // preventDefault() is used to prevent the selection of text here -  
452 - // however, in Safari, this causes select boxes not to be selectable  
453 - // anymore, so this fix is needed  
454 - ($.browser.safari || event.preventDefault());  
455 -  
456 - event.originalEvent.mouseHandled = true;  
457 - return true;  
458 - },  
459 -  
460 - _mouseMove: function(event) {  
461 - // IE mouseup check - mouseup happened when mouse was out of window  
462 - if ($.browser.msie && !event.button) {  
463 - return this._mouseUp(event);  
464 - }  
465 -  
466 - if (this._mouseStarted) {  
467 - this._mouseDrag(event);  
468 - return event.preventDefault();  
469 - }  
470 -  
471 - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {  
472 - this._mouseStarted =  
473 - (this._mouseStart(this._mouseDownEvent, event) !== false);  
474 - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));  
475 - }  
476 -  
477 - return !this._mouseStarted;  
478 - },  
479 -  
480 - _mouseUp: function(event) {  
481 - $(document)  
482 - .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)  
483 - .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);  
484 -  
485 - if (this._mouseStarted) {  
486 - this._mouseStarted = false;  
487 - this._preventClickEvent = (event.target == this._mouseDownEvent.target);  
488 - this._mouseStop(event);  
489 - }  
490 -  
491 - return false;  
492 - },  
493 -  
494 - _mouseDistanceMet: function(event) {  
495 - return (Math.max(  
496 - Math.abs(this._mouseDownEvent.pageX - event.pageX),  
497 - Math.abs(this._mouseDownEvent.pageY - event.pageY)  
498 - ) >= this.options.distance  
499 - );  
500 - },  
501 -  
502 - _mouseDelayMet: function(event) {  
503 - return this.mouseDelayMet;  
504 - },  
505 -  
506 - // These are placeholder methods, to be overriden by extending plugin  
507 - _mouseStart: function(event) {},  
508 - _mouseDrag: function(event) {},  
509 - _mouseStop: function(event) {},  
510 - _mouseCapture: function(event) { return true; }  
511 -};  
512 -  
513 -$.ui.mouse.defaults = {  
514 - cancel: null,  
515 - distance: 1,  
516 - delay: 0  
517 -}; 10 +;
  11 +jQuery.ui || (function($) {
  12 +
  13 + var _remove = $.fn.remove,
  14 + isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
  15 +
  16 + //Helper functions and ui object
  17 + $.ui = {
  18 + version: "1.7.2",
  19 +
  20 + // $.ui.plugin is deprecated. Use the proxy pattern instead.
  21 + plugin: {
  22 + add: function(module, option, set) {
  23 + var proto = $.ui[module].prototype;
  24 + for (var i in set) {
  25 + proto.plugins[i] = proto.plugins[i] || [];
  26 + proto.plugins[i].push([option, set[i]]);
  27 + }
  28 + },
  29 + call: function(instance, name, args) {
  30 + var set = instance.plugins[name];
  31 + if (!set || !instance.element[0].parentNode) {
  32 + return;
  33 + }
  34 +
  35 + for (var i = 0; i < set.length; i++) {
  36 + if (instance.options[set[i][0]]) {
  37 + set[i][1].apply(instance.element, args);
  38 + }
  39 + }
  40 + }
  41 + },
  42 +
  43 + contains: function(a, b) {
  44 + return document.compareDocumentPosition
  45 + ? a.compareDocumentPosition(b) & 16
  46 + : a !== b && a.contains(b);
  47 + },
  48 +
  49 + hasScroll: function(el, a) {
  50 +
  51 + //If overflow is hidden, the element might have extra content, but the user wants to hide it
  52 + if ($(el).css('overflow') == 'hidden') {
  53 + return false;
  54 + }
  55 +
  56 + var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
  57 + has = false;
  58 +
  59 + if (el[scroll] > 0) {
  60 + return true;
  61 + }
  62 +
  63 + // TODO: determine which cases actually cause this to happen
  64 + // if the element doesn't have the scroll set, see if it's possible to
  65 + // set the scroll
  66 + el[scroll] = 1;
  67 + has = (el[scroll] > 0);
  68 + el[scroll] = 0;
  69 + return has;
  70 + },
  71 +
  72 + isOverAxis: function(x, reference, size) {
  73 + //Determines when x coordinate is over "b" element axis
  74 + return (x > reference) && (x < (reference + size));
  75 + },
  76 +
  77 + isOver: function(y, x, top, left, height, width) {
  78 + //Determines when x, y coordinates is over "b" element
  79 + return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
  80 + },
  81 +
  82 + keyCode: {
  83 + BACKSPACE: 8,
  84 + CAPS_LOCK: 20,
  85 + COMMA: 188,
  86 + CONTROL: 17,
  87 + DELETE: 46,
  88 + DOWN: 40,
  89 + END: 35,
  90 + ENTER: 13,
  91 + ESCAPE: 27,
  92 + HOME: 36,
  93 + INSERT: 45,
  94 + LEFT: 37,
  95 + NUMPAD_ADD: 107,
  96 + NUMPAD_DECIMAL: 110,
  97 + NUMPAD_DIVIDE: 111,
  98 + NUMPAD_ENTER: 108,
  99 + NUMPAD_MULTIPLY: 106,
  100 + NUMPAD_SUBTRACT: 109,
  101 + PAGE_DOWN: 34,
  102 + PAGE_UP: 33,
  103 + PERIOD: 190,
  104 + RIGHT: 39,
  105 + SHIFT: 16,
  106 + SPACE: 32,
  107 + TAB: 9,
  108 + UP: 38
  109 + }
  110 + };
  111 +
  112 + // WAI-ARIA normalization
  113 + if (isFF2) {
  114 + var attr = $.attr,
  115 + removeAttr = $.fn.removeAttr,
  116 + ariaNS = "http://www.w3.org/2005/07/aaa",
  117 + ariaState = /^aria-/,
  118 + ariaRole = /^wairole:/;
  119 +
  120 + $.attr = function(elem, name, value) {
  121 + var set = value !== undefined;
  122 +
  123 + return (name == 'role'
  124 + ? (set
  125 + ? attr.call(this, elem, name, "wairole:" + value)
  126 + : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
  127 + : (ariaState.test(name)
  128 + ? (set
  129 + ? elem.setAttributeNS(ariaNS,
  130 + name.replace(ariaState, "aaa:"), value)
  131 + : attr.call(this, elem, name.replace(ariaState, "aaa:")))
  132 + : attr.apply(this, arguments)));
  133 + };
  134 +
  135 + $.fn.removeAttr = function(name) {
  136 + return (ariaState.test(name)
  137 + ? this.each(function() {
  138 + this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
  139 + }) : removeAttr.call(this, name));
  140 + };
  141 + }
  142 +
  143 + //jQuery plugins
  144 + $.fn.extend({
  145 + remove: function() {
  146 + // Safari has a native remove event which actually removes DOM elements,
  147 + // so we have to use triggerHandler instead of trigger (#3037).
  148 + $("*", this).add(this).each(function() {
  149 + $(this).triggerHandler("remove");
  150 + });
  151 + return _remove.apply(this, arguments);
  152 + },
  153 +
  154 + enableSelection: function() {
  155 + return this
  156 + .attr('unselectable', 'off')
  157 + .css('MozUserSelect', '')
  158 + .unbind('selectstart.ui');
  159 + },
  160 +
  161 + disableSelection: function() {
  162 + return this
  163 + .attr('unselectable', 'on')
  164 + .css('MozUserSelect', 'none')
  165 + .bind('selectstart.ui', function() {
  166 + return false;
  167 + });
  168 + },
  169 +
  170 + scrollParent: function() {
  171 + var scrollParent;
  172 + if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
  173 + scrollParent = this.parents().filter(function() {
  174 + return (/(relative|absolute|fixed)/).test($.curCSS(this, 'position', 1)) && (/(auto|scroll)/).test($.curCSS(this, 'overflow', 1) + $.curCSS(this, 'overflow-y', 1) + $.curCSS(this, 'overflow-x', 1));
  175 + }).eq(0);
  176 + } else {
  177 + scrollParent = this.parents().filter(function() {
  178 + return (/(auto|scroll)/).test($.curCSS(this, 'overflow', 1) + $.curCSS(this, 'overflow-y', 1) + $.curCSS(this, 'overflow-x', 1));
  179 + }).eq(0);
  180 + }
  181 +
  182 + return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
  183 + }
  184 + });
  185 +
  186 +
  187 + //Additional selectors
  188 + $.extend($.expr[':'], {
  189 + data: function(elem, i, match) {
  190 + return !!$.data(elem, match[3]);
  191 + },
  192 +
  193 + focusable: function(element) {
  194 + var nodeName = element.nodeName.toLowerCase(),
  195 + tabIndex = $.attr(element, 'tabindex');
  196 + return (/input|select|textarea|button|object/.test(nodeName)
  197 + ? !element.disabled
  198 + : 'a' == nodeName || 'area' == nodeName
  199 + ? element.href || !isNaN(tabIndex)
  200 + : !isNaN(tabIndex))
  201 + // the element and all of its ancestors must be visible
  202 + // the browser may report that the area is hidden
  203 + && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
  204 + },
  205 +
  206 + tabbable: function(element) {
  207 + var tabIndex = $.attr(element, 'tabindex');
  208 + return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
  209 + }
  210 + });
  211 +
  212 +
  213 + // $.widget is a factory to create jQuery plugins
  214 + // taking some boilerplate code out of the plugin code
  215 + function getter(namespace, plugin, method, args) {
  216 + function getMethods(type) {
  217 + var methods = $[namespace][plugin][type] || [];
  218 + return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
  219 + }
  220 +
  221 + var methods = getMethods('getter');
  222 + if (args.length == 1 && typeof args[0] == 'string') {
  223 + methods = methods.concat(getMethods('getterSetter'));
  224 + }
  225 + return ($.inArray(method, methods) != -1);
  226 + }
  227 +
  228 + $.widget = function(name, prototype) {
  229 + var namespace = name.split(".")[0];
  230 + name = name.split(".")[1];
  231 +
  232 + // create plugin method
  233 + $.fn[name] = function(options) {
  234 + var isMethodCall = (typeof options == 'string'),
  235 + args = Array.prototype.slice.call(arguments, 1);
  236 +
  237 + // prevent calls to internal methods
  238 + if (isMethodCall && options.substring(0, 1) == '_') {
  239 + return this;
  240 + }
  241 +
  242 + // handle getter methods
  243 + if (isMethodCall && getter(namespace, name, options, args)) {
  244 + var instance = $.data(this[0], name);
  245 + return (instance ? instance[options].apply(instance, args)
  246 + : undefined);
  247 + }
  248 +
  249 + // handle initialization and non-getter methods
  250 + return this.each(function() {
  251 + var instance = $.data(this, name);
  252 +
  253 + // constructor
  254 + (!instance && !isMethodCall &&
  255 + $.data(this, name, new $[namespace][name](this, options))._init());
  256 +
  257 + // method call
  258 + (instance && isMethodCall && $.isFunction(instance[options]) &&
  259 + instance[options].apply(instance, args));
  260 + });
  261 + };
  262 +
  263 + // create widget constructor
  264 + $[namespace] = $[namespace] || {};
  265 + $[namespace][name] = function(element, options) {
  266 + var self = this;
  267 +
  268 + this.namespace = namespace;
  269 + this.widgetName = name;
  270 + this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
  271 + this.widgetBaseClass = namespace + '-' + name;
  272 +
  273 + this.options = $.extend({},
  274 + $.widget.defaults,
  275 + $[namespace][name].defaults,
  276 + $.metadata && $.metadata.get(element)[name],
  277 + options);
  278 +
  279 + this.element = $(element)
  280 + .bind('setData.' + name, function(event, key, value) {
  281 + if (event.target == element) {
  282 + return self._setData(key, value);
  283 + }
  284 + })
  285 + .bind('getData.' + name, function(event, key) {
  286 + if (event.target == element) {
  287 + return self._getData(key);
  288 + }
  289 + })
  290 + .bind('remove', function() {
  291 + return self.destroy();
  292 + });
  293 + };
  294 +
  295 + // add widget prototype
  296 + $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
  297 +
  298 + // TODO: merge getter and getterSetter properties from widget prototype
  299 + // and plugin prototype
  300 + $[namespace][name].getterSetter = 'option';
  301 + };
  302 +
  303 + $.widget.prototype = {
  304 + _init: function() {
  305 + },
  306 + destroy: function() {
  307 + this.element.removeData(this.widgetName)
  308 + .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
  309 + .removeAttr('aria-disabled');
  310 + },
  311 +
  312 + option: function(key, value) {
  313 + var options = key,
  314 + self = this;
  315 +
  316 + if (typeof key == "string") {
  317 + if (value === undefined) {
  318 + return this._getData(key);
  319 + }
  320 + options = {};
  321 + options[key] = value;
  322 + }
  323 +
  324 + $.each(options, function(key, value) {
  325 + self._setData(key, value);
  326 + });
  327 + },
  328 + _getData: function(key) {
  329 + return this.options[key];
  330 + },
  331 + _setData: function(key, value) {
  332 + this.options[key] = value;
  333 +
  334 + if (key == 'disabled') {
  335 + this.element
  336 + [value ? 'addClass' : 'removeClass'](
  337 + this.widgetBaseClass + '-disabled' + ' ' +
  338 + this.namespace + '-state-disabled')
  339 + .attr("aria-disabled", value);
  340 + }
  341 + },
  342 +
  343 + enable: function() {
  344 + this._setData('disabled', false);
  345 + },
  346 + disable: function() {
  347 + this._setData('disabled', true);
  348 + },
  349 +
  350 + _trigger: function(type, event, data) {
  351 + var callback = this.options[type],
  352 + eventName = (type == this.widgetEventPrefix
  353 + ? type : this.widgetEventPrefix + type);
  354 +
  355 + event = $.Event(event);
  356 + event.type = eventName;
  357 +
  358 + // copy original event properties over to the new event
  359 + // this would happen if we could call $.event.fix instead of $.Event
  360 + // but we don't have a way to force an event to be fixed multiple times
  361 + if (event.originalEvent) {
  362 + for (var i = $.event.props.length, prop; i;) {
  363 + prop = $.event.props[--i];
  364 + event[prop] = event.originalEvent[prop];
  365 + }
  366 + }
  367 +
  368 + this.element.trigger(event, data);
  369 +
  370 + return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
  371 + || event.isDefaultPrevented());
  372 + }
  373 + };
  374 +
  375 + $.widget.defaults = {
  376 + disabled: false
  377 + };
  378 +
  379 +
  380 + /** Mouse Interaction Plugin **/
  381 +
  382 + $.ui.mouse = {
  383 + _mouseInit: function() {
  384 + var self = this;
  385 +
  386 + this.element
  387 + .bind('mousedown.' + this.widgetName, function(event) {
  388 + return self._mouseDown(event);
  389 + })
  390 + .bind('click.' + this.widgetName, function(event) {
  391 + if (self._preventClickEvent) {
  392 + self._preventClickEvent = false;
  393 + event.stopImmediatePropagation();
  394 + return false;
  395 + }
  396 + });
  397 +
  398 + // Prevent text selection in IE
  399 + if ($.browser.msie) {
  400 + this._mouseUnselectable = this.element.attr('unselectable');
  401 + this.element.attr('unselectable', 'on');
  402 + }
  403 +
  404 + this.started = false;
  405 + },
  406 +
  407 + // TODO: make sure destroying one instance of mouse doesn't mess with
  408 + // other instances of mouse
  409 + _mouseDestroy: function() {
  410 + this.element.unbind('.' + this.widgetName);
  411 +
  412 + // Restore text selection in IE
  413 + ($.browser.msie
  414 + && this.element.attr('unselectable', this._mouseUnselectable));
  415 + },
  416 +
  417 + _mouseDown: function(event) {
  418 + // don't let more than one widget handle mouseStart
  419 + // TODO: figure out why we have to use originalEvent
  420 + event.originalEvent = event.originalEvent || {};
  421 + if (event.originalEvent.mouseHandled) {
  422 + return;
  423 + }
  424 +
  425 + // we may have missed mouseup (out of window)
  426 + (this._mouseStarted && this._mouseUp(event));
  427 +
  428 + this._mouseDownEvent = event;
  429 +
  430 + var self = this,
  431 + btnIsLeft = (event.which == 1),
  432 + elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
  433 + if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
  434 + return true;
  435 + }
  436 +
  437 + this.mouseDelayMet = !this.options.delay;
  438 + if (!this.mouseDelayMet) {
  439 + this._mouseDelayTimer = setTimeout(function() {
  440 + self.mouseDelayMet = true;
  441 + }, this.options.delay);
  442 + }
  443 +
  444 + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  445 + this._mouseStarted = (this._mouseStart(event) !== false);
  446 + if (!this._mouseStarted) {
  447 + event.preventDefault();
  448 + return true;
  449 + }
  450 + }
  451 +
  452 + // these delegates are required to keep context
  453 + this._mouseMoveDelegate = function(event) {
  454 + return self._mouseMove(event);
  455 + };
  456 + this._mouseUpDelegate = function(event) {
  457 + return self._mouseUp(event);
  458 + };
  459 + $(document)
  460 + .bind('mousemove.' + this.widgetName, this._mouseMoveDelegate)
  461 + .bind('mouseup.' + this.widgetName, this._mouseUpDelegate);
  462 +
  463 + // preventDefault() is used to prevent the selection of text here -
  464 + // however, in Safari, this causes select boxes not to be selectable
  465 + // anymore, so this fix is needed
  466 + ($.browser.safari || event.preventDefault());
  467 +
  468 + event.originalEvent.mouseHandled = true;
  469 + return true;
  470 + },
  471 +
  472 + _mouseMove: function(event) {
  473 + // IE mouseup check - mouseup happened when mouse was out of window
  474 + if ($.browser.msie && !event.button) {
  475 + return this._mouseUp(event);
  476 + }
  477 +
  478 + if (this._mouseStarted) {
  479 + this._mouseDrag(event);
  480 + return event.preventDefault();
  481 + }
  482 +
  483 + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
  484 + this._mouseStarted =
  485 + (this._mouseStart(this._mouseDownEvent, event) !== false);
  486 + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
  487 + }
  488 +
  489 + return !this._mouseStarted;
  490 + },
  491 +
  492 + _mouseUp: function(event) {
  493 + $(document)
  494 + .unbind('mousemove.' + this.widgetName, this._mouseMoveDelegate)
  495 + .unbind('mouseup.' + this.widgetName, this._mouseUpDelegate);
  496 +
  497 + if (this._mouseStarted) {
  498 + this._mouseStarted = false;
  499 + this._preventClickEvent = (event.target == this._mouseDownEvent.target);
  500 + this._mouseStop(event);
  501 + }
  502 +
  503 + return false;
  504 + },
  505 +
  506 + _mouseDistanceMet: function(event) {
  507 + return (Math.max(
  508 + Math.abs(this._mouseDownEvent.pageX - event.pageX),
  509 + Math.abs(this._mouseDownEvent.pageY - event.pageY)
  510 + ) >= this.options.distance
  511 + );
  512 + },
  513 +
  514 + _mouseDelayMet: function(event) {
  515 + return this.mouseDelayMet;
  516 + },
  517 +
  518 + // These are placeholder methods, to be overriden by extending plugin
  519 + _mouseStart: function(event) {
  520 + },
  521 + _mouseDrag: function(event) {
  522 + },
  523 + _mouseStop: function(event) {
  524 + },
  525 + _mouseCapture: function(event) {
  526 + return true;
  527 + }
  528 + };
  529 +
  530 + $.ui.mouse.defaults = {
  531 + cancel: null,
  532 + distance: 1,
  533 + delay: 0
  534 + };
518 535
519 })(jQuery); 536 })(jQuery);
@@ -12,755 +12,763 @@ @@ -12,755 +12,763 @@
12 */ 12 */
13 (function($) { 13 (function($) {
14 14
15 -$.widget("ui.draggable", $.extend({}, $.ui.mouse, { 15 + $.widget("ui.draggable", $.extend({}, $.ui.mouse, {
16 16
17 - _init: function() { 17 + _init: function() {
18 18
19 - if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))  
20 - this.element[0].style.position = 'relative'; 19 + if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
  20 + this.element[0].style.position = 'relative';
21 21
22 - (this.options.addClasses && this.element.addClass("ui-draggable"));  
23 - (this.options.disabled && this.element.addClass("ui-draggable-disabled")); 22 + (this.options.addClasses && this.element.addClass("ui-draggable"));
  23 + (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
24 24
25 - this._mouseInit(); 25 + this._mouseInit();
26 26
27 - }, 27 + },
28 28
29 - destroy: function() {  
30 - if(!this.element.data('draggable')) return;  
31 - this.element  
32 - .removeData("draggable")  
33 - .unbind(".draggable")  
34 - .removeClass("ui-draggable"  
35 - + " ui-draggable-dragging"  
36 - + " ui-draggable-disabled");  
37 - this._mouseDestroy();  
38 - }, 29 + destroy: function() {
  30 + if (!this.element.data('draggable')) return;
  31 + this.element
  32 + .removeData("draggable")
  33 + .unbind(".draggable")
  34 + .removeClass("ui-draggable"
  35 + + " ui-draggable-dragging"
  36 + + " ui-draggable-disabled");
  37 + this._mouseDestroy();
  38 + },
39 39
40 - _mouseCapture: function(event) { 40 + _mouseCapture: function(event) {
41 41
42 - var o = this.options; 42 + var o = this.options;
43 43
44 - if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))  
45 - return false; 44 + if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
  45 + return false;
46 46
47 - //Quit if we're not on a valid handle  
48 - this.handle = this._getHandle(event);  
49 - if (!this.handle)  
50 - return false; 47 + //Quit if we're not on a valid handle
  48 + this.handle = this._getHandle(event);
  49 + if (!this.handle)
  50 + return false;
51 51
52 - return true; 52 + return true;
53 53
54 - }, 54 + },
55 55
56 - _mouseStart: function(event) { 56 + _mouseStart: function(event) {
57 57
58 - var o = this.options; 58 + var o = this.options;
59 59
60 - //Create and append the visible helper  
61 - this.helper = this._createHelper(event); 60 + //Create and append the visible helper
  61 + this.helper = this._createHelper(event);
62 62
63 - //Cache the helper size  
64 - this._cacheHelperProportions(); 63 + //Cache the helper size
  64 + this._cacheHelperProportions();
65 65
66 - //If ddmanager is used for droppables, set the global draggable  
67 - if($.ui.ddmanager)  
68 - $.ui.ddmanager.current = this; 66 + //If ddmanager is used for droppables, set the global draggable
  67 + if ($.ui.ddmanager)
  68 + $.ui.ddmanager.current = this;
69 69
70 - /*  
71 - * - Position generation -  
72 - * This block generates everything position related - it's the core of draggables.  
73 - */ 70 + /*
  71 + * - Position generation -
  72 + * This block generates everything position related - it's the core of draggables.
  73 + */
74 74
75 - //Cache the margins of the original element  
76 - this._cacheMargins(); 75 + //Cache the margins of the original element
  76 + this._cacheMargins();
77 77
78 - //Store the helper's css position  
79 - this.cssPosition = this.helper.css("position");  
80 - this.scrollParent = this.helper.scrollParent(); 78 + //Store the helper's css position
  79 + this.cssPosition = this.helper.css("position");
  80 + this.scrollParent = this.helper.scrollParent();
81 81
82 - //The element's absolute position on the page minus margins  
83 - this.offset = this.element.offset();  
84 - this.offset = {  
85 - top: this.offset.top - this.margins.top,  
86 - left: this.offset.left - this.margins.left  
87 - }; 82 + //The element's absolute position on the page minus margins
  83 + this.offset = this.element.offset();
  84 + this.offset = {
  85 + top: this.offset.top - this.margins.top,
  86 + left: this.offset.left - this.margins.left
  87 + };
88 88
89 - $.extend(this.offset, {  
90 - click: { //Where the click happened, relative to the element  
91 - left: event.pageX - this.offset.left,  
92 - top: event.pageY - this.offset.top  
93 - },  
94 - parent: this._getParentOffset(),  
95 - relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper  
96 - }); 89 + $.extend(this.offset, {
  90 + click: { //Where the click happened, relative to the element
  91 + left: event.pageX - this.offset.left,
  92 + top: event.pageY - this.offset.top
  93 + },
  94 + parent: this._getParentOffset(),
  95 + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
  96 + });
97 97
98 - //Generate the original position  
99 - this.originalPosition = this._generatePosition(event);  
100 - this.originalPageX = event.pageX;  
101 - this.originalPageY = event.pageY; 98 + //Generate the original position
  99 + this.originalPosition = this._generatePosition(event);
  100 + this.originalPageX = event.pageX;
  101 + this.originalPageY = event.pageY;
102 102
103 - //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied  
104 - if(o.cursorAt)  
105 - this._adjustOffsetFromHelper(o.cursorAt); 103 + //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
  104 + if (o.cursorAt)
  105 + this._adjustOffsetFromHelper(o.cursorAt);
106 106
107 - //Set a containment if given in the options  
108 - if(o.containment)  
109 - this._setContainment(); 107 + //Set a containment if given in the options
  108 + if (o.containment)
  109 + this._setContainment();
110 110
111 - //Call plugins and callbacks  
112 - this._trigger("start", event); 111 + //Call plugins and callbacks
  112 + this._trigger("start", event);
113 113
114 - //Recache the helper size  
115 - this._cacheHelperProportions(); 114 + //Recache the helper size
  115 + this._cacheHelperProportions();
116 116
117 - //Prepare the droppable offsets  
118 - if ($.ui.ddmanager && !o.dropBehaviour)  
119 - $.ui.ddmanager.prepareOffsets(this, event); 117 + //Prepare the droppable offsets
  118 + if ($.ui.ddmanager && !o.dropBehaviour)
  119 + $.ui.ddmanager.prepareOffsets(this, event);
120 120
121 - this.helper.addClass("ui-draggable-dragging");  
122 - this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position  
123 - return true;  
124 - }, 121 + this.helper.addClass("ui-draggable-dragging");
  122 + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
  123 + return true;
  124 + },
125 125
126 - _mouseDrag: function(event, noPropagation) { 126 + _mouseDrag: function(event, noPropagation) {
127 127
128 - //Compute the helpers position  
129 - this.position = this._generatePosition(event);  
130 - this.positionAbs = this._convertPositionTo("absolute");  
131 -  
132 - //Call plugins and callbacks and use the resulting position if something is returned  
133 - if (!noPropagation) {  
134 - var ui = this._uiHash();  
135 - this._trigger('drag', event, ui);  
136 - this.position = ui.position;  
137 - } 128 + //Compute the helpers position
  129 + this.position = this._generatePosition(event);
  130 + this.positionAbs = this._convertPositionTo("absolute");
  131 +
  132 + //Call plugins and callbacks and use the resulting position if something is returned
  133 + if (!noPropagation) {
  134 + var ui = this._uiHash();
  135 + this._trigger('drag', event, ui);
  136 + this.position = ui.position;
  137 + }
138 138
139 - if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';  
140 - if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';  
141 - if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); 139 + if (!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left + 'px';
  140 + if (!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top + 'px';
  141 + if ($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
142 142
143 - return false;  
144 - },  
145 -  
146 - _mouseStop: function(event) {  
147 -  
148 - //If we are using droppables, inform the manager about the drop  
149 - var dropped = false;  
150 - if ($.ui.ddmanager && !this.options.dropBehaviour)  
151 - dropped = $.ui.ddmanager.drop(this, event);  
152 -  
153 - //if a drop comes from outside (a sortable)  
154 - if(this.dropped) {  
155 - dropped = this.dropped;  
156 - this.dropped = false;  
157 - }  
158 -  
159 - if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {  
160 - var self = this;  
161 - $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {  
162 - self._trigger("stop", event);  
163 - self._clear();  
164 - });  
165 - } else {  
166 - this._trigger("stop", event);  
167 - this._clear();  
168 - }  
169 -  
170 - return false;  
171 - },  
172 -  
173 - _getHandle: function(event) {  
174 -  
175 - var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;  
176 - $(this.options.handle, this.element)  
177 - .find("*")  
178 - .andSelf()  
179 - .each(function() {  
180 - if(this == event.target) handle = true;  
181 - });  
182 -  
183 - return handle;  
184 -  
185 - },  
186 -  
187 - _createHelper: function(event) {  
188 -  
189 - var o = this.options;  
190 - var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);  
191 -  
192 - if(!helper.parents('body').length)  
193 - helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));  
194 -  
195 - if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))  
196 - helper.css("position", "absolute");  
197 -  
198 - return helper;  
199 -  
200 - },  
201 -  
202 - _adjustOffsetFromHelper: function(obj) {  
203 - if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;  
204 - if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;  
205 - if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;  
206 - if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;  
207 - },  
208 -  
209 - _getParentOffset: function() {  
210 -  
211 - //Get the offsetParent and cache its position  
212 - this.offsetParent = this.helper.offsetParent();  
213 - var po = this.offsetParent.offset();  
214 -  
215 - // This is a special case where we need to modify a offset calculated on start, since the following happened:  
216 - // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent  
217 - // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that  
218 - // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag  
219 - if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {  
220 - po.left += this.scrollParent.scrollLeft();  
221 - po.top += this.scrollParent.scrollTop();  
222 - }  
223 -  
224 - if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information  
225 - || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix  
226 - po = { top: 0, left: 0 };  
227 -  
228 - return {  
229 - top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),  
230 - left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)  
231 - };  
232 -  
233 - },  
234 -  
235 - _getRelativeOffset: function() {  
236 -  
237 - if(this.cssPosition == "relative") {  
238 - var p = this.element.position();  
239 - return {  
240 - top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),  
241 - left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()  
242 - };  
243 - } else {  
244 - return { top: 0, left: 0 };  
245 - }  
246 -  
247 - },  
248 -  
249 - _cacheMargins: function() {  
250 - this.margins = {  
251 - left: (parseInt(this.element.css("marginLeft"),10) || 0),  
252 - top: (parseInt(this.element.css("marginTop"),10) || 0)  
253 - };  
254 - },  
255 -  
256 - _cacheHelperProportions: function() {  
257 - this.helperProportions = {  
258 - width: this.helper.outerWidth(),  
259 - height: this.helper.outerHeight()  
260 - };  
261 - },  
262 -  
263 - _setContainment: function() {  
264 -  
265 - var o = this.options;  
266 - if(o.containment == 'parent') o.containment = this.helper[0].parentNode;  
267 - if(o.containment == 'document' || o.containment == 'window') this.containment = [  
268 - 0 - this.offset.relative.left - this.offset.parent.left,  
269 - 0 - this.offset.relative.top - this.offset.parent.top,  
270 - $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,  
271 - ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top  
272 - ];  
273 -  
274 - if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {  
275 - var ce = $(o.containment)[0]; if(!ce) return;  
276 - var co = $(o.containment).offset();  
277 - var over = ($(ce).css("overflow") != 'hidden');  
278 -  
279 - this.containment = [  
280 - co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,  
281 - co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,  
282 - co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,  
283 - co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top  
284 - ];  
285 - } else if(o.containment.constructor == Array) {  
286 - this.containment = o.containment;  
287 - }  
288 -  
289 - },  
290 -  
291 - _convertPositionTo: function(d, pos) {  
292 -  
293 - if(!pos) pos = this.position;  
294 - var mod = d == "absolute" ? 1 : -1;  
295 - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);  
296 -  
297 - return {  
298 - top: (  
299 - pos.top // The absolute mouse position  
300 - + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent  
301 - + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)  
302 - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)  
303 - ),  
304 - left: (  
305 - pos.left // The absolute mouse position  
306 - + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent  
307 - + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)  
308 - - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)  
309 - )  
310 - };  
311 -  
312 - },  
313 -  
314 - _generatePosition: function(event) {  
315 -  
316 - var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);  
317 -  
318 - // This is another very weird special case that only happens for relative elements:  
319 - // 1. If the css position is relative  
320 - // 2. and the scroll parent is the document or similar to the offset parent  
321 - // we have to refresh the relative offset during the scroll so there are no jumps  
322 - if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {  
323 - this.offset.relative = this._getRelativeOffset();  
324 - }  
325 -  
326 - var pageX = event.pageX;  
327 - var pageY = event.pageY;  
328 -  
329 - /*  
330 - * - Position constraining -  
331 - * Constrain the position to a mix of grid, containment.  
332 - */  
333 -  
334 - if(this.originalPosition) { //If we are not dragging yet, we won't check for options  
335 -  
336 - if(this.containment) {  
337 - if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;  
338 - if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;  
339 - if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;  
340 - if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;  
341 - }  
342 -  
343 - if(o.grid) {  
344 - var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];  
345 - pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;  
346 -  
347 - var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];  
348 - pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;  
349 - }  
350 -  
351 - }  
352 -  
353 - return {  
354 - top: (  
355 - pageY // The absolute mouse position  
356 - - this.offset.click.top // Click offset (relative to the element)  
357 - - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent  
358 - - this.offset.parent.top // The offsetParent's offset without borders (offset + border)  
359 - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))  
360 - ),  
361 - left: (  
362 - pageX // The absolute mouse position  
363 - - this.offset.click.left // Click offset (relative to the element)  
364 - - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent  
365 - - this.offset.parent.left // The offsetParent's offset without borders (offset + border)  
366 - + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))  
367 - )  
368 - };  
369 -  
370 - },  
371 -  
372 - _clear: function() {  
373 - this.helper.removeClass("ui-draggable-dragging");  
374 - if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();  
375 - //if($.ui.ddmanager) $.ui.ddmanager.current = null;  
376 - this.helper = null;  
377 - this.cancelHelperRemoval = false;  
378 - },  
379 -  
380 - // From now on bulk stuff - mainly helpers  
381 -  
382 - _trigger: function(type, event, ui) {  
383 - ui = ui || this._uiHash();  
384 - $.ui.plugin.call(this, type, [event, ui]);  
385 - if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins  
386 - return $.widget.prototype._trigger.call(this, type, event, ui);  
387 - },  
388 -  
389 - plugins: {},  
390 -  
391 - _uiHash: function(event) {  
392 - return {  
393 - helper: this.helper,  
394 - position: this.position,  
395 - absolutePosition: this.positionAbs, //deprecated  
396 - offset: this.positionAbs  
397 - };  
398 - }  
399 -  
400 -}));  
401 -  
402 -$.extend($.ui.draggable, {  
403 - version: "1.7.2",  
404 - eventPrefix: "drag",  
405 - defaults: {  
406 - addClasses: true,  
407 - appendTo: "parent",  
408 - axis: false,  
409 - cancel: ":input,option",  
410 - connectToSortable: false,  
411 - containment: false,  
412 - cursor: "auto",  
413 - cursorAt: false,  
414 - delay: 0,  
415 - distance: 1,  
416 - grid: false,  
417 - handle: false,  
418 - helper: "original",  
419 - iframeFix: false,  
420 - opacity: false,  
421 - refreshPositions: false,  
422 - revert: false,  
423 - revertDuration: 500,  
424 - scope: "default",  
425 - scroll: true,  
426 - scrollSensitivity: 20,  
427 - scrollSpeed: 20,  
428 - snap: false,  
429 - snapMode: "both",  
430 - snapTolerance: 20,  
431 - stack: false,  
432 - zIndex: false  
433 - }  
434 -});  
435 -  
436 -$.ui.plugin.add("draggable", "connectToSortable", {  
437 - start: function(event, ui) {  
438 -  
439 - var inst = $(this).data("draggable"), o = inst.options,  
440 - uiSortable = $.extend({}, ui, { item: inst.element });  
441 - inst.sortables = [];  
442 - $(o.connectToSortable).each(function() {  
443 - var sortable = $.data(this, 'sortable');  
444 - if (sortable && !sortable.options.disabled) {  
445 - inst.sortables.push({  
446 - instance: sortable,  
447 - shouldRevert: sortable.options.revert  
448 - });  
449 - sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache  
450 - sortable._trigger("activate", event, uiSortable);  
451 - }  
452 - });  
453 -  
454 - },  
455 - stop: function(event, ui) {  
456 -  
457 - //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper  
458 - var inst = $(this).data("draggable"),  
459 - uiSortable = $.extend({}, ui, { item: inst.element });  
460 -  
461 - $.each(inst.sortables, function() {  
462 - if(this.instance.isOver) {  
463 -  
464 - this.instance.isOver = 0;  
465 -  
466 - inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance  
467 - this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)  
468 -  
469 - //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'  
470 - if(this.shouldRevert) this.instance.options.revert = true;  
471 -  
472 - //Trigger the stop of the sortable  
473 - this.instance._mouseStop(event);  
474 -  
475 - this.instance.options.helper = this.instance.options._helper;  
476 -  
477 - //If the helper has been the original item, restore properties in the sortable  
478 - if(inst.options.helper == 'original')  
479 - this.instance.currentItem.css({ top: 'auto', left: 'auto' });  
480 -  
481 - } else {  
482 - this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance  
483 - this.instance._trigger("deactivate", event, uiSortable);  
484 - }  
485 -  
486 - });  
487 -  
488 - },  
489 - drag: function(event, ui) {  
490 -  
491 - var inst = $(this).data("draggable"), self = this;  
492 -  
493 - var checkPos = function(o) {  
494 - var dyClick = this.offset.click.top, dxClick = this.offset.click.left;  
495 - var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;  
496 - var itemHeight = o.height, itemWidth = o.width;  
497 - var itemTop = o.top, itemLeft = o.left;  
498 -  
499 - return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);  
500 - };  
501 -  
502 - $.each(inst.sortables, function(i) {  
503 -  
504 - //Copy over some variables to allow calling the sortable's native _intersectsWith  
505 - this.instance.positionAbs = inst.positionAbs;  
506 - this.instance.helperProportions = inst.helperProportions;  
507 - this.instance.offset.click = inst.offset.click;  
508 -  
509 - if(this.instance._intersectsWith(this.instance.containerCache)) {  
510 -  
511 - //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once  
512 - if(!this.instance.isOver) {  
513 -  
514 - this.instance.isOver = 1;  
515 - //Now we fake the start of dragging for the sortable instance,  
516 - //by cloning the list group item, appending it to the sortable and using it as inst.currentItem  
517 - //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)  
518 - this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);  
519 - this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it  
520 - this.instance.options.helper = function() { return ui.helper[0]; };  
521 -  
522 - event.target = this.instance.currentItem[0];  
523 - this.instance._mouseCapture(event, true);  
524 - this.instance._mouseStart(event, true, true);  
525 -  
526 - //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes  
527 - this.instance.offset.click.top = inst.offset.click.top;  
528 - this.instance.offset.click.left = inst.offset.click.left;  
529 - this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;  
530 - this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;  
531 -  
532 - inst._trigger("toSortable", event);  
533 - inst.dropped = this.instance.element; //draggable revert needs that  
534 - //hack so receive/update callbacks work (mostly)  
535 - inst.currentItem = inst.element;  
536 - this.instance.fromOutside = inst;  
537 -  
538 - }  
539 -  
540 - //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable  
541 - if(this.instance.currentItem) this.instance._mouseDrag(event);  
542 -  
543 - } else {  
544 -  
545 - //If it doesn't intersect with the sortable, and it intersected before,  
546 - //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval  
547 - if(this.instance.isOver) {  
548 -  
549 - this.instance.isOver = 0;  
550 - this.instance.cancelHelperRemoval = true;  
551 -  
552 - //Prevent reverting on this forced stop  
553 - this.instance.options.revert = false;  
554 -  
555 - // The out event needs to be triggered independently  
556 - this.instance._trigger('out', event, this.instance._uiHash(this.instance));  
557 -  
558 - this.instance._mouseStop(event, true);  
559 - this.instance.options.helper = this.instance.options._helper;  
560 -  
561 - //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size  
562 - this.instance.currentItem.remove();  
563 - if(this.instance.placeholder) this.instance.placeholder.remove();  
564 -  
565 - inst._trigger("fromSortable", event);  
566 - inst.dropped = false; //draggable revert needs that  
567 - }  
568 -  
569 - };  
570 -  
571 - });  
572 -  
573 - }  
574 -});  
575 -  
576 -$.ui.plugin.add("draggable", "cursor", {  
577 - start: function(event, ui) {  
578 - var t = $('body'), o = $(this).data('draggable').options;  
579 - if (t.css("cursor")) o._cursor = t.css("cursor");  
580 - t.css("cursor", o.cursor);  
581 - },  
582 - stop: function(event, ui) {  
583 - var o = $(this).data('draggable').options;  
584 - if (o._cursor) $('body').css("cursor", o._cursor);  
585 - }  
586 -});  
587 -  
588 -$.ui.plugin.add("draggable", "iframeFix", {  
589 - start: function(event, ui) {  
590 - var o = $(this).data('draggable').options;  
591 - $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {  
592 - $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')  
593 - .css({  
594 - width: this.offsetWidth+"px", height: this.offsetHeight+"px",  
595 - position: "absolute", opacity: "0.001", zIndex: 1000  
596 - })  
597 - .css($(this).offset())  
598 - .appendTo("body");  
599 - });  
600 - },  
601 - stop: function(event, ui) {  
602 - $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers  
603 - }  
604 -});  
605 -  
606 -$.ui.plugin.add("draggable", "opacity", {  
607 - start: function(event, ui) {  
608 - var t = $(ui.helper), o = $(this).data('draggable').options;  
609 - if(t.css("opacity")) o._opacity = t.css("opacity");  
610 - t.css('opacity', o.opacity);  
611 - },  
612 - stop: function(event, ui) {  
613 - var o = $(this).data('draggable').options;  
614 - if(o._opacity) $(ui.helper).css('opacity', o._opacity);  
615 - }  
616 -});  
617 -  
618 -$.ui.plugin.add("draggable", "scroll", {  
619 - start: function(event, ui) {  
620 - var i = $(this).data("draggable");  
621 - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();  
622 - },  
623 - drag: function(event, ui) {  
624 -  
625 - var i = $(this).data("draggable"), o = i.options, scrolled = false;  
626 -  
627 - if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {  
628 -  
629 - if(!o.axis || o.axis != 'x') {  
630 - if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)  
631 - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;  
632 - else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)  
633 - i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;  
634 - }  
635 -  
636 - if(!o.axis || o.axis != 'y') {  
637 - if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)  
638 - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;  
639 - else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)  
640 - i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;  
641 - }  
642 -  
643 - } else {  
644 -  
645 - if(!o.axis || o.axis != 'x') {  
646 - if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)  
647 - scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);  
648 - else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)  
649 - scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);  
650 - }  
651 -  
652 - if(!o.axis || o.axis != 'y') {  
653 - if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)  
654 - scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);  
655 - else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)  
656 - scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);  
657 - }  
658 -  
659 - }  
660 -  
661 - if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)  
662 - $.ui.ddmanager.prepareOffsets(i, event);  
663 -  
664 - }  
665 -});  
666 -  
667 -$.ui.plugin.add("draggable", "snap", {  
668 - start: function(event, ui) {  
669 -  
670 - var i = $(this).data("draggable"), o = i.options;  
671 - i.snapElements = [];  
672 -  
673 - $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {  
674 - var $t = $(this); var $o = $t.offset();  
675 - if(this != i.element[0]) i.snapElements.push({  
676 - item: this,  
677 - width: $t.outerWidth(), height: $t.outerHeight(),  
678 - top: $o.top, left: $o.left  
679 - });  
680 - });  
681 -  
682 - },  
683 - drag: function(event, ui) {  
684 -  
685 - var inst = $(this).data("draggable"), o = inst.options;  
686 - var d = o.snapTolerance;  
687 -  
688 - var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,  
689 - y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;  
690 -  
691 - for (var i = inst.snapElements.length - 1; i >= 0; i--){  
692 -  
693 - var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,  
694 - t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;  
695 -  
696 - //Yes, I know, this is insane ;)  
697 - if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {  
698 - if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));  
699 - inst.snapElements[i].snapping = false;  
700 - continue;  
701 - }  
702 -  
703 - if(o.snapMode != 'inner') {  
704 - var ts = Math.abs(t - y2) <= d;  
705 - var bs = Math.abs(b - y1) <= d;  
706 - var ls = Math.abs(l - x2) <= d;  
707 - var rs = Math.abs(r - x1) <= d;  
708 - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;  
709 - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;  
710 - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;  
711 - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;  
712 - }  
713 -  
714 - var first = (ts || bs || ls || rs);  
715 -  
716 - if(o.snapMode != 'outer') {  
717 - var ts = Math.abs(t - y1) <= d;  
718 - var bs = Math.abs(b - y2) <= d;  
719 - var ls = Math.abs(l - x1) <= d;  
720 - var rs = Math.abs(r - x2) <= d;  
721 - if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;  
722 - if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;  
723 - if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;  
724 - if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;  
725 - }  
726 -  
727 - if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))  
728 - (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));  
729 - inst.snapElements[i].snapping = (ts || bs || ls || rs || first);  
730 -  
731 - };  
732 -  
733 - }  
734 -});  
735 -  
736 -$.ui.plugin.add("draggable", "stack", {  
737 - start: function(event, ui) {  
738 -  
739 - var o = $(this).data("draggable").options;  
740 -  
741 - var group = $.makeArray($(o.stack.group)).sort(function(a,b) {  
742 - return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min);  
743 - });  
744 -  
745 - $(group).each(function(i) {  
746 - this.style.zIndex = o.stack.min + i;  
747 - });  
748 -  
749 - this[0].style.zIndex = o.stack.min + group.length;  
750 -  
751 - }  
752 -});  
753 -  
754 -$.ui.plugin.add("draggable", "zIndex", {  
755 - start: function(event, ui) {  
756 - var t = $(ui.helper), o = $(this).data("draggable").options;  
757 - if(t.css("zIndex")) o._zIndex = t.css("zIndex");  
758 - t.css('zIndex', o.zIndex);  
759 - },  
760 - stop: function(event, ui) {  
761 - var o = $(this).data("draggable").options;  
762 - if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);  
763 - }  
764 -}); 143 + return false;
  144 + },
  145 +
  146 + _mouseStop: function(event) {
  147 +
  148 + //If we are using droppables, inform the manager about the drop
  149 + var dropped = false;
  150 + if ($.ui.ddmanager && !this.options.dropBehaviour)
  151 + dropped = $.ui.ddmanager.drop(this, event);
  152 +
  153 + //if a drop comes from outside (a sortable)
  154 + if (this.dropped) {
  155 + dropped = this.dropped;
  156 + this.dropped = false;
  157 + }
  158 +
  159 + if ((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
  160 + var self = this;
  161 + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
  162 + self._trigger("stop", event);
  163 + self._clear();
  164 + });
  165 + } else {
  166 + this._trigger("stop", event);
  167 + this._clear();
  168 + }
  169 +
  170 + return false;
  171 + },
  172 +
  173 + _getHandle: function(event) {
  174 +
  175 + var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
  176 + $(this.options.handle, this.element)
  177 + .find("*")
  178 + .andSelf()
  179 + .each(function() {
  180 + if (this == event.target) handle = true;
  181 + });
  182 +
  183 + return handle;
  184 +
  185 + },
  186 +
  187 + _createHelper: function(event) {
  188 +
  189 + var o = this.options;
  190 + var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
  191 +
  192 + if (!helper.parents('body').length)
  193 + helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
  194 +
  195 + if (helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
  196 + helper.css("position", "absolute");
  197 +
  198 + return helper;
  199 +
  200 + },
  201 +
  202 + _adjustOffsetFromHelper: function(obj) {
  203 + if (obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
  204 + if (obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
  205 + if (obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
  206 + if (obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
  207 + },
  208 +
  209 + _getParentOffset: function() {
  210 +
  211 + //Get the offsetParent and cache its position
  212 + this.offsetParent = this.helper.offsetParent();
  213 + var po = this.offsetParent.offset();
  214 +
  215 + // This is a special case where we need to modify a offset calculated on start, since the following happened:
  216 + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
  217 + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
  218 + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
  219 + if (this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
  220 + po.left += this.scrollParent.scrollLeft();
  221 + po.top += this.scrollParent.scrollTop();
  222 + }
  223 +
  224 + if ((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
  225 + || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
  226 + po = { top: 0, left: 0 };
  227 +
  228 + return {
  229 + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
  230 + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
  231 + };
  232 +
  233 + },
  234 +
  235 + _getRelativeOffset: function() {
  236 +
  237 + if (this.cssPosition == "relative") {
  238 + var p = this.element.position();
  239 + return {
  240 + top: p.top - (parseInt(this.helper.css("top"), 10) || 0) + this.scrollParent.scrollTop(),
  241 + left: p.left - (parseInt(this.helper.css("left"), 10) || 0) + this.scrollParent.scrollLeft()
  242 + };
  243 + } else {
  244 + return { top: 0, left: 0 };
  245 + }
  246 +
  247 + },
  248 +
  249 + _cacheMargins: function() {
  250 + this.margins = {
  251 + left: (parseInt(this.element.css("marginLeft"), 10) || 0),
  252 + top: (parseInt(this.element.css("marginTop"), 10) || 0)
  253 + };
  254 + },
  255 +
  256 + _cacheHelperProportions: function() {
  257 + this.helperProportions = {
  258 + width: this.helper.outerWidth(),
  259 + height: this.helper.outerHeight()
  260 + };
  261 + },
  262 +
  263 + _setContainment: function() {
  264 +
  265 + var o = this.options;
  266 + if (o.containment == 'parent') o.containment = this.helper[0].parentNode;
  267 + if (o.containment == 'document' || o.containment == 'window') this.containment = [
  268 + 0 - this.offset.relative.left - this.offset.parent.left,
  269 + 0 - this.offset.relative.top - this.offset.parent.top,
  270 + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
  271 + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
  272 + ];
  273 +
  274 + if (!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
  275 + var ce = $(o.containment)[0];
  276 + if (!ce) return;
  277 + var co = $(o.containment).offset();
  278 + var over = ($(ce).css("overflow") != 'hidden');
  279 +
  280 + this.containment = [
  281 + co.left + (parseInt($(ce).css("borderLeftWidth"), 10) || 0) + (parseInt($(ce).css("paddingLeft"), 10) || 0) - this.margins.left,
  282 + co.top + (parseInt($(ce).css("borderTopWidth"), 10) || 0) + (parseInt($(ce).css("paddingTop"), 10) || 0) - this.margins.top,
  283 + co.left + (over ? Math.max(ce.scrollWidth, ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"), 10) || 0) - (parseInt($(ce).css("paddingRight"), 10) || 0) - this.helperProportions.width - this.margins.left,
  284 + co.top + (over ? Math.max(ce.scrollHeight, ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"), 10) || 0) - (parseInt($(ce).css("paddingBottom"), 10) || 0) - this.helperProportions.height - this.margins.top
  285 + ];
  286 + } else if (o.containment.constructor == Array) {
  287 + this.containment = o.containment;
  288 + }
  289 +
  290 + },
  291 +
  292 + _convertPositionTo: function(d, pos) {
  293 +
  294 + if (!pos) pos = this.position;
  295 + var mod = d == "absolute" ? 1 : -1;
  296 + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  297 +
  298 + return {
  299 + top: (
  300 + pos.top // The absolute mouse position
  301 + + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  302 + + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
  303 + - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
  304 + ),
  305 + left: (
  306 + pos.left // The absolute mouse position
  307 + + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
  308 + + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
  309 + - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
  310 + )
  311 + };
  312 +
  313 + },
  314 +
  315 + _generatePosition: function(event) {
  316 +
  317 + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
  318 +
  319 + // This is another very weird special case that only happens for relative elements:
  320 + // 1. If the css position is relative
  321 + // 2. and the scroll parent is the document or similar to the offset parent
  322 + // we have to refresh the relative offset during the scroll so there are no jumps
  323 + if (this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
  324 + this.offset.relative = this._getRelativeOffset();
  325 + }
  326 +
  327 + var pageX = event.pageX;
  328 + var pageY = event.pageY;
  329 +
  330 + /*
  331 + * - Position constraining -
  332 + * Constrain the position to a mix of grid, containment.
  333 + */
  334 +
  335 + if (this.originalPosition) { //If we are not dragging yet, we won't check for options
  336 +
  337 + if (this.containment) {
  338 + if (event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
  339 + if (event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
  340 + if (event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
  341 + if (event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
  342 + }
  343 +
  344 + if (o.grid) {
  345 + var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
  346 + pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
  347 +
  348 + var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
  349 + pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
  350 + }
  351 +
  352 + }
  353 +
  354 + return {
  355 + top: (
  356 + pageY // The absolute mouse position
  357 + - this.offset.click.top // Click offset (relative to the element)
  358 + - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
  359 + - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
  360 + + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
  361 + ),
  362 + left: (
  363 + pageX // The absolute mouse position
  364 + - this.offset.click.left // Click offset (relative to the element)
  365 + - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
  366 + - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
  367 + + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
  368 + )
  369 + };
  370 +
  371 + },
  372 +
  373 + _clear: function() {
  374 + this.helper.removeClass("ui-draggable-dragging");
  375 + if (this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
  376 + //if($.ui.ddmanager) $.ui.ddmanager.current = null;
  377 + this.helper = null;
  378 + this.cancelHelperRemoval = false;
  379 + },
  380 +
  381 + // From now on bulk stuff - mainly helpers
  382 +
  383 + _trigger: function(type, event, ui) {
  384 + ui = ui || this._uiHash();
  385 + $.ui.plugin.call(this, type, [event, ui]);
  386 + if (type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
  387 + return $.widget.prototype._trigger.call(this, type, event, ui);
  388 + },
  389 +
  390 + plugins: {},
  391 +
  392 + _uiHash: function(event) {
  393 + return {
  394 + helper: this.helper,
  395 + position: this.position,
  396 + absolutePosition: this.positionAbs, //deprecated
  397 + offset: this.positionAbs
  398 + };
  399 + }
  400 +
  401 + }));
  402 +
  403 + $.extend($.ui.draggable, {
  404 + version: "1.7.2",
  405 + eventPrefix: "drag",
  406 + defaults: {
  407 + addClasses: true,
  408 + appendTo: "parent",
  409 + axis: false,
  410 + cancel: ":input,option",
  411 + connectToSortable: false,
  412 + containment: false,
  413 + cursor: "auto",
  414 + cursorAt: false,
  415 + delay: 0,
  416 + distance: 1,
  417 + grid: false,
  418 + handle: false,
  419 + helper: "original",
  420 + iframeFix: false,
  421 + opacity: false,
  422 + refreshPositions: false,
  423 + revert: false,
  424 + revertDuration: 500,
  425 + scope: "default",
  426 + scroll: true,
  427 + scrollSensitivity: 20,
  428 + scrollSpeed: 20,
  429 + snap: false,
  430 + snapMode: "both",
  431 + snapTolerance: 20,
  432 + stack: false,
  433 + zIndex: false
  434 + }
  435 + });
  436 +
  437 + $.ui.plugin.add("draggable", "connectToSortable", {
  438 + start: function(event, ui) {
  439 +
  440 + var inst = $(this).data("draggable"), o = inst.options,
  441 + uiSortable = $.extend({}, ui, { item: inst.element });
  442 + inst.sortables = [];
  443 + $(o.connectToSortable).each(function() {
  444 + var sortable = $.data(this, 'sortable');
  445 + if (sortable && !sortable.options.disabled) {
  446 + inst.sortables.push({
  447 + instance: sortable,
  448 + shouldRevert: sortable.options.revert
  449 + });
  450 + sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
  451 + sortable._trigger("activate", event, uiSortable);
  452 + }
  453 + });
  454 +
  455 + },
  456 + stop: function(event, ui) {
  457 +
  458 + //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
  459 + var inst = $(this).data("draggable"),
  460 + uiSortable = $.extend({}, ui, { item: inst.element });
  461 +
  462 + $.each(inst.sortables, function() {
  463 + if (this.instance.isOver) {
  464 +
  465 + this.instance.isOver = 0;
  466 +
  467 + inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
  468 + this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
  469 +
  470 + //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
  471 + if (this.shouldRevert) this.instance.options.revert = true;
  472 +
  473 + //Trigger the stop of the sortable
  474 + this.instance._mouseStop(event);
  475 +
  476 + this.instance.options.helper = this.instance.options._helper;
  477 +
  478 + //If the helper has been the original item, restore properties in the sortable
  479 + if (inst.options.helper == 'original')
  480 + this.instance.currentItem.css({ top: 'auto', left: 'auto' });
  481 +
  482 + } else {
  483 + this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
  484 + this.instance._trigger("deactivate", event, uiSortable);
  485 + }
  486 +
  487 + });
  488 +
  489 + },
  490 + drag: function(event, ui) {
  491 +
  492 + var inst = $(this).data("draggable"), self = this;
  493 +
  494 + var checkPos = function(o) {
  495 + var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
  496 + var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
  497 + var itemHeight = o.height, itemWidth = o.width;
  498 + var itemTop = o.top, itemLeft = o.left;
  499 +
  500 + return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
  501 + };
  502 +
  503 + $.each(inst.sortables, function(i) {
  504 +
  505 + //Copy over some variables to allow calling the sortable's native _intersectsWith
  506 + this.instance.positionAbs = inst.positionAbs;
  507 + this.instance.helperProportions = inst.helperProportions;
  508 + this.instance.offset.click = inst.offset.click;
  509 +
  510 + if (this.instance._intersectsWith(this.instance.containerCache)) {
  511 +
  512 + //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
  513 + if (!this.instance.isOver) {
  514 +
  515 + this.instance.isOver = 1;
  516 + //Now we fake the start of dragging for the sortable instance,
  517 + //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
  518 + //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
  519 + this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
  520 + this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
  521 + this.instance.options.helper = function() {
  522 + return ui.helper[0];
  523 + };
  524 +
  525 + event.target = this.instance.currentItem[0];
  526 + this.instance._mouseCapture(event, true);
  527 + this.instance._mouseStart(event, true, true);
  528 +
  529 + //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
  530 + this.instance.offset.click.top = inst.offset.click.top;
  531 + this.instance.offset.click.left = inst.offset.click.left;
  532 + this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
  533 + this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
  534 +
  535 + inst._trigger("toSortable", event);
  536 + inst.dropped = this.instance.element; //draggable revert needs that
  537 + //hack so receive/update callbacks work (mostly)
  538 + inst.currentItem = inst.element;
  539 + this.instance.fromOutside = inst;
  540 +
  541 + }
  542 +
  543 + //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
  544 + if (this.instance.currentItem) this.instance._mouseDrag(event);
  545 +
  546 + } else {
  547 +
  548 + //If it doesn't intersect with the sortable, and it intersected before,
  549 + //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
  550 + if (this.instance.isOver) {
  551 +
  552 + this.instance.isOver = 0;
  553 + this.instance.cancelHelperRemoval = true;
  554 +
  555 + //Prevent reverting on this forced stop
  556 + this.instance.options.revert = false;
  557 +
  558 + // The out event needs to be triggered independently
  559 + this.instance._trigger('out', event, this.instance._uiHash(this.instance));
  560 +
  561 + this.instance._mouseStop(event, true);
  562 + this.instance.options.helper = this.instance.options._helper;
  563 +
  564 + //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
  565 + this.instance.currentItem.remove();
  566 + if (this.instance.placeholder) this.instance.placeholder.remove();
  567 +
  568 + inst._trigger("fromSortable", event);
  569 + inst.dropped = false; //draggable revert needs that
  570 + }
  571 +
  572 + }
  573 + ;
  574 +
  575 + });
  576 +
  577 + }
  578 + });
  579 +
  580 + $.ui.plugin.add("draggable", "cursor", {
  581 + start: function(event, ui) {
  582 + var t = $('body'), o = $(this).data('draggable').options;
  583 + if (t.css("cursor")) o._cursor = t.css("cursor");
  584 + t.css("cursor", o.cursor);
  585 + },
  586 + stop: function(event, ui) {
  587 + var o = $(this).data('draggable').options;
  588 + if (o._cursor) $('body').css("cursor", o._cursor);
  589 + }
  590 + });
  591 +
  592 + $.ui.plugin.add("draggable", "iframeFix", {
  593 + start: function(event, ui) {
  594 + var o = $(this).data('draggable').options;
  595 + $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
  596 + $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
  597 + .css({
  598 + width: this.offsetWidth + "px", height: this.offsetHeight + "px",
  599 + position: "absolute", opacity: "0.001", zIndex: 1000
  600 + })
  601 + .css($(this).offset())
  602 + .appendTo("body");
  603 + });
  604 + },
  605 + stop: function(event, ui) {
  606 + $("div.ui-draggable-iframeFix").each(function() {
  607 + this.parentNode.removeChild(this);
  608 + }); //Remove frame helpers
  609 + }
  610 + });
  611 +
  612 + $.ui.plugin.add("draggable", "opacity", {
  613 + start: function(event, ui) {
  614 + var t = $(ui.helper), o = $(this).data('draggable').options;
  615 + if (t.css("opacity")) o._opacity = t.css("opacity");
  616 + t.css('opacity', o.opacity);
  617 + },
  618 + stop: function(event, ui) {
  619 + var o = $(this).data('draggable').options;
  620 + if (o._opacity) $(ui.helper).css('opacity', o._opacity);
  621 + }
  622 + });
  623 +
  624 + $.ui.plugin.add("draggable", "scroll", {
  625 + start: function(event, ui) {
  626 + var i = $(this).data("draggable");
  627 + if (i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
  628 + },
  629 + drag: function(event, ui) {
  630 +
  631 + var i = $(this).data("draggable"), o = i.options, scrolled = false;
  632 +
  633 + if (i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
  634 +
  635 + if (!o.axis || o.axis != 'x') {
  636 + if ((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
  637 + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
  638 + else if (event.pageY - i.overflowOffset.top < o.scrollSensitivity)
  639 + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
  640 + }
  641 +
  642 + if (!o.axis || o.axis != 'y') {
  643 + if ((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
  644 + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
  645 + else if (event.pageX - i.overflowOffset.left < o.scrollSensitivity)
  646 + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
  647 + }
  648 +
  649 + } else {
  650 +
  651 + if (!o.axis || o.axis != 'x') {
  652 + if (event.pageY - $(document).scrollTop() < o.scrollSensitivity)
  653 + scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
  654 + else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
  655 + scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
  656 + }
  657 +
  658 + if (!o.axis || o.axis != 'y') {
  659 + if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
  660 + scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
  661 + else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
  662 + scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
  663 + }
  664 +
  665 + }
  666 +
  667 + if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
  668 + $.ui.ddmanager.prepareOffsets(i, event);
  669 +
  670 + }
  671 + });
  672 +
  673 + $.ui.plugin.add("draggable", "snap", {
  674 + start: function(event, ui) {
  675 +
  676 + var i = $(this).data("draggable"), o = i.options;
  677 + i.snapElements = [];
  678 +
  679 + $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
  680 + var $t = $(this);
  681 + var $o = $t.offset();
  682 + if (this != i.element[0]) i.snapElements.push({
  683 + item: this,
  684 + width: $t.outerWidth(), height: $t.outerHeight(),
  685 + top: $o.top, left: $o.left
  686 + });
  687 + });
  688 +
  689 + },
  690 + drag: function(event, ui) {
  691 +
  692 + var inst = $(this).data("draggable"), o = inst.options;
  693 + var d = o.snapTolerance;
  694 +
  695 + var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
  696 + y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
  697 +
  698 + for (var i = inst.snapElements.length - 1; i >= 0; i--) {
  699 +
  700 + var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
  701 + t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
  702 +
  703 + //Yes, I know, this is insane ;)
  704 + if (!((l - d < x1 && x1 < r + d && t - d < y1 && y1 < b + d) || (l - d < x1 && x1 < r + d && t - d < y2 && y2 < b + d) || (l - d < x2 && x2 < r + d && t - d < y1 && y1 < b + d) || (l - d < x2 && x2 < r + d && t - d < y2 && y2 < b + d))) {
  705 + if (inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  706 + inst.snapElements[i].snapping = false;
  707 + continue;
  708 + }
  709 +
  710 + if (o.snapMode != 'inner') {
  711 + var ts = Math.abs(t - y2) <= d;
  712 + var bs = Math.abs(b - y1) <= d;
  713 + var ls = Math.abs(l - x2) <= d;
  714 + var rs = Math.abs(r - x1) <= d;
  715 + if (ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  716 + if (bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
  717 + if (ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
  718 + if (rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
  719 + }
  720 +
  721 + var first = (ts || bs || ls || rs);
  722 +
  723 + if (o.snapMode != 'outer') {
  724 + var ts = Math.abs(t - y1) <= d;
  725 + var bs = Math.abs(b - y2) <= d;
  726 + var ls = Math.abs(l - x1) <= d;
  727 + var rs = Math.abs(r - x2) <= d;
  728 + if (ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
  729 + if (bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
  730 + if (ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
  731 + if (rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
  732 + }
  733 +
  734 + if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
  735 + (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
  736 + inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
  737 +
  738 + }
  739 + ;
  740 +
  741 + }
  742 + });
  743 +
  744 + $.ui.plugin.add("draggable", "stack", {
  745 + start: function(event, ui) {
  746 +
  747 + var o = $(this).data("draggable").options;
  748 +
  749 + var group = $.makeArray($(o.stack.group)).sort(function(a, b) {
  750 + return (parseInt($(a).css("zIndex"), 10) || o.stack.min) - (parseInt($(b).css("zIndex"), 10) || o.stack.min);
  751 + });
  752 +
  753 + $(group).each(function(i) {
  754 + this.style.zIndex = o.stack.min + i;
  755 + });
  756 +
  757 + this[0].style.zIndex = o.stack.min + group.length;
  758 +
  759 + }
  760 + });
  761 +
  762 + $.ui.plugin.add("draggable", "zIndex", {
  763 + start: function(event, ui) {
  764 + var t = $(ui.helper), o = $(this).data("draggable").options;
  765 + if (t.css("zIndex")) o._zIndex = t.css("zIndex");
  766 + t.css('zIndex', o.zIndex);
  767 + },
  768 + stop: function(event, ui) {
  769 + var o = $(this).data("draggable").options;
  770 + if (o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
  771 + }
  772 + });
765 773
766 })(jQuery); 774 })(jQuery);
@@ -12,789 +12,803 @@ @@ -12,789 +12,803 @@
12 */ 12 */
13 (function($) { 13 (function($) {
14 14
15 -$.widget("ui.resizable", $.extend({}, $.ui.mouse, { 15 + $.widget("ui.resizable", $.extend({}, $.ui.mouse, {
16 16
17 - _init: function() { 17 + _init: function() {
18 18
19 - var self = this, o = this.options;  
20 - this.element.addClass("ui-resizable"); 19 + var self = this, o = this.options;
  20 + this.element.addClass("ui-resizable");
21 21
22 - $.extend(this, {  
23 - _aspectRatio: !!(o.aspectRatio),  
24 - aspectRatio: o.aspectRatio,  
25 - originalElement: this.element,  
26 - _proportionallyResizeElements: [],  
27 - _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null  
28 - }); 22 + $.extend(this, {
  23 + _aspectRatio: !!(o.aspectRatio),
  24 + aspectRatio: o.aspectRatio,
  25 + originalElement: this.element,
  26 + _proportionallyResizeElements: [],
  27 + _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
  28 + });
29 29
30 - //Wrap the element if it cannot hold child nodes  
31 - if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { 30 + //Wrap the element if it cannot hold child nodes
  31 + if (this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
32 32
33 - //Opera fix for relative positioning  
34 - if (/relative/.test(this.element.css('position')) && $.browser.opera)  
35 - this.element.css({ position: 'relative', top: 'auto', left: 'auto' }); 33 + //Opera fix for relative positioning
  34 + if (/relative/.test(this.element.css('position')) && $.browser.opera)
  35 + this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
36 36
37 - //Create a wrapper element and set the wrapper to the new current internal element  
38 - this.element.wrap(  
39 - $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({  
40 - position: this.element.css('position'),  
41 - width: this.element.outerWidth(),  
42 - height: this.element.outerHeight(),  
43 - top: this.element.css('top'),  
44 - left: this.element.css('left')  
45 - })  
46 - ); 37 + //Create a wrapper element and set the wrapper to the new current internal element
  38 + this.element.wrap(
  39 + $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
  40 + position: this.element.css('position'),
  41 + width: this.element.outerWidth(),
  42 + height: this.element.outerHeight(),
  43 + top: this.element.css('top'),
  44 + left: this.element.css('left')
  45 + })
  46 + );
47 47
48 - //Overwrite the original this.element  
49 - this.element = this.element.parent().data(  
50 - "resizable", this.element.data('resizable')  
51 - ); 48 + //Overwrite the original this.element
  49 + this.element = this.element.parent().data(
  50 + "resizable", this.element.data('resizable')
  51 + );
52 52
53 - this.elementIsWrapper = true; 53 + this.elementIsWrapper = true;
54 54
55 - //Move margins to the wrapper  
56 - this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });  
57 - this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); 55 + //Move margins to the wrapper
  56 + this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
  57 + this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
58 58
59 - //Prevent Safari textarea resize  
60 - this.originalResizeStyle = this.originalElement.css('resize');  
61 - this.originalElement.css('resize', 'none'); 59 + //Prevent Safari textarea resize
  60 + this.originalResizeStyle = this.originalElement.css('resize');
  61 + this.originalElement.css('resize', 'none');
62 62
63 - //Push the actual element to our proportionallyResize internal array  
64 - this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); 63 + //Push the actual element to our proportionallyResize internal array
  64 + this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
65 65
66 - // avoid IE jump (hard set the margin)  
67 - this.originalElement.css({ margin: this.originalElement.css('margin') }); 66 + // avoid IE jump (hard set the margin)
  67 + this.originalElement.css({ margin: this.originalElement.css('margin') });
68 68
69 - // fix handlers offset  
70 - this._proportionallyResize(); 69 + // fix handlers offset
  70 + this._proportionallyResize();
71 71
72 - } 72 + }
73 73
74 - this.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' });  
75 - if(this.handles.constructor == String) { 74 + this.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' });
  75 + if (this.handles.constructor == String) {
76 76
77 - if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';  
78 - var n = this.handles.split(","); this.handles = {}; 77 + if (this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
  78 + var n = this.handles.split(",");
  79 + this.handles = {};
79 80
80 - for(var i = 0; i < n.length; i++) { 81 + for (var i = 0; i < n.length; i++) {
81 82
82 - var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;  
83 - var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>'); 83 + var handle = $.trim(n[i]), hname = 'ui-resizable-' + handle;
  84 + var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
84 85
85 - // increase zIndex of sw, se, ne, nw axis  
86 - //TODO : this modifies original option  
87 - if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex }); 86 + // increase zIndex of sw, se, ne, nw axis
  87 + //TODO : this modifies original option
  88 + if (/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
88 89
89 - //TODO : What's going on here?  
90 - if ('se' == handle) {  
91 - axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');  
92 - }; 90 + //TODO : What's going on here?
  91 + if ('se' == handle) {
  92 + axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
  93 + }
  94 + ;
93 95
94 - //Insert into internal handles object and append to element  
95 - this.handles[handle] = '.ui-resizable-'+handle;  
96 - this.element.append(axis);  
97 - } 96 + //Insert into internal handles object and append to element
  97 + this.handles[handle] = '.ui-resizable-' + handle;
  98 + this.element.append(axis);
  99 + }
98 100
99 - } 101 + }
  102 +
  103 + this._renderAxis = function(target) {
100 104
101 - this._renderAxis = function(target) { 105 + target = target || this.element;
102 106
103 - target = target || this.element; 107 + for (var i in this.handles) {
104 108
105 - for(var i in this.handles) { 109 + if (this.handles[i].constructor == String)
  110 + this.handles[i] = $(this.handles[i], this.element).show();
106 111
107 - if(this.handles[i].constructor == String)  
108 - this.handles[i] = $(this.handles[i], this.element).show(); 112 + //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
  113 + if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
109 114
110 - //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)  
111 - if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { 115 + var axis = $(this.handles[i], this.element), padWrapper = 0;
112 116
113 - var axis = $(this.handles[i], this.element), padWrapper = 0; 117 + //Checking the correct pad and border
  118 + padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
114 119
115 - //Checking the correct pad and border  
116 - padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); 120 + //The padding type i have to apply...
  121 + var padPos = [ 'padding',
  122 + /ne|nw|n/.test(i) ? 'Top' :
  123 + /se|sw|s/.test(i) ? 'Bottom' :
  124 + /^e$/.test(i) ? 'Right' : 'Left' ].join("");
117 125
118 - //The padding type i have to apply...  
119 - var padPos = [ 'padding',  
120 - /ne|nw|n/.test(i) ? 'Top' :  
121 - /se|sw|s/.test(i) ? 'Bottom' :  
122 - /^e$/.test(i) ? 'Right' : 'Left' ].join(""); 126 + target.css(padPos, padWrapper);
123 127
124 - target.css(padPos, padWrapper); 128 + this._proportionallyResize();
125 129
126 - this._proportionallyResize(); 130 + }
127 131
128 - } 132 + //TODO: What's that good for? There's not anything to be executed left
  133 + if (!$(this.handles[i]).length)
  134 + continue;
129 135
130 - //TODO: What's that good for? There's not anything to be executed left  
131 - if(!$(this.handles[i]).length)  
132 - continue; 136 + }
  137 + };
133 138
134 - }  
135 - }; 139 + //TODO: make renderAxis a prototype function
  140 + this._renderAxis(this.element);
136 141
137 - //TODO: make renderAxis a prototype function  
138 - this._renderAxis(this.element); 142 + this._handles = $('.ui-resizable-handle', this.element)
  143 + .disableSelection();
139 144
140 - this._handles = $('.ui-resizable-handle', this.element)  
141 - .disableSelection(); 145 + //Matching axis name
  146 + this._handles.mouseover(function() {
  147 + if (!self.resizing) {
  148 + if (this.className)
  149 + var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
  150 + //Axis, default = se
  151 + self.axis = axis && axis[1] ? axis[1] : 'se';
  152 + }
  153 + });
142 154
143 - //Matching axis name  
144 - this._handles.mouseover(function() {  
145 - if (!self.resizing) {  
146 - if (this.className)  
147 - var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);  
148 - //Axis, default = se  
149 - self.axis = axis && axis[1] ? axis[1] : 'se';  
150 - }  
151 - }); 155 + //If we want to auto hide the elements
  156 + if (o.autoHide) {
  157 + this._handles.hide();
  158 + $(this.element)
  159 + .addClass("ui-resizable-autohide")
  160 + .hover(function() {
  161 + $(this).removeClass("ui-resizable-autohide");
  162 + self._handles.show();
  163 + },
  164 + function() {
  165 + if (!self.resizing) {
  166 + $(this).addClass("ui-resizable-autohide");
  167 + self._handles.hide();
  168 + }
  169 + });
  170 + }
152 171
153 - //If we want to auto hide the elements  
154 - if (o.autoHide) {  
155 - this._handles.hide();  
156 - $(this.element)  
157 - .addClass("ui-resizable-autohide")  
158 - .hover(function() {  
159 - $(this).removeClass("ui-resizable-autohide");  
160 - self._handles.show();  
161 - },  
162 - function(){  
163 - if (!self.resizing) {  
164 - $(this).addClass("ui-resizable-autohide");  
165 - self._handles.hide();  
166 - }  
167 - });  
168 - } 172 + //Initialize the mouse interaction
  173 + this._mouseInit();
169 174
170 - //Initialize the mouse interaction  
171 - this._mouseInit(); 175 + },
172 176
173 - }, 177 + destroy: function() {
174 178
175 - destroy: function() { 179 + this._mouseDestroy();
176 180
177 - this._mouseDestroy(); 181 + var _destroy = function(exp) {
  182 + $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
  183 + .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
  184 + };
178 185
179 - var _destroy = function(exp) {  
180 - $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")  
181 - .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();  
182 - }; 186 + //TODO: Unwrap at same DOM position
  187 + if (this.elementIsWrapper) {
  188 + _destroy(this.element);
  189 + var wrapper = this.element;
  190 + wrapper.parent().append(
  191 + this.originalElement.css({
  192 + position: wrapper.css('position'),
  193 + width: wrapper.outerWidth(),
  194 + height: wrapper.outerHeight(),
  195 + top: wrapper.css('top'),
  196 + left: wrapper.css('left')
  197 + })
  198 + ).end().remove();
  199 + }
183 200
184 - //TODO: Unwrap at same DOM position  
185 - if (this.elementIsWrapper) {  
186 - _destroy(this.element);  
187 - var wrapper = this.element;  
188 - wrapper.parent().append(  
189 - this.originalElement.css({  
190 - position: wrapper.css('position'),  
191 - width: wrapper.outerWidth(),  
192 - height: wrapper.outerHeight(),  
193 - top: wrapper.css('top'),  
194 - left: wrapper.css('left')  
195 - })  
196 - ).end().remove();  
197 - } 201 + this.originalElement.css('resize', this.originalResizeStyle);
  202 + _destroy(this.originalElement);
198 203
199 - this.originalElement.css('resize', this.originalResizeStyle);  
200 - _destroy(this.originalElement); 204 + },
201 205
202 - }, 206 + _mouseCapture: function(event) {
203 207
204 - _mouseCapture: function(event) { 208 + var handle = false;
  209 + for (var i in this.handles) {
  210 + if ($(this.handles[i])[0] == event.target) handle = true;
  211 + }
205 212
206 - var handle = false;  
207 - for(var i in this.handles) {  
208 - if($(this.handles[i])[0] == event.target) handle = true;  
209 - } 213 + return this.options.disabled || !!handle;
210 214
211 - return this.options.disabled || !!handle; 215 + },
212 216
213 - }, 217 + _mouseStart: function(event) {
214 218
215 - _mouseStart: function(event) { 219 + var o = this.options, iniPos = this.element.position(), el = this.element;
216 220
217 - var o = this.options, iniPos = this.element.position(), el = this.element; 221 + this.resizing = true;
  222 + this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
218 223
219 - this.resizing = true;  
220 - this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; 224 + // bugfix for http://dev.jquery.com/ticket/1749
  225 + if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
  226 + el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
  227 + }
221 228
222 - // bugfix for http://dev.jquery.com/ticket/1749  
223 - if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {  
224 - el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });  
225 - } 229 + //Opera fixing relative position
  230 + if ($.browser.opera && (/relative/).test(el.css('position')))
  231 + el.css({ position: 'relative', top: 'auto', left: 'auto' });
226 232
227 - //Opera fixing relative position  
228 - if ($.browser.opera && (/relative/).test(el.css('position')))  
229 - el.css({ position: 'relative', top: 'auto', left: 'auto' }); 233 + this._renderProxy();
230 234
231 - this._renderProxy(); 235 + var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
232 236
233 - var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); 237 + if (o.containment) {
  238 + curleft += $(o.containment).scrollLeft() || 0;
  239 + curtop += $(o.containment).scrollTop() || 0;
  240 + }
234 241
235 - if (o.containment) {  
236 - curleft += $(o.containment).scrollLeft() || 0;  
237 - curtop += $(o.containment).scrollTop() || 0;  
238 - } 242 + //Store needed variables
  243 + this.offset = this.helper.offset();
  244 + this.position = { left: curleft, top: curtop };
  245 + this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  246 + this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
  247 + this.originalPosition = { left: curleft, top: curtop };
  248 + this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
  249 + this.originalMousePosition = { left: event.pageX, top: event.pageY };
239 250
240 - //Store needed variables  
241 - this.offset = this.helper.offset();  
242 - this.position = { left: curleft, top: curtop };  
243 - this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };  
244 - this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };  
245 - this.originalPosition = { left: curleft, top: curtop };  
246 - this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };  
247 - this.originalMousePosition = { left: event.pageX, top: event.pageY }; 251 + //Aspect Ratio
  252 + this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
248 253
249 - //Aspect Ratio  
250 - this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); 254 + var cursor = $('.ui-resizable-' + this.axis).css('cursor');
  255 + $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
251 256
252 - var cursor = $('.ui-resizable-' + this.axis).css('cursor');  
253 - $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); 257 + el.addClass("ui-resizable-resizing");
  258 + this._propagate("start", event);
  259 + return true;
  260 + },
254 261
255 - el.addClass("ui-resizable-resizing");  
256 - this._propagate("start", event);  
257 - return true;  
258 - }, 262 + _mouseDrag: function(event) {
259 263
260 - _mouseDrag: function(event) { 264 + //Increase performance, avoid regex
  265 + var el = this.helper, o = this.options, props = {},
  266 + self = this, smp = this.originalMousePosition, a = this.axis;
261 267
262 - //Increase performance, avoid regex  
263 - var el = this.helper, o = this.options, props = {},  
264 - self = this, smp = this.originalMousePosition, a = this.axis; 268 + var dx = (event.pageX - smp.left) || 0, dy = (event.pageY - smp.top) || 0;
  269 + var trigger = this._change[a];
  270 + if (!trigger) return false;
265 271
266 - var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;  
267 - var trigger = this._change[a];  
268 - if (!trigger) return false; 272 + // Calculate the attrs that will be change
  273 + var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
269 274
270 - // Calculate the attrs that will be change  
271 - var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; 275 + if (this._aspectRatio || event.shiftKey)
  276 + data = this._updateRatio(data, event);
272 277
273 - if (this._aspectRatio || event.shiftKey)  
274 - data = this._updateRatio(data, event); 278 + data = this._respectSize(data, event);
275 279
276 - data = this._respectSize(data, event); 280 + // plugins callbacks need to be called first
  281 + this._propagate("resize", event);
277 282
278 - // plugins callbacks need to be called first  
279 - this._propagate("resize", event); 283 + el.css({
  284 + top: this.position.top + "px", left: this.position.left + "px",
  285 + width: this.size.width + "px", height: this.size.height + "px"
  286 + });
280 287
281 - el.css({  
282 - top: this.position.top + "px", left: this.position.left + "px",  
283 - width: this.size.width + "px", height: this.size.height + "px"  
284 - }); 288 + if (!this._helper && this._proportionallyResizeElements.length)
  289 + this._proportionallyResize();
285 290
286 - if (!this._helper && this._proportionallyResizeElements.length)  
287 - this._proportionallyResize(); 291 + this._updateCache(data);
288 292
289 - this._updateCache(data); 293 + // calling the user callback at the end
  294 + this._trigger('resize', event, this.ui());
290 295
291 - // calling the user callback at the end  
292 - this._trigger('resize', event, this.ui()); 296 + return false;
  297 + },
293 298
294 - return false;  
295 - }, 299 + _mouseStop: function(event) {
296 300
297 - _mouseStop: function(event) { 301 + this.resizing = false;
  302 + var o = this.options, self = this;
298 303
299 - this.resizing = false;  
300 - var o = this.options, self = this; 304 + if (this._helper) {
  305 + var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  306 + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
  307 + soffsetw = ista ? 0 : self.sizeDiff.width;
301 308
302 - if(this._helper) {  
303 - var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),  
304 - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,  
305 - soffsetw = ista ? 0 : self.sizeDiff.width; 309 + var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
  310 + left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
  311 + top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
306 312
307 - var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },  
308 - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,  
309 - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; 313 + if (!o.animate)
  314 + this.element.css($.extend(s, { top: top, left: left }));
310 315
311 - if (!o.animate)  
312 - this.element.css($.extend(s, { top: top, left: left })); 316 + self.helper.height(self.size.height);
  317 + self.helper.width(self.size.width);
313 318
314 - self.helper.height(self.size.height);  
315 - self.helper.width(self.size.width); 319 + if (this._helper && !o.animate) this._proportionallyResize();
  320 + }
316 321
317 - if (this._helper && !o.animate) this._proportionallyResize();  
318 - } 322 + $('body').css('cursor', 'auto');
319 323
320 - $('body').css('cursor', 'auto'); 324 + this.element.removeClass("ui-resizable-resizing");
321 325
322 - this.element.removeClass("ui-resizable-resizing"); 326 + this._propagate("stop", event);
323 327
324 - this._propagate("stop", event); 328 + if (this._helper) this.helper.remove();
  329 + return false;
325 330
326 - if (this._helper) this.helper.remove();  
327 - return false; 331 + },
328 332
329 - }, 333 + _updateCache: function(data) {
  334 + var o = this.options;
  335 + this.offset = this.helper.offset();
  336 + if (isNumber(data.left)) this.position.left = data.left;
  337 + if (isNumber(data.top)) this.position.top = data.top;
  338 + if (isNumber(data.height)) this.size.height = data.height;
  339 + if (isNumber(data.width)) this.size.width = data.width;
  340 + },
330 341
331 - _updateCache: function(data) {  
332 - var o = this.options;  
333 - this.offset = this.helper.offset();  
334 - if (isNumber(data.left)) this.position.left = data.left;  
335 - if (isNumber(data.top)) this.position.top = data.top;  
336 - if (isNumber(data.height)) this.size.height = data.height;  
337 - if (isNumber(data.width)) this.size.width = data.width;  
338 - }, 342 + _updateRatio: function(data, event) {
339 343
340 - _updateRatio: function(data, event) { 344 + var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
341 345
342 - var o = this.options, cpos = this.position, csize = this.size, a = this.axis; 346 + if (data.height) data.width = (csize.height * this.aspectRatio);
  347 + else if (data.width) data.height = (csize.width / this.aspectRatio);
343 348
344 - if (data.height) data.width = (csize.height * this.aspectRatio);  
345 - else if (data.width) data.height = (csize.width / this.aspectRatio); 349 + if (a == 'sw') {
  350 + data.left = cpos.left + (csize.width - data.width);
  351 + data.top = null;
  352 + }
  353 + if (a == 'nw') {
  354 + data.top = cpos.top + (csize.height - data.height);
  355 + data.left = cpos.left + (csize.width - data.width);
  356 + }
346 357
347 - if (a == 'sw') {  
348 - data.left = cpos.left + (csize.width - data.width);  
349 - data.top = null;  
350 - }  
351 - if (a == 'nw') {  
352 - data.top = cpos.top + (csize.height - data.height);  
353 - data.left = cpos.left + (csize.width - data.width);  
354 - } 358 + return data;
  359 + },
355 360
356 - return data;  
357 - }, 361 + _respectSize: function(data, event) {
358 362
359 - _respectSize: function(data, event) { 363 + var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
  364 + ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
  365 + isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
360 366
361 - var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,  
362 - ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),  
363 - isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); 367 + if (isminw) data.width = o.minWidth;
  368 + if (isminh) data.height = o.minHeight;
  369 + if (ismaxw) data.width = o.maxWidth;
  370 + if (ismaxh) data.height = o.maxHeight;
364 371
365 - if (isminw) data.width = o.minWidth;  
366 - if (isminh) data.height = o.minHeight;  
367 - if (ismaxw) data.width = o.maxWidth;  
368 - if (ismaxh) data.height = o.maxHeight; 372 + var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
  373 + var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
369 374
370 - var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;  
371 - var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); 375 + if (isminw && cw) data.left = dw - o.minWidth;
  376 + if (ismaxw && cw) data.left = dw - o.maxWidth;
  377 + if (isminh && ch) data.top = dh - o.minHeight;
  378 + if (ismaxh && ch) data.top = dh - o.maxHeight;
372 379
373 - if (isminw && cw) data.left = dw - o.minWidth;  
374 - if (ismaxw && cw) data.left = dw - o.maxWidth;  
375 - if (isminh && ch) data.top = dh - o.minHeight;  
376 - if (ismaxh && ch) data.top = dh - o.maxHeight; 380 + // fixing jump error on top/left - bug #2330
  381 + var isNotwh = !data.width && !data.height;
  382 + if (isNotwh && !data.left && data.top) data.top = null;
  383 + else if (isNotwh && !data.top && data.left) data.left = null;
377 384
378 - // fixing jump error on top/left - bug #2330  
379 - var isNotwh = !data.width && !data.height;  
380 - if (isNotwh && !data.left && data.top) data.top = null;  
381 - else if (isNotwh && !data.top && data.left) data.left = null; 385 + return data;
  386 + },
382 387
383 - return data;  
384 - }, 388 + _proportionallyResize: function() {
385 389
386 - _proportionallyResize: function() { 390 + var o = this.options;
  391 + if (!this._proportionallyResizeElements.length) return;
  392 + var element = this.helper || this.element;
  393 +
  394 + for (var i = 0; i < this._proportionallyResizeElements.length; i++) {
  395 +
  396 + var prel = this._proportionallyResizeElements[i];
  397 +
  398 + if (!this.borderDif) {
  399 + var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
  400 + p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
  401 +
  402 + this.borderDif = $.map(b, function(v, i) {
  403 + var border = parseInt(v, 10) || 0, padding = parseInt(p[i], 10) || 0;
  404 + return border + padding;
  405 + });
  406 + }
  407 +
  408 + if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
  409 + continue;
  410 +
  411 + prel.css({
  412 + height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
  413 + width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
  414 + });
  415 +
  416 + }
  417 + ;
  418 +
  419 + },
  420 +
  421 + _renderProxy: function() {
  422 +
  423 + var el = this.element, o = this.options;
  424 + this.elementOffset = el.offset();
  425 +
  426 + if (this._helper) {
  427 +
  428 + this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
  429 +
  430 + // fix ie6 offset TODO: This seems broken
  431 + var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
  432 + pxyoffset = ( ie6 ? 2 : -1 );
  433 +
  434 + this.helper.addClass(this._helper).css({
  435 + width: this.element.outerWidth() + pxyoffset,
  436 + height: this.element.outerHeight() + pxyoffset,
  437 + position: 'absolute',
  438 + left: this.elementOffset.left - ie6offset + 'px',
  439 + top: this.elementOffset.top - ie6offset + 'px',
  440 + zIndex: ++o.zIndex //TODO: Don't modify option
  441 + });
  442 +
  443 + this.helper
  444 + .appendTo("body")
  445 + .disableSelection();
  446 +
  447 + } else {
  448 + this.helper = this.element;
  449 + }
  450 +
  451 + },
  452 +
  453 + _change: {
  454 + e: function(event, dx, dy) {
  455 + return { width: this.originalSize.width + dx };
  456 + },
  457 + w: function(event, dx, dy) {
  458 + var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  459 + return { left: sp.left + dx, width: cs.width - dx };
  460 + },
  461 + n: function(event, dx, dy) {
  462 + var o = this.options, cs = this.originalSize, sp = this.originalPosition;
  463 + return { top: sp.top + dy, height: cs.height - dy };
  464 + },
  465 + s: function(event, dx, dy) {
  466 + return { height: this.originalSize.height + dy };
  467 + },
  468 + se: function(event, dx, dy) {
  469 + return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  470 + },
  471 + sw: function(event, dx, dy) {
  472 + return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  473 + },
  474 + ne: function(event, dx, dy) {
  475 + return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
  476 + },
  477 + nw: function(event, dx, dy) {
  478 + return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
  479 + }
  480 + },
  481 +
  482 + _propagate: function(n, event) {
  483 + $.ui.plugin.call(this, n, [event, this.ui()]);
  484 + (n != "resize" && this._trigger(n, event, this.ui()));
  485 + },
  486 +
  487 + plugins: {},
  488 +
  489 + ui: function() {
  490 + return {
  491 + originalElement: this.originalElement,
  492 + element: this.element,
  493 + helper: this.helper,
  494 + position: this.position,
  495 + size: this.size,
  496 + originalSize: this.originalSize,
  497 + originalPosition: this.originalPosition
  498 + };
  499 + }
  500 +
  501 + }));
  502 +
  503 + $.extend($.ui.resizable, {
  504 + version: "1.7.2",
  505 + eventPrefix: "resize",
  506 + defaults: {
  507 + alsoResize: false,
  508 + animate: false,
  509 + animateDuration: "slow",
  510 + animateEasing: "swing",
  511 + aspectRatio: false,
  512 + autoHide: false,
  513 + cancel: ":input,option",
  514 + containment: false,
  515 + delay: 0,
  516 + distance: 1,
  517 + ghost: false,
  518 + grid: false,
  519 + handles: "e,s,se",
  520 + helper: false,
  521 + maxHeight: null,
  522 + maxWidth: null,
  523 + minHeight: 10,
  524 + minWidth: 10,
  525 + zIndex: 1000
  526 + }
  527 + });
  528 +
  529 + /*
  530 + * Resizable Extensions
  531 + */
  532 +
  533 + $.ui.plugin.add("resizable", "alsoResize", {
  534 +
  535 + start: function(event, ui) {
  536 +
  537 + var self = $(this).data("resizable"), o = self.options;
  538 +
  539 + _store = function(exp) {
  540 + $(exp).each(function() {
  541 + $(this).data("resizable-alsoresize", {
  542 + width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
  543 + left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
  544 + });
  545 + });
  546 + };
  547 +
  548 + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
  549 + if (o.alsoResize.length) {
  550 + o.alsoResize = o.alsoResize[0];
  551 + _store(o.alsoResize);
  552 + }
  553 + else {
  554 + $.each(o.alsoResize, function(exp, c) {
  555 + _store(exp);
  556 + });
  557 + }
  558 + } else {
  559 + _store(o.alsoResize);
  560 + }
  561 + },
  562 +
  563 + resize: function(event, ui) {
  564 + var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
  565 +
  566 + var delta = {
  567 + height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
  568 + top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
  569 + },
  570 +
  571 + _alsoResize = function(exp, c) {
  572 + $(exp).each(function() {
  573 + var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
  574 +
  575 + $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
  576 + var sum = (start[prop] || 0) + (delta[prop] || 0);
  577 + if (sum && sum >= 0)
  578 + style[prop] = sum || null;
  579 + });
  580 +
  581 + //Opera fixing relative position
  582 + if (/relative/.test(el.css('position')) && $.browser.opera) {
  583 + self._revertToRelativePosition = true;
  584 + el.css({ position: 'absolute', top: 'auto', left: 'auto' });
  585 + }
  586 +
  587 + el.css(style);
  588 + });
  589 + };
  590 +
  591 + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
  592 + $.each(o.alsoResize, function(exp, c) {
  593 + _alsoResize(exp, c);
  594 + });
  595 + } else {
  596 + _alsoResize(o.alsoResize);
  597 + }
  598 + },
  599 +
  600 + stop: function(event, ui) {
  601 + var self = $(this).data("resizable");
  602 +
  603 + //Opera fixing relative position
  604 + if (self._revertToRelativePosition && $.browser.opera) {
  605 + self._revertToRelativePosition = false;
  606 + el.css({ position: 'relative' });
  607 + }
  608 +
  609 + $(this).removeData("resizable-alsoresize-start");
  610 + }
  611 + });
  612 +
  613 + $.ui.plugin.add("resizable", "animate", {
  614 +
  615 + stop: function(event, ui) {
  616 + var self = $(this).data("resizable"), o = self.options;
  617 +
  618 + var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
  619 + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
  620 + soffsetw = ista ? 0 : self.sizeDiff.width;
  621 +
  622 + var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
  623 + left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
  624 + top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
  625 +
  626 + self.element.animate(
  627 + $.extend(style, top && left ? { top: top, left: left } : {}), {
  628 + duration: o.animateDuration,
  629 + easing: o.animateEasing,
  630 + step: function() {
  631 +
  632 + var data = {
  633 + width: parseInt(self.element.css('width'), 10),
  634 + height: parseInt(self.element.css('height'), 10),
  635 + top: parseInt(self.element.css('top'), 10),
  636 + left: parseInt(self.element.css('left'), 10)
  637 + };
  638 +
  639 + if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
  640 +
  641 + // propagating resize, and updating values for each animation step
  642 + self._updateCache(data);
  643 + self._propagate("resize", event);
  644 +
  645 + }
  646 + }
  647 + );
  648 + }
  649 +
  650 + });
  651 +
  652 + $.ui.plugin.add("resizable", "containment", {
  653 +
  654 + start: function(event, ui) {
  655 + var self = $(this).data("resizable"), o = self.options, el = self.element;
  656 + var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
  657 + if (!ce) return;
  658 +
  659 + self.containerElement = $(ce);
387 660
388 - var o = this.options;  
389 - if (!this._proportionallyResizeElements.length) return;  
390 - var element = this.helper || this.element;  
391 -  
392 - for (var i=0; i < this._proportionallyResizeElements.length; i++) {  
393 -  
394 - var prel = this._proportionallyResizeElements[i];  
395 -  
396 - if (!this.borderDif) {  
397 - var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],  
398 - p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];  
399 -  
400 - this.borderDif = $.map(b, function(v, i) {  
401 - var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;  
402 - return border + padding;  
403 - });  
404 - }  
405 -  
406 - if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))  
407 - continue;  
408 -  
409 - prel.css({  
410 - height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,  
411 - width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0  
412 - });  
413 -  
414 - };  
415 -  
416 - },  
417 -  
418 - _renderProxy: function() {  
419 -  
420 - var el = this.element, o = this.options;  
421 - this.elementOffset = el.offset();  
422 -  
423 - if(this._helper) {  
424 -  
425 - this.helper = this.helper || $('<div style="overflow:hidden;"></div>');  
426 -  
427 - // fix ie6 offset TODO: This seems broken  
428 - var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),  
429 - pxyoffset = ( ie6 ? 2 : -1 );  
430 -  
431 - this.helper.addClass(this._helper).css({  
432 - width: this.element.outerWidth() + pxyoffset,  
433 - height: this.element.outerHeight() + pxyoffset,  
434 - position: 'absolute',  
435 - left: this.elementOffset.left - ie6offset +'px',  
436 - top: this.elementOffset.top - ie6offset +'px',  
437 - zIndex: ++o.zIndex //TODO: Don't modify option  
438 - });  
439 -  
440 - this.helper  
441 - .appendTo("body")  
442 - .disableSelection();  
443 -  
444 - } else {  
445 - this.helper = this.element;  
446 - }  
447 -  
448 - },  
449 -  
450 - _change: {  
451 - e: function(event, dx, dy) {  
452 - return { width: this.originalSize.width + dx };  
453 - },  
454 - w: function(event, dx, dy) {  
455 - var o = this.options, cs = this.originalSize, sp = this.originalPosition;  
456 - return { left: sp.left + dx, width: cs.width - dx };  
457 - },  
458 - n: function(event, dx, dy) {  
459 - var o = this.options, cs = this.originalSize, sp = this.originalPosition;  
460 - return { top: sp.top + dy, height: cs.height - dy };  
461 - },  
462 - s: function(event, dx, dy) {  
463 - return { height: this.originalSize.height + dy };  
464 - },  
465 - se: function(event, dx, dy) {  
466 - return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));  
467 - },  
468 - sw: function(event, dx, dy) {  
469 - return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));  
470 - },  
471 - ne: function(event, dx, dy) {  
472 - return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));  
473 - },  
474 - nw: function(event, dx, dy) {  
475 - return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));  
476 - }  
477 - },  
478 -  
479 - _propagate: function(n, event) {  
480 - $.ui.plugin.call(this, n, [event, this.ui()]);  
481 - (n != "resize" && this._trigger(n, event, this.ui()));  
482 - },  
483 -  
484 - plugins: {},  
485 -  
486 - ui: function() {  
487 - return {  
488 - originalElement: this.originalElement,  
489 - element: this.element,  
490 - helper: this.helper,  
491 - position: this.position,  
492 - size: this.size,  
493 - originalSize: this.originalSize,  
494 - originalPosition: this.originalPosition  
495 - };  
496 - }  
497 -  
498 -}));  
499 -  
500 -$.extend($.ui.resizable, {  
501 - version: "1.7.2",  
502 - eventPrefix: "resize",  
503 - defaults: {  
504 - alsoResize: false,  
505 - animate: false,  
506 - animateDuration: "slow",  
507 - animateEasing: "swing",  
508 - aspectRatio: false,  
509 - autoHide: false,  
510 - cancel: ":input,option",  
511 - containment: false,  
512 - delay: 0,  
513 - distance: 1,  
514 - ghost: false,  
515 - grid: false,  
516 - handles: "e,s,se",  
517 - helper: false,  
518 - maxHeight: null,  
519 - maxWidth: null,  
520 - minHeight: 10,  
521 - minWidth: 10,  
522 - zIndex: 1000  
523 - }  
524 -}); 661 + if (/document/.test(oc) || oc == document) {
  662 + self.containerOffset = { left: 0, top: 0 };
  663 + self.containerPosition = { left: 0, top: 0 };
525 664
526 -/*  
527 - * Resizable Extensions  
528 - */  
529 -  
530 -$.ui.plugin.add("resizable", "alsoResize", {  
531 -  
532 - start: function(event, ui) {  
533 -  
534 - var self = $(this).data("resizable"), o = self.options;  
535 -  
536 - _store = function(exp) {  
537 - $(exp).each(function() {  
538 - $(this).data("resizable-alsoresize", {  
539 - width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),  
540 - left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)  
541 - });  
542 - });  
543 - };  
544 -  
545 - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {  
546 - if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }  
547 - else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }  
548 - }else{  
549 - _store(o.alsoResize);  
550 - }  
551 - },  
552 -  
553 - resize: function(event, ui){  
554 - var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;  
555 -  
556 - var delta = {  
557 - height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,  
558 - top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0  
559 - },  
560 -  
561 - _alsoResize = function(exp, c) {  
562 - $(exp).each(function() {  
563 - var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];  
564 -  
565 - $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {  
566 - var sum = (start[prop]||0) + (delta[prop]||0);  
567 - if (sum && sum >= 0)  
568 - style[prop] = sum || null;  
569 - });  
570 -  
571 - //Opera fixing relative position  
572 - if (/relative/.test(el.css('position')) && $.browser.opera) {  
573 - self._revertToRelativePosition = true;  
574 - el.css({ position: 'absolute', top: 'auto', left: 'auto' });  
575 - }  
576 -  
577 - el.css(style);  
578 - });  
579 - };  
580 -  
581 - if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {  
582 - $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });  
583 - }else{  
584 - _alsoResize(o.alsoResize);  
585 - }  
586 - },  
587 -  
588 - stop: function(event, ui){  
589 - var self = $(this).data("resizable");  
590 -  
591 - //Opera fixing relative position  
592 - if (self._revertToRelativePosition && $.browser.opera) {  
593 - self._revertToRelativePosition = false;  
594 - el.css({ position: 'relative' });  
595 - }  
596 -  
597 - $(this).removeData("resizable-alsoresize-start");  
598 - }  
599 -});  
600 -  
601 -$.ui.plugin.add("resizable", "animate", {  
602 -  
603 - stop: function(event, ui) {  
604 - var self = $(this).data("resizable"), o = self.options;  
605 -  
606 - var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),  
607 - soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,  
608 - soffsetw = ista ? 0 : self.sizeDiff.width;  
609 -  
610 - var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },  
611 - left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,  
612 - top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;  
613 -  
614 - self.element.animate(  
615 - $.extend(style, top && left ? { top: top, left: left } : {}), {  
616 - duration: o.animateDuration,  
617 - easing: o.animateEasing,  
618 - step: function() {  
619 -  
620 - var data = {  
621 - width: parseInt(self.element.css('width'), 10),  
622 - height: parseInt(self.element.css('height'), 10),  
623 - top: parseInt(self.element.css('top'), 10),  
624 - left: parseInt(self.element.css('left'), 10)  
625 - };  
626 -  
627 - if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });  
628 -  
629 - // propagating resize, and updating values for each animation step  
630 - self._updateCache(data);  
631 - self._propagate("resize", event);  
632 -  
633 - }  
634 - }  
635 - );  
636 - }  
637 -  
638 -});  
639 -  
640 -$.ui.plugin.add("resizable", "containment", {  
641 -  
642 - start: function(event, ui) {  
643 - var self = $(this).data("resizable"), o = self.options, el = self.element;  
644 - var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;  
645 - if (!ce) return;  
646 -  
647 - self.containerElement = $(ce);  
648 -  
649 - if (/document/.test(oc) || oc == document) {  
650 - self.containerOffset = { left: 0, top: 0 };  
651 - self.containerPosition = { left: 0, top: 0 };  
652 -  
653 - self.parentData = {  
654 - element: $(document), left: 0, top: 0,  
655 - width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight  
656 - };  
657 - }  
658 -  
659 - // i'm a node, so compute top, left, right, bottom  
660 - else {  
661 - var element = $(ce), p = [];  
662 - $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });  
663 -  
664 - self.containerOffset = element.offset();  
665 - self.containerPosition = element.position();  
666 - self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };  
667 -  
668 - var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,  
669 - width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);  
670 -  
671 - self.parentData = {  
672 - element: ce, left: co.left, top: co.top, width: width, height: height  
673 - };  
674 - }  
675 - }, 665 + self.parentData = {
  666 + element: $(document), left: 0, top: 0,
  667 + width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
  668 + };
  669 + }
676 670
677 - resize: function(event, ui) {  
678 - var self = $(this).data("resizable"), o = self.options,  
679 - ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,  
680 - pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;  
681 -  
682 - if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;  
683 -  
684 - if (cp.left < (self._helper ? co.left : 0)) {  
685 - self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));  
686 - if (pRatio) self.size.height = self.size.width / o.aspectRatio;  
687 - self.position.left = o.helper ? co.left : 0;  
688 - }  
689 -  
690 - if (cp.top < (self._helper ? co.top : 0)) {  
691 - self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);  
692 - if (pRatio) self.size.width = self.size.height * o.aspectRatio;  
693 - self.position.top = self._helper ? co.top : 0;  
694 - } 671 + // i'm a node, so compute top, left, right, bottom
  672 + else {
  673 + var element = $(ce), p = [];
  674 + $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) {
  675 + p[i] = num(element.css("padding" + name));
  676 + });
695 677
696 - self.offset.left = self.parentData.left+self.position.left;  
697 - self.offset.top = self.parentData.top+self.position.top;  
698 -  
699 - var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),  
700 - hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );  
701 -  
702 - var isParent = self.containerElement.get(0) == self.element.parent().get(0),  
703 - isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));  
704 -  
705 - if(isParent && isOffsetRelative) woset -= self.parentData.left;  
706 -  
707 - if (woset + self.size.width >= self.parentData.width) {  
708 - self.size.width = self.parentData.width - woset;  
709 - if (pRatio) self.size.height = self.size.width / self.aspectRatio;  
710 - }  
711 -  
712 - if (hoset + self.size.height >= self.parentData.height) {  
713 - self.size.height = self.parentData.height - hoset;  
714 - if (pRatio) self.size.width = self.size.height * self.aspectRatio;  
715 - }  
716 - },  
717 -  
718 - stop: function(event, ui){  
719 - var self = $(this).data("resizable"), o = self.options, cp = self.position,  
720 - co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;  
721 -  
722 - var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;  
723 -  
724 - if (self._helper && !o.animate && (/relative/).test(ce.css('position')))  
725 - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); 678 + self.containerOffset = element.offset();
  679 + self.containerPosition = element.position();
  680 + self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
726 681
727 - if (self._helper && !o.animate && (/static/).test(ce.css('position')))  
728 - $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });  
729 -  
730 - }  
731 -}); 682 + var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
  683 + width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
732 684
733 -$.ui.plugin.add("resizable", "ghost", {  
734 -  
735 - start: function(event, ui) { 685 + self.parentData = {
  686 + element: ce, left: co.left, top: co.top, width: width, height: height
  687 + };
  688 + }
  689 + },
736 690
737 - var self = $(this).data("resizable"), o = self.options, cs = self.size;  
738 -  
739 - self.ghost = self.originalElement.clone();  
740 - self.ghost  
741 - .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })  
742 - .addClass('ui-resizable-ghost')  
743 - .addClass(typeof o.ghost == 'string' ? o.ghost : '');  
744 -  
745 - self.ghost.appendTo(self.helper);  
746 -  
747 - },  
748 -  
749 - resize: function(event, ui){  
750 - var self = $(this).data("resizable"), o = self.options;  
751 - if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });  
752 - },  
753 -  
754 - stop: function(event, ui){  
755 - var self = $(this).data("resizable"), o = self.options;  
756 - if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));  
757 - }  
758 -  
759 -});  
760 -  
761 -$.ui.plugin.add("resizable", "grid", {  
762 -  
763 - resize: function(event, ui) {  
764 - var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;  
765 - o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;  
766 - 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);  
767 -  
768 - if (/^(se|s|e)$/.test(a)) {  
769 - self.size.width = os.width + ox;  
770 - self.size.height = os.height + oy;  
771 - }  
772 - else if (/^(ne)$/.test(a)) {  
773 - self.size.width = os.width + ox;  
774 - self.size.height = os.height + oy;  
775 - self.position.top = op.top - oy;  
776 - }  
777 - else if (/^(sw)$/.test(a)) {  
778 - self.size.width = os.width + ox;  
779 - self.size.height = os.height + oy;  
780 - self.position.left = op.left - ox;  
781 - }  
782 - else {  
783 - self.size.width = os.width + ox;  
784 - self.size.height = os.height + oy;  
785 - self.position.top = op.top - oy;  
786 - self.position.left = op.left - ox;  
787 - }  
788 - } 691 + resize: function(event, ui) {
  692 + var self = $(this).data("resizable"), o = self.options,
  693 + ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
  694 + pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
  695 +
  696 + if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
  697 +
  698 + if (cp.left < (self._helper ? co.left : 0)) {
  699 + self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
  700 + if (pRatio) self.size.height = self.size.width / o.aspectRatio;
  701 + self.position.left = o.helper ? co.left : 0;
  702 + }
  703 +
  704 + if (cp.top < (self._helper ? co.top : 0)) {
  705 + self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
  706 + if (pRatio) self.size.width = self.size.height * o.aspectRatio;
  707 + self.position.top = self._helper ? co.top : 0;
  708 + }
  709 +
  710 + self.offset.left = self.parentData.left + self.position.left;
  711 + self.offset.top = self.parentData.top + self.position.top;
  712 +
  713 + var woset = Math.abs((self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width),
  714 + hoset = Math.abs((self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height);
  715 +
  716 + var isParent = self.containerElement.get(0) == self.element.parent().get(0),
  717 + isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
  718 +
  719 + if (isParent && isOffsetRelative) woset -= self.parentData.left;
  720 +
  721 + if (woset + self.size.width >= self.parentData.width) {
  722 + self.size.width = self.parentData.width - woset;
  723 + if (pRatio) self.size.height = self.size.width / self.aspectRatio;
  724 + }
  725 +
  726 + if (hoset + self.size.height >= self.parentData.height) {
  727 + self.size.height = self.parentData.height - hoset;
  728 + if (pRatio) self.size.width = self.size.height * self.aspectRatio;
  729 + }
  730 + },
  731 +
  732 + stop: function(event, ui) {
  733 + var self = $(this).data("resizable"), o = self.options, cp = self.position,
  734 + co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
  735 +
  736 + var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
  737 +
  738 + if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
  739 + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  740 +
  741 + if (self._helper && !o.animate && (/static/).test(ce.css('position')))
  742 + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
  743 +
  744 + }
  745 + });
  746 +
  747 + $.ui.plugin.add("resizable", "ghost", {
  748 +
  749 + start: function(event, ui) {
  750 +
  751 + var self = $(this).data("resizable"), o = self.options, cs = self.size;
  752 +
  753 + self.ghost = self.originalElement.clone();
  754 + self.ghost
  755 + .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
  756 + .addClass('ui-resizable-ghost')
  757 + .addClass(typeof o.ghost == 'string' ? o.ghost : '');
  758 +
  759 + self.ghost.appendTo(self.helper);
  760 +
  761 + },
  762 +
  763 + resize: function(event, ui) {
  764 + var self = $(this).data("resizable"), o = self.options;
  765 + if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
  766 + },
  767 +
  768 + stop: function(event, ui) {
  769 + var self = $(this).data("resizable"), o = self.options;
  770 + if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
  771 + }
  772 +
  773 + });
  774 +
  775 + $.ui.plugin.add("resizable", "grid", {
  776 +
  777 + resize: function(event, ui) {
  778 + var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey;
  779 + o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
  780 + 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);
  781 +
  782 + if (/^(se|s|e)$/.test(a)) {
  783 + self.size.width = os.width + ox;
  784 + self.size.height = os.height + oy;
  785 + }
  786 + else if (/^(ne)$/.test(a)) {
  787 + self.size.width = os.width + ox;
  788 + self.size.height = os.height + oy;
  789 + self.position.top = op.top - oy;
  790 + }
  791 + else if (/^(sw)$/.test(a)) {
  792 + self.size.width = os.width + ox;
  793 + self.size.height = os.height + oy;
  794 + self.position.left = op.left - ox;
  795 + }
  796 + else {
  797 + self.size.width = os.width + ox;
  798 + self.size.height = os.height + oy;
  799 + self.position.top = op.top - oy;
  800 + self.position.left = op.left - ox;
  801 + }
  802 + }
789 803
790 -});  
791 -  
792 -var num = function(v) {  
793 - return parseInt(v, 10) || 0;  
794 -}; 804 + });
  805 +
  806 + var num = function(v) {
  807 + return parseInt(v, 10) || 0;
  808 + };
795 809
796 -var isNumber = function(value) {  
797 - return !isNaN(parseInt(value, 10));  
798 -}; 810 + var isNumber = function(value) {
  811 + return !isNaN(parseInt(value, 10));
  812 + };
799 813
800 })(jQuery); 814 })(jQuery);
@@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
16 <h:scripts>org.ajax4jsf.javascript.AjaxScript, 16 <h:scripts>org.ajax4jsf.javascript.AjaxScript,
17 /org/ajax4jsf/javascript/scripts/form.js, 17 /org/ajax4jsf/javascript/scripts/form.js,
18 /org/richfaces/renderkit/html/scripts/form.js, 18 /org/richfaces/renderkit/html/scripts/form.js,
  19 + /org/richfaces/renderkit/html/scripts/utils.js,
19 /org/richfaces/renderkit/html/scripts/jquery/jquery.js, 20 /org/richfaces/renderkit/html/scripts/jquery/jquery.js,
20 /org/richfaces/renderkit/html/scripts/ui.core.js, 21 /org/richfaces/renderkit/html/scripts/ui.core.js,
21 /org/richfaces/renderkit/html/scripts/ui.draggable.js, 22 /org/richfaces/renderkit/html/scripts/ui.draggable.js,
@@ -31,6 +32,6 @@ @@ -31,6 +32,6 @@
31 x:passThruWithExclusions="value,name,type,id"></div> 32 x:passThruWithExclusions="value,name,type,id"></div>
32 <input type="hidden" name="#{clientId}" id="#{clientId}"/> 33 <input type="hidden" name="#{clientId}" id="#{clientId}"/>
33 <script type="text/javascript"> 34 <script type="text/javascript">
34 - <f:call name = "writeInitFunction" /> 35 + <f:call name = "writeInitFunction"/>
35 </script> 36 </script>
36 </f:root> 37 </f:root>
Please register or login to post a comment