JBoss Rich Faces SVN: r16844 - root/framework/trunk/impl/src/main/resources/META-INF/resources.
by richfaces-svn-commits@lists.jboss.org
Author: pyaschenko
Date: 2010-04-29 10:11:41 -0400 (Thu, 29 Apr 2010)
New Revision: 16844
Modified:
root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces-queue.js
Log:
queue form search was added
Modified: root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces-queue.js
===================================================================
--- root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces-queue.js 2010-04-29 13:56:40 UTC (rev 16843)
+++ root/framework/trunk/impl/src/main/resources/META-INF/resources/richfaces-queue.js 2010-04-29 14:11:41 UTC (rev 16844)
@@ -2,7 +2,7 @@
* @author Pavel Yaschenko
*/
-(function(jQuery, richfaces, jsf) {
+(function($, richfaces, jsf) {
/**
* RichFaces Ajax container
@@ -58,14 +58,31 @@
this.source = source;
this.options = options || {};
this.queueOptions = {}
+ var id;
+
+ // find default options for QueueEntry
if (options.hasOwnProperty("queueId")) {
if (defaultQueueOptions[options.queueId]) {
- this.queueOptions = defaultQueueOptions[options.queueId];
+ id = options.queueId;
}
} else {
- // TODO: find form options or use view options
- this.queueOptions = defaultQueueOptions[DEFAULT_QUEUE_ID];
+ var element = richfaces.getDomElement(source);
+ var form;
+ if (element) {
+ element = $(element).closest("form");
+ if (element.length>0) {
+ form = element.get(0);
+ }
+ }
+ if (form && form.id && defaultQueueOptions[form.id]) {
+ id = form.id;
+ } else {
+ id = DEFAULT_QUEUE_ID;
+ }
}
+ if (id) {
+ this.queueOptions = defaultQueueOptions[id];
+ }
this.event = event;
//similarityGroupingId is mutable, thus we need special field for it
@@ -73,7 +90,7 @@
this.eventsCount = 1;
};
- jQuery.extend(QueueEntry.prototype, {
+ $.extend(QueueEntry.prototype, {
isIgnoreDupResponses: function() {
return this.options.ignoreDupResponses;
14 years, 10 months
JBoss Rich Faces SVN: r16843 - root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-04-29 09:56:40 -0400 (Thu, 29 Apr 2010)
New Revision: 16843
Modified:
root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java
Log:
Modified: root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java
===================================================================
--- root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java 2010-04-29 13:55:56 UTC (rev 16842)
+++ root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java 2010-04-29 13:56:40 UTC (rev 16843)
@@ -27,6 +27,7 @@
@Override
public void apply(FaceletContext ctx, UIComponent comp) throws IOException {
if(owner.isWrapping()) {
+ //TODO: anton create behavior and place it in BehaviorStack
owner.applyNextHandler(ctx, comp);
} else {
wrappedHandlerDelegate.apply(ctx, comp);
14 years, 10 months
JBoss Rich Faces SVN: r16842 - root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-04-29 09:55:56 -0400 (Thu, 29 Apr 2010)
New Revision: 16842
Modified:
root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js
Log:
attachToDom support
Modified: root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js
===================================================================
--- root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js 2010-04-29 13:20:27 UTC (rev 16841)
+++ root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js 2010-04-29 13:55:56 UTC (rev 16842)
@@ -53,8 +53,9 @@
richfaces.ui.DataScroller = function(id, submit, options) {
$super.constructor.call(this,id);
- this.attachToDom.call(this, id);
+ $p.attachToDom.call(this, id);
+
this.options = options;
this.currentPage = options.currentPage;
var buttons = options.buttons;
@@ -92,6 +93,8 @@
};
var $super = richfaces.BaseComponent.extend(richfaces.BaseComponent, richfaces.ui.DataScroller);
+ var $p = richfaces.BaseComponent.extend(richfaces.BaseComponent,richfaces.ui.DataScroller, {});
+ var $super = richfaces.ui.DataScroller.$super;
$.extend(richfaces.ui.DataScroller.prototype, (function (options) {
14 years, 10 months
JBoss Rich Faces SVN: r16841 - in root/examples-sandbox/trunk/components/tables/src/main: java/org/richfaces/demo/utils and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-04-29 09:20:27 -0400 (Thu, 29 Apr 2010)
New Revision: 16841
Modified:
root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java
root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/utils/EmployeeUtils.java
root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml
Log:
Modified: root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java
===================================================================
--- root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java 2010-04-29 12:31:50 UTC (rev 16840)
+++ root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/DataBean.java 2010-04-29 13:20:27 UTC (rev 16841)
@@ -21,6 +21,47 @@
Map<Object,Integer> stateMap = new HashMap<Object, Integer>();
+ private String test1 = "test1";
+
+ private String test2 = "test2";
+
+ private String target = "targetId";
+
+ private String operation = "operation";
+
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public String getOperation() {
+ return operation;
+ }
+
+ public void setOperation(String operation) {
+ this.operation = operation;
+ }
+
+ public String getTest1() {
+ return test1;
+ }
+
+ public void setTest1(String test1) {
+ this.test1 = test1;
+ }
+
+ public String getTest2() {
+ return test2;
+ }
+
+ public void setTest2(String test2) {
+ this.test2 = test2;
+ }
+
int page = 1;
public int getPage() {
Modified: root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/utils/EmployeeUtils.java
===================================================================
--- root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/utils/EmployeeUtils.java 2010-04-29 12:31:50 UTC (rev 16840)
+++ root/examples-sandbox/trunk/components/tables/src/main/java/org/richfaces/demo/utils/EmployeeUtils.java 2010-04-29 13:20:27 UTC (rev 16841)
@@ -14,7 +14,7 @@
List<Employee> employeeList = new ArrayList<Employee>();
addEmployeeToCollection(employeeList, "9Alexander Ivanov", "Director", "aivanov(a)beltelecom.by", "AMicrosoft", "+375 29 255 00 00", "Minsk, Belarus");
- addEmployeeToCollection(employeeList, "4Bill Gates", "President", "bgates(a)microsoft.com", "AMicrosoft", "817-335-5881", "Tokyo, Japan");
+ addEmployeeToCollection(employeeList, "4Bill Gates", "President", "bgates(a)microsoft.com", "AMicrosoft", "817-335-5881", "Tokyo, Japan");
addEmployeeToCollection(employeeList, "Amanda Gellhouse", "IT/Internet Support; Manager", "agellhouse(a)sun.com", "Sun", "853-729-3784", "Sun Valley, USA");
addEmployeeToCollection(employeeList, "2Hideo Kodzima", "Vice Prezident", "khideo(a)konami.jp", "AMicrosoft", "419-615-2730", "Tokyo, Japan");
addEmployeeToCollection(employeeList, "3Stan Carpenter", "Lead Designer", "scarpenter(a)ndogs.com", "AMicrosoft", "714-647-3380", "Tokyo, Japan");
@@ -633,7 +633,7 @@
addEmployeeToCollection(employeeList, "Daniel Crespo", "IT/Internet Support; Analyst", "dcrespo(a)bokken.com", "Bokken As", "+91-22-6659-7300", "Wien, Austria");
addEmployeeToCollection(employeeList, "Petr Cumba", "IT-chef", "pcumba(a)abarta.com", "ABARTA, Inc.", "701-277-0403", "Liberal, KS United States");
addEmployeeToCollection(employeeList, "James Curley", "Network Manager", "jcurley(a)triboro.com", "Triboro Gulf", "+047-52020000", "Nesflaten, Rogaland Norway");
- addEmployeeToCollection(employeeList, "Lu Dam", "SVP Operations and Technical", "ludam(a)krepro.com", "Krepro As", "313-876-0190", "Walters, OK United States");
+ addEmployeeToCollection(employeeList, "Lu Dam", "SVP Operations and Technical", "ludam(a)krepro.com", "Krepro As", "313-876-0190", "Walters, OK United States");/*
addEmployeeToCollection(employeeList, "Randy Davenport", "Database Administrator", "rdevenport(a)savatrip.com", "Sav-A-Trip, Inc", "+032-38807700", "Adelaide, Australia");
addEmployeeToCollection(employeeList, "Kevin A. Kohlscheen", "Computer Specialist", "kakohlscheen(a)eni.com", "Eni S.p.A.", "+031-455223300", "Andria, Bari Italy");
addEmployeeToCollection(employeeList, "M Koetsier", "Programmer", "mkoetsier(a)pinnergy.com", "Pinnergy Ltd", "316-838-4663", "Moscow, Russia");
@@ -1345,7 +1345,7 @@
addEmployeeToCollection(employeeList, "Andy Kirkham", "VP Administration", "akirkham(a)pacificorp.com", "Pacificorp", "561-642-2153", "Ashton, ID United States");
addEmployeeToCollection(employeeList, "Derrik Khoo Sin Huat", "CTO", "aksinhuat(a)aes.com", "The AES Corporation", "864-233-4064", "Sydney, Australia");
addEmployeeToCollection(employeeList, "Rick Kelsven", "Network Analyst", "rkelsven(a)rudny.com", "Rudny's Inc", "208-356-4991", "Bangkok, Thailand");
-
+*/
return employeeList;
}
Modified: root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml
===================================================================
--- root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml 2010-04-29 12:31:50 UTC (rev 16840)
+++ root/examples-sandbox/trunk/components/tables/src/main/webapp/home.xhtml 2010-04-29 13:20:27 UTC (rev 16841)
@@ -5,6 +5,8 @@
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:ds="http://richfaces.org/datascroller"
+ xmlns:cc="http://richfaces.org/componentControl"
+
>
<f:view contentType="text/html"/>
@@ -27,7 +29,11 @@
<f:facet name="header">
<h:outputText id="columnHeader1" value="Column Header Facet"/>
</f:facet>
-
+
+ <rich:toggleControl for="expandedSubTable" expandControl="resources/images/+.gif" collapseControl="resources/images/-.gif">
+
+ </rich:toggleControl>
+
<h:outputText value="#{record.name}" />
<f:facet name="footer">
<h:outputText id="columnFooter1" value="Column Footer Facet 1"/>
@@ -47,7 +53,7 @@
<rich:subTable id="expandedSubTable" var="company" value="#{record.companies}" rows="1" switchType="ajax" expanded="true">
<f:facet name="header">
- <ds:dataScroller id="subscroller" for="expandedSubTable" page="#{dataBean.stateMap[rowKey]}" maxPages="3"></ds:dataScroller >
+ <ds:dataScroller id="subscroller" for="expandedSubTable" maxPages="3"></ds:dataScroller >
</f:facet>
<f:facet name="footer">
@@ -74,7 +80,36 @@
</rich:dataTable>
<br/>
- <h:commandButton value="submit" />
+
+ <!-- cc:componentControl event="click" target="#{dataBean.target}" operation="#{dataBean.operation}">
+ <f:param name="event" value="event"/>
+ <cc:hashParameter>
+ <f:param name="key1" value="value1"/>
+ <f:param name="key2" value="value2"/>
+ <f:param name="key3" value="value3"/>
+ <cc:hashParameter name="nested1">
+ <f:param name="key11" value="value11"/>
+ </cc:hashParameter>
+ </cc:hashParameter>
+ <cc:hashParameter name="hashkey1">
+ <f:param name="keyhash1" value="value1"/>
+ <f:param name="keyhash2" value="value2"/>
+ </cc:hashParameter>
+ <h:commandButton value="richfaces1"/>
+ <h:commandButton value="richfaces2"/>
+ </cc:componentControl -->
+
+
+ <h:commandButton value="next">
+ <cc:componentControl event="click" target="form1:scroller1" operation="switchToPage">
+ <f:param value="fastforward"/>
+ </cc:componentControl>
+ </h:commandButton>
+
+ <h:commandButton value="previous">
+ <cc:componentControl event="click" target="form1:scroller1" operation="previous"/>
+ </h:commandButton>
+
</h:form>
</h:body>
</html>
14 years, 10 months
JBoss Rich Faces SVN: r16840 - root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-04-29 08:31:50 -0400 (Thu, 29 Apr 2010)
New Revision: 16840
Added:
root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/CustomBehaviorHandler.java
Log:
base hadler for the behaviors
Added: root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/CustomBehaviorHandler.java
===================================================================
--- root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/CustomBehaviorHandler.java (rev 0)
+++ root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/CustomBehaviorHandler.java 2010-04-29 12:31:50 UTC (rev 16840)
@@ -0,0 +1,29 @@
+package org.richfaces.tag;
+
+import javax.faces.view.facelets.BehaviorConfig;
+import javax.faces.view.facelets.BehaviorHandler;
+import javax.faces.view.facelets.TagHandlerDelegate;
+
+
+/**
+ * @author Anton Belevich
+ *
+ */
+public abstract class CustomBehaviorHandler extends BehaviorHandler {
+
+ TagHandlerDelegate helper;
+
+ public CustomBehaviorHandler(BehaviorConfig config) {
+ super(config);
+ }
+
+ public abstract boolean isWrapping();
+
+ @Override
+ protected TagHandlerDelegate getTagHandlerDelegate() {
+ if(helper == null) {
+ helper = new BehaviorTagHandlerDelegate(this, delegateFactory.createBehaviorHandlerDelegate(this));
+ }
+ return helper;
+ }
+}
14 years, 10 months
JBoss Rich Faces SVN: r16839 - in root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces: renderkit and 2 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-04-29 08:17:51 -0400 (Thu, 29 Apr 2010)
New Revision: 16839
Modified:
root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/component/behavior/ComponentControlBehavior.java
root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/renderkit/ComponentControlBehaviorRenderer.java
root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorRule.java
root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java
root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/taglib/ComponentControlHandler.java
Log:
add comments, wrapping support
Modified: root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/component/behavior/ComponentControlBehavior.java
===================================================================
--- root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/component/behavior/ComponentControlBehavior.java 2010-04-29 12:16:33 UTC (rev 16838)
+++ root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/component/behavior/ComponentControlBehavior.java 2010-04-29 12:17:51 UTC (rev 16839)
@@ -6,6 +6,10 @@
import javax.faces.component.UIComponent;
import javax.faces.component.behavior.FacesBehavior;
+/**
+ * @author Anton Belevich
+ *
+ */
@FacesBehavior(value="org.richfaces.behavior.ComponentControlBehavior")
public class ComponentControlBehavior extends ClientBehavior {
Modified: root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/renderkit/ComponentControlBehaviorRenderer.java
===================================================================
--- root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/renderkit/ComponentControlBehaviorRenderer.java 2010-04-29 12:16:33 UTC (rev 16838)
+++ root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/renderkit/ComponentControlBehaviorRenderer.java 2010-04-29 12:17:51 UTC (rev 16839)
@@ -23,6 +23,10 @@
import org.richfaces.component.behavior.ComponentControlBehavior;
+/**
+ * @author Anton Belevich
+ *
+ */
@FacesBehaviorRenderer(rendererType="org.richfaces.behavior.ComponentControlBehavior", renderKitId=RenderKitFactory.HTML_BASIC_RENDER_KIT)
@ResourceDependencies( {@ResourceDependency(library = "javax.faces", name = "jsf.js"),
@ResourceDependency(name = "jquery.js"),
Modified: root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorRule.java
===================================================================
--- root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorRule.java 2010-04-29 12:16:33 UTC (rev 16838)
+++ root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorRule.java 2010-04-29 12:17:51 UTC (rev 16839)
@@ -10,6 +10,10 @@
import org.richfaces.log.RichfacesLogger;
import org.slf4j.Logger;
+/**
+ * @author Anton Belevich
+ *
+ */
public class BehaviorRule extends MetaRule {
private static Logger log = RichfacesLogger.CONNECTION.getLogger();
Modified: root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java
===================================================================
--- root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java 2010-04-29 12:16:33 UTC (rev 16838)
+++ root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/tag/BehaviorTagHandlerDelegate.java 2010-04-29 12:17:51 UTC (rev 16839)
@@ -5,25 +5,32 @@
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.view.AttachedObjectHandler;
-import javax.faces.view.facelets.BehaviorHandler;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.MetaRuleset;
import javax.faces.view.facelets.TagHandlerDelegate;
+/**
+ * @author Anton Belevich
+ *
+ */
public class BehaviorTagHandlerDelegate extends TagHandlerDelegate implements AttachedObjectHandler {
TagHandlerDelegate wrappedHandlerDelegate;
- BehaviorHandler owner;
+ CustomBehaviorHandler owner;
- public BehaviorTagHandlerDelegate(BehaviorHandler owner, TagHandlerDelegate wrappedHandlerDelegate) {
+ public BehaviorTagHandlerDelegate(CustomBehaviorHandler owner, TagHandlerDelegate wrappedHandlerDelegate) {
this.owner = owner;
this.wrappedHandlerDelegate = wrappedHandlerDelegate;
}
@Override
public void apply(FaceletContext ctx, UIComponent comp) throws IOException {
- wrappedHandlerDelegate.apply(ctx, comp);
+ if(owner.isWrapping()) {
+ owner.applyNextHandler(ctx, comp);
+ } else {
+ wrappedHandlerDelegate.apply(ctx, comp);
+ }
}
@Override
Modified: root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/taglib/ComponentControlHandler.java
===================================================================
--- root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/taglib/ComponentControlHandler.java 2010-04-29 12:16:33 UTC (rev 16838)
+++ root/ui-sandbox/trunk/components/componentcontrol/src/main/java/org/richfaces/taglib/ComponentControlHandler.java 2010-04-29 12:17:51 UTC (rev 16839)
@@ -20,6 +20,10 @@
import org.richfaces.component.behavior.ComponentControlBehavior;
import org.richfaces.tag.CustomBehaviorHandler;
+/**
+ * @author Anton Belevich
+ *
+ */
public class ComponentControlHandler extends CustomBehaviorHandler {
public ComponentControlHandler(BehaviorConfig config) {
@@ -85,5 +89,10 @@
private boolean isUIParameter(String type) {
return (UIParameter.COMPONENT_TYPE.equals(type) || UIHashParameter.COMPONENT_TYPE.equals(type));
}
+
+ @Override
+ public boolean isWrapping() {
+ return false;
+ }
}
14 years, 10 months
JBoss Rich Faces SVN: r16838 - in root/ui-sandbox/trunk/components/datascroller/ui/src/main: resources/META-INF/resources/css and 2 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-04-29 08:16:33 -0400 (Thu, 29 Apr 2010)
New Revision: 16838
Modified:
root/ui-sandbox/trunk/components/datascroller/ui/src/main/java/org/richfaces/renderkit/DataScrollerBaseRenderer.java
root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/css/datascroller.css
root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js
root/ui-sandbox/trunk/components/datascroller/ui/src/main/templates/datascroller.template.xml
Log:
use <a> instead of <span>
Modified: root/ui-sandbox/trunk/components/datascroller/ui/src/main/java/org/richfaces/renderkit/DataScrollerBaseRenderer.java
===================================================================
--- root/ui-sandbox/trunk/components/datascroller/ui/src/main/java/org/richfaces/renderkit/DataScrollerBaseRenderer.java 2010-04-29 03:42:51 UTC (rev 16837)
+++ root/ui-sandbox/trunk/components/datascroller/ui/src/main/java/org/richfaces/renderkit/DataScrollerBaseRenderer.java 2010-04-29 12:16:33 UTC (rev 16838)
@@ -204,7 +204,7 @@
styleClass="";
}
- out.startElement(HTML.SPAN_ELEM, component);
+ out.startElement(HTML.A_ELEMENT, component);
if (isCurrentPage) {
out.writeAttribute(HTML.CLASS_ATTRIBUTE, "ds_digital ds_current " + styleClass, null);
@@ -212,6 +212,9 @@
out.writeAttribute(HTML.CLASS_ATTRIBUTE, "ds_digital " + styleClass, null);
}
+ out.writeAttribute(HTML.HREF_ATTR, "javascript:void(0);", null);
+
+
if (null != style) {
out.writeAttribute(HTML.STYLE_ATTRIBUTE, style, null);
}
@@ -224,7 +227,7 @@
digital.put(id, page);
out.writeText(page, null);
- out.endElement(HTML.SPAN_ELEM);
+ out.endElement(HTML.A_ELEMENT);
}
return digital;
@@ -293,7 +296,6 @@
StringBuffer buffer = new StringBuffer();
function.appendScript(buffer);
-
definition.addToBody(buffer);
return definition;
}
Modified: root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/css/datascroller.css
===================================================================
--- root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/css/datascroller.css 2010-04-29 03:42:51 UTC (rev 16837)
+++ root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/css/datascroller.css 2010-04-29 12:16:33 UTC (rev 16838)
@@ -20,6 +20,8 @@
font-size : 11px/*generalSizeFont*/;
font-family : verdana/*generalFamilyFont*/;
color : #000000/*generalTextColor*/;
+ text-decoration:none;
+ font-weight: normal;
}
.ds_left{
@@ -42,8 +44,11 @@
background : url(images/bg_field.png) top left repeat-x/*gradient - from additionalBackgroundColor to tableBackgroundColor, background-color - tableBackgroundColor*/;
display : inline-block;
font-size : 11px/*generalSizeFont*/;
- font-family : verdana/*generalFamilyFont*/;
+ font-family : verdana/*generalFamilyFont*/;
+ text-decoration:none;
color : #000000/*generalTextColor*/;
+ font-weight: normal;
+
}
.ds_over{
Modified: root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js
===================================================================
--- root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js 2010-04-29 03:42:51 UTC (rev 16837)
+++ root/ui-sandbox/trunk/components/datascroller/ui/src/main/resources/META-INF/resources/script/datascroller.js 2010-04-29 12:16:33 UTC (rev 16838)
@@ -2,16 +2,62 @@
richfaces.ui = richfaces.ui || {};
- richfaces.ui.DataScroller = function(id, submit, options) {
+ var initButtons = function(buttons, css, component) {
+ var id;
+
+ var fn = function(e) {
+ e.data.fn.call(e.data.component, e);
+ }
+
+ var data = {};
+ data.component = component;
+
+ for(id in buttons) {
+ var element = $(document.getElementById(id));
+
+ data.id = id;
+ data.page = buttons[id];
+ data.element = element;
+ data.fn = component.processClick;
+
+ element.bind('click', copy(data), fn);
+
+ if(css) {
+ data.fn = component.processStyles;
+ data.css = css.mousedown;
+ element.bind('mousedown', copy(data), fn);
+
+ data.css = css.mouseup;
+ element.bind('mouseup', copy(data), fn);
+
+ data.css = css.mouseout;
+ element.bind('mouseout', copy(data), fn);
+
+ data.css = css.mouseover;
+ element.bind('mouseover', copy(data), fn);
+ }
+ }
+ };
+
+ var copy = function(data) {
+ var key;
+ var eventData = {};
+
+ for (key in data) {
+ eventData[key] = data[key];
+ }
+
+ return eventData;
+ };
+
+ richfaces.ui.DataScroller = function(id, submit, options) {
$super.constructor.call(this,id);
-
this.attachToDom.call(this, id);
this.options = options;
this.currentPage = options.currentPage;
-
- var buttons = options.buttons;
+ var buttons = options.buttons;
var digitals = options.digitals;
if (submit && typeof submit == 'function') {
@@ -26,16 +72,14 @@
css.mouseup = "ds_button ds_left";
css.mouseout = "ds_button ds_left";
css.mousedown = "ds_button ds_left ds_over";
-
- this.initButtons(leftButtons,css);
+ initButtons(leftButtons,css, this);
var rightButtons = buttons.right;
css.mouseover = "ds_button ds_right ds_over";
css.mouseup = "ds_button ds_right";
css.mouseout = "ds_button ds_right";
css.mousedown = "ds_button ds_right ds_over";
-
- this.initButtons(rightButtons,css);
+ initButtons(rightButtons,css, this);
}
if(digitals) {
@@ -43,95 +87,41 @@
css.mouseup= "ds_digital ds_over";
css.mouseout = "ds_digital";
css.mousedown="ds_digital ds_press";
-
- this.initButtons(digitals,css);
+ initButtons(digitals, css,this);
}
};
var $super = richfaces.BaseComponent.extend(richfaces.BaseComponent, richfaces.ui.DataScroller);
$.extend(richfaces.ui.DataScroller.prototype, (function (options) {
-
- var copy = function(data) {
- var key;
- var eventData = {};
-
- for (key in data) {
- eventData[key] = data[key];
- }
-
- return eventData;
- };
-
- var processStyles = function(event) {
- var data = event.data;
-
- if(data && (data.page != this.currentPage)) {
- var element = data.element;
- var css = data.css;
-
- if(element && css) {
- element.attr('class', css);
- }
- }
-
- };
-
- var processClick = function(event) {
- var data = event.data;
-
- if(data) {
- var page = data.page;
- if(page) {
- this.switchToPage(page);
- }
- }
- }
-
- var scrollEventName = "rich:datascroller:onscroll";
+
+ var scrollEventName = "rich:datascroller:onscroll";
return {
name: "RichFaces.ui.DataScroller",
+
+ processClick: function(event) {
+ var data = event.data;
+ if(data) {
+ var page = data.page;
+ if(page) {
+ this.switchToPage(page);
+ }
+ }
+ },
- initButtons: function(buttons, css) {
+ processStyles: function(event) {
+ var data = event.data;
- var id;
-
- var fn = function(e) {
- e.data.fn.call(e.data.component, e, this);
+ if(data && (data.page != this.currentPage)) {
+ var element = data.element;
+ var css = data.css;
+
+ if(element && css) {
+ element.attr('class', css);
+ }
}
-
- var data = {};
- data.component = this;
-
- for(id in buttons) {
-
- var element = $(document.getElementById(id));
-
- data.id = id;
- data.page = buttons[id];
- data.element = element;
- data.fn = processClick;
-
- element.bind('click', copy(data), fn);
-
- if(css) {
- data.fn = processStyles;
-
- data.css = css.mousedown;
- element.bind('mousedown', copy(data), fn);
-
- data.css = css.mouseup;
- element.bind('mouseup', copy(data), fn);
-
- data.css = css.mouseout;
- element.bind('mouseout', copy(data), fn);
-
- data.css = css.mouseover;
- element.bind('mouseover', copy(data), fn);
- }
- }
},
switchToPage: function(page) {
Modified: root/ui-sandbox/trunk/components/datascroller/ui/src/main/templates/datascroller.template.xml
===================================================================
--- root/ui-sandbox/trunk/components/datascroller/ui/src/main/templates/datascroller.template.xml 2010-04-29 03:42:51 UTC (rev 16837)
+++ root/ui-sandbox/trunk/components/datascroller/ui/src/main/templates/datascroller.template.xml 2010-04-29 12:16:33 UTC (rev 16838)
@@ -20,14 +20,14 @@
<c:if test="#{controlsState.firstRendered}">
<c:choose>
<c:when test="#{controlsState.firstEnabled}">
- <span id="#{clientId}_ds_f" class="ds_button ds_left" >
+ <a id="#{clientId}_ds_f" class="ds_button ds_left" href="javascript:void(0)" >
««
- </span>
+ </a>
</c:when>
<c:otherwise>
- <span id="#{clientId}_ds_f" class="ds_button ds_left ds_disabled">
+ <a id="#{clientId}_ds_f" class="ds_button ds_left ds_disabled" href="javascript:void(0)">
««
- </span>
+ </a>
</c:otherwise>
</c:choose>
</c:if>
@@ -36,14 +36,14 @@
<c:if test="#{controlsState.fastRewindRendered}">
<c:choose>
<c:when test="#{controlsState.fastRewindEnabled}">
- <span id="#{clientId}_ds_fr" class="ds_button ds_left">
+ <a id="#{clientId}_ds_fr" class="ds_button ds_left" href="javascript:void(0)">
«
- </span>
+ </a>
</c:when>
<c:otherwise>
- <span id="#{clientId}_ds_fr" class="ds_button ds_left ds_disabled">
+ <a id="#{clientId}_ds_fr" class="ds_button ds_left ds_disabled" href="javascript:void(0)">
«
- </span>
+ </a>
</c:otherwise>
</c:choose>
</c:if>
@@ -53,14 +53,14 @@
<c:if test="#{controlsState.fastForwardRendered}">
<c:choose>
<c:when test="#{controlsState.fastForwardEnabled}">
- <span id="#{clientId}_ds_ff" class="ds_button ds_right">
+ <a id="#{clientId}_ds_ff" class="ds_button ds_right" href="javascript:void(0)">
»
- </span>
+ </a>
</c:when>
<c:otherwise>
- <span id="#{clientId}_ds_ff" class="ds_button ds_right ds_disabled">
+ <a id="#{clientId}_ds_ff" class="ds_button ds_right ds_disabled" href="javascript:void(0)">
»
- </span>
+ </a>
</c:otherwise>
</c:choose>
</c:if>
@@ -68,14 +68,14 @@
<c:if test="#{controlsState.lastRendered}">
<c:choose>
<c:when test="#{controlsState.lastEnabled}">
- <span id="#{clientId}_ds_l" class="ds_button ds_right">
+ <a id="#{clientId}_ds_l" class="ds_button ds_right" href="javascript:void(0)">
»»
- </span>
+ </a>
</c:when>
<c:otherwise>
- <span id="#{clientId}_ds_l" class="ds_button ds_right ds_disabled">
+ <a id="#{clientId}_ds_l" class="ds_button ds_right ds_disabled" href="javascript:void(0)">
»»
- </span>
+ </a>
</c:otherwise>
</c:choose>
</c:if>
14 years, 10 months
JBoss Rich Faces SVN: r16837 - branches/enterprise/3.3.X/docs/userguide/en/src/main/docbook/modules.
by richfaces-svn-commits@lists.jboss.org
Author: SeanRogers
Date: 2010-04-28 23:42:51 -0400 (Wed, 28 Apr 2010)
New Revision: 16837
Modified:
branches/enterprise/3.3.X/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml
Log:
Adding note on circular references (RFPL-562)
Modified: branches/enterprise/3.3.X/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml
===================================================================
--- branches/enterprise/3.3.X/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml 2010-04-29 03:34:21 UTC (rev 16836)
+++ branches/enterprise/3.3.X/docs/userguide/en/src/main/docbook/modules/RFCarchitectover.xml 2010-04-29 03:42:51 UTC (rev 16837)
@@ -188,6 +188,18 @@
Render Response Phase <property>RichFaces</property> framework makes a traversal
of the component tree, calls its own renderer and put the result into the Faces
Response. </para>
+ </listitem>
+ <listitem>
+ <para>
+ Certain components in the <property>RichFaces</property> framework allow data to be serialized and transferred from the server to the client. If the data model being used contains circular references, serialization of the data fails due to a stack overflow.
+ </para>
+ <para>
+ Circular references are unsupported and should be avoided; however, <xref linkend="Avoiding_Circular_References" /> shows how to prevent a stack overflow due to circular references. Serialization of the data is done from the top-most object down, and circular references back to parent objects are ignored. Access to non-serialized references to parent objects is not available using this method.
+ </para>
+ <example id="Avoiding_Circular_References">
+ <title>Avoiding Circular References</title>
+ <programlisting language="XML" role="XML">Code sample</programlisting>
+ </example>
</listitem>
</itemizedlist>
</section>
14 years, 10 months
JBoss Rich Faces SVN: r16836 - branches/enterprise/3.3.X/docs/common-resources.
by richfaces-svn-commits@lists.jboss.org
Author: SeanRogers
Date: 2010-04-28 23:34:21 -0400 (Wed, 28 Apr 2010)
New Revision: 16836
Modified:
branches/enterprise/3.3.X/docs/common-resources/pom.xml
Log:
Adding note on circular references (RFPL-562)
Modified: branches/enterprise/3.3.X/docs/common-resources/pom.xml
===================================================================
--- branches/enterprise/3.3.X/docs/common-resources/pom.xml 2010-04-29 01:40:35 UTC (rev 16835)
+++ branches/enterprise/3.3.X/docs/common-resources/pom.xml 2010-04-29 03:34:21 UTC (rev 16836)
@@ -26,4 +26,4 @@
</plugins>
</pluginManagement>
</build-->
-</project>
\ No newline at end of file
+</project>
14 years, 10 months
JBoss Rich Faces SVN: r16835 - in branches/community/3.3.X/sandbox/samples: full-calendar and 7 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-04-28 21:40:35 -0400 (Wed, 28 Apr 2010)
New Revision: 16835
Added:
branches/community/3.3.X/sandbox/samples/full-calendar/
branches/community/3.3.X/sandbox/samples/full-calendar/pom.xml
branches/community/3.3.X/sandbox/samples/full-calendar/src/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/ComponentBean.java
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/FullCalendarAjaxEvent.java
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/UIFullCalendar.java
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/resources/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/faces-config.xml
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/web.xml
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/fullcalendar.js
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/index.jsp
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/jquery.js
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/page.xhtml
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/richfaces.fullcalendar.js
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.core.js
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.draggable.js
branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.resizable.js
Log:
Prototype for schedule component: http://community.jboss.org/message/539813#539813 check-in
Added: branches/community/3.3.X/sandbox/samples/full-calendar/pom.xml
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/pom.xml (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/pom.xml 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,143 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces.demo</groupId>
+ <artifactId>full-calendar</artifactId>
+ <packaging>war</packaging>
+ <version>1.0-SNAPSHOT</version>
+
+ <properties>
+ <rfVersion>3.3.3.Final</rfVersion>
+ </properties>
+
+
+ <repositories>
+ <repository>
+ <id>jboss.org</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </repository>
+ <repository>
+ <id>maven-repository2.dev.java.net</id>
+ <url>http://download.java.net/maven/2</url>
+ </repository>
+ <repository>
+ <id>maven-repository1.dev.java.net</id>
+ <url>http://download.java.net/maven/1</url>
+ <layout>legacy</layout>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>jboss.org</id>
+ <url>http://repository.jboss.org/maven2</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>maven-jetty-plugin</artifactId>
+ <version>6.1.5</version>
+ <configuration>
+ <scanIntervalSeconds>10</scanIntervalSeconds>
+ <connectors>
+ <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+ <port>8081</port>
+ <maxIdleTime>60000</maxIdleTime>
+ </connector>
+ </connectors>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-eclipse-plugin</artifactId>
+ <version>2.7</version>
+ <configuration>
+ <wtpversion>2.0</wtpversion>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <version>1.2_14</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>1.2_14</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui</artifactId>
+ <version>${rfVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.framework</groupId>
+ <artifactId>richfaces-impl</artifactId>
+ <version>${rfVersion}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.facelets</groupId>
+ <artifactId>jsf-facelets</artifactId>
+ <version>1.1.15.B1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>javax.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>2.5</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <version>1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/ComponentBean.java
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/ComponentBean.java (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/ComponentBean.java 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,17 @@
+package demo.beans;
+
+import javax.faces.component.UIComponent;
+
+public class ComponentBean {
+
+ private UIComponent component = new UIFullCalendar();
+
+ public UIComponent getComponent() {
+ return component;
+ }
+
+ public void setComponent(UIComponent component) {
+ this.component = component;
+ }
+
+}
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/FullCalendarAjaxEvent.java
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/FullCalendarAjaxEvent.java (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/FullCalendarAjaxEvent.java 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,32 @@
+package demo.beans;
+
+
+import java.util.Date;
+
+import javax.faces.component.UIComponent;
+
+import org.ajax4jsf.event.AjaxEvent;
+
+public class FullCalendarAjaxEvent extends AjaxEvent {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3588719931853540807L;
+
+ private Date startDate;
+
+ private Date endDate;
+
+ public FullCalendarAjaxEvent(UIComponent component, Date startDate, Date endDate) {
+ super(component);
+ }
+
+ public Date getStartDate() {
+ return startDate;
+ }
+
+ public Date getEndDate() {
+ return endDate;
+ }
+}
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/UIFullCalendar.java
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/UIFullCalendar.java (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/java/demo/beans/UIFullCalendar.java 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,188 @@
+package demo.beans;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIComponentBase;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.FacesEvent;
+
+import org.ajax4jsf.context.AjaxContext;
+import org.ajax4jsf.javascript.JSFunction;
+import org.ajax4jsf.javascript.JSFunctionDefinition;
+import org.ajax4jsf.javascript.JSObject;
+import org.ajax4jsf.javascript.JSReference;
+import org.ajax4jsf.renderkit.AjaxRendererUtils;
+import org.ajax4jsf.renderkit.RendererUtils.HTML;
+
+public class UIFullCalendar extends UIComponentBase {
+
+ private static final String CALLBACK = "callback";
+ private static final String END_DATE = "endDate";
+ private static final String START_DATE = "startDate";
+
+ @Override
+ public String getFamily() {
+ return null;
+ }
+
+ private Object createAjaxFunction(FacesContext context) {
+ JSFunction ajaxFunction = AjaxRendererUtils.buildAjaxFunction(this,
+ context);
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.put(START_DATE, new JSReference(START_DATE));
+ params.put(END_DATE, new JSReference(END_DATE));
+
+ Map<String, Object> eventOptions = AjaxRendererUtils.buildEventOptions(
+ context, this, params, true);
+ eventOptions.put("oncomplete", new JSReference(CALLBACK));
+
+ ajaxFunction.addParameter(eventOptions);
+
+ return new JSFunctionDefinition("event", START_DATE, END_DATE, CALLBACK)
+ .addToBody(ajaxFunction);
+ }
+
+ @Override
+ public void decode(FacesContext context) {
+ if (!this.isRendered()) {
+ return;
+ }
+
+ Map<String, String> requestParameterMap = context.getExternalContext()
+ .getRequestParameterMap();
+ if (requestParameterMap.get(this.getClientId(context)) != null) {
+ String startDateParam = requestParameterMap.get(START_DATE);
+ String endDateParam = requestParameterMap.get(END_DATE);
+
+ try {
+ Date startDate = new Date(Long.parseLong(startDateParam));
+ Date endDate = new Date(Long.parseLong(endDateParam));
+
+ new FullCalendarAjaxEvent(this, startDate, endDate).queue();
+ } catch (NumberFormatException e) {
+ // TODO: handle exception
+ }
+ }
+ }
+
+ @Override
+ public void broadcast(FacesEvent event) throws AbortProcessingException {
+ super.broadcast(event);
+
+ if (event instanceof FullCalendarAjaxEvent) {
+ FullCalendarAjaxEvent calendarAjaxEvent = (FullCalendarAjaxEvent) event;
+
+ FacesContext facesContext = getFacesContext();
+ AjaxContext ajaxContext = AjaxContext
+ .getCurrentInstance(facesContext);
+
+ ajaxContext.setResponseData(getCalendarData(calendarAjaxEvent
+ .getStartDate(), calendarAjaxEvent.getEndDate()));
+ }
+ }
+
+ private Object getCalendarData(Date startDate, Date endDate) {
+
+// $year = date('Y');
+// $month = date('m');
+//
+// echo json_encode(array(
+//
+// array(
+// 'id' => 111,
+// 'title' => "Event1",
+// 'start' => "$year-$month-10",
+// 'url' => "http://yahoo.com/"
+// ),
+//
+// array(
+// 'id' => 222,
+// 'title' => "Event2",
+// 'start' => "$year-$month-20",
+// 'end' => "$year-$month-22",
+// 'url' => "http://yahoo.com/"
+// )
+//
+// ));
+
+ DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
+ format.setLenient(false);
+
+ List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
+
+ Map<String, Object> firstDataElement = new HashMap<String, Object>();
+
+ firstDataElement.put("id", 111);
+ firstDataElement.put("title", "Event 1");
+ Calendar calendar = Calendar.getInstance();
+
+ calendar.set(Calendar.DATE, 10);
+
+ firstDataElement.put("start", format.format(calendar.getTimeInMillis()));
+ firstDataElement.put("url", "http://www.yahoo.com");
+
+ data.add(firstDataElement);
+
+ Map<String, Object> secondDataElement = new HashMap<String, Object>();
+
+ secondDataElement.put("id", 222);
+ secondDataElement.put("title", "Event 2");
+ calendar.set(Calendar.DATE, 20);
+ secondDataElement.put("start", format.format(calendar.getTimeInMillis()));
+ calendar.set(Calendar.DATE, 22);
+ secondDataElement.put("end", format.format(calendar.getTimeInMillis()));
+ secondDataElement.put("url", "http://www.yahoo.com");
+
+ data.add(secondDataElement);
+
+ return data;
+ }
+
+ @Override
+ public void encodeEnd(FacesContext context) throws IOException {
+ ResponseWriter writer = context.getResponseWriter();
+ String clientId = this.getClientId(context);
+
+ writer.startElement(HTML.DIV_ELEM, this);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, clientId, HTML.id_ATTRIBUTE);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "rich-fullc",
+ HTML.class_ATTRIBUTE);
+
+ UIComponent loadingFacet = getFacet("loading");
+ if (loadingFacet != null && loadingFacet.isRendered()) {
+ writer.startElement(HTML.DIV_ELEM, this);
+ writer.writeAttribute(HTML.id_ATTRIBUTE, clientId + ":loading",
+ null);
+ writer.writeAttribute(HTML.class_ATTRIBUTE, "rich-fullc-loading",
+ null);
+
+ loadingFacet.encodeAll(context);
+
+ writer.endElement(HTML.DIV_ELEM);
+ }
+
+ writer.startElement(HTML.SCRIPT_ELEM, this);
+ writer
+ .writeAttribute(HTML.TYPE_ATTR, "text/javascript",
+ HTML.TYPE_ATTR);
+ writer.writeText(new JSObject("RichFaces.FullCalendar", clientId,
+ createAjaxFunction(context)).toScript(), null);
+ writer.endElement(HTML.SCRIPT_ELEM);
+
+ writer.endElement(HTML.DIV_ELEM);
+ }
+
+}
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/faces-config.xml
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/faces-config.xml (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/faces-config.xml 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+
+ <managed-bean>
+ <managed-bean-name>componentBean</managed-bean-name>
+ <managed-bean-class>demo.beans.ComponentBean</managed-bean-class>
+ <managed-bean-scope>request</managed-bean-scope>
+ </managed-bean>
+
+ <application>
+ <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
+ </application>
+
+</faces-config>
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/web.xml
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/web.xml (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/WEB-INF/web.xml 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee"
+ xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <display-name>Archetype Created Web Application</display-name>
+ <context-param>
+ <param-name>org.richfaces.SKIN</param-name>
+ <param-value>blueSky</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+ <param-value>server</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.LoadStyleStrategy</param-name>
+ <param-value>ALL</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.CONTROL_SKINNING_CLASSES</param-name>
+ <param-value>disable</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.LoadScriptStrategy</param-name>
+ <param-value>DEFAULT</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.ajax4jsf.COMPRESS_SCRIPT</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.ajax4jsf.COMPRESS_STYLE</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.DEVELOPMENT</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.SKIP_COMMENTS</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>facelets.VIEW_MAPPINGS</param-name>
+ <param-value>*.xhtml</param-value>
+ </context-param>
+ <session-config>
+ <session-timeout>1000</session-timeout>
+ </session-config>
+ <filter>
+ <filter-name>richfaces</filter-name>
+ <filter-class>org.ajax4jsf.Filter</filter-class>
+ </filter>
+ <filter-mapping>
+ <filter-name>richfaces</filter-name>
+ <servlet-name>Faces Servlet</servlet-name>
+ <dispatcher>REQUEST</dispatcher>
+ <dispatcher>FORWARD</dispatcher>
+ <dispatcher>ERROR</dispatcher>
+ </filter-mapping>
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>/faces/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/fullcalendar.js
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/fullcalendar.js (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/fullcalendar.js 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,3418 @@
+/*!
+ * FullCalendar v1.4.5
+ * http://arshaw.com/fullcalendar/
+ *
+ * Use fullcalendar.css for basic styling.
+ * For event drag & drop, required jQuery UI draggable.
+ * For event resizing, requires jQuery UI resizable.
+ *
+ * Copyright (c) 2009 Adam Shaw
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Date: Sun Feb 21 20:30:11 2010 -0800
+ *
+ */
+
+(function($) {
+
+
+var fc = $.fullCalendar = {};
+var views = fc.views = {};
+
+
+/* Defaults
+-----------------------------------------------------------------------------*/
+
+var defaults = {
+
+ // display
+ defaultView: 'month',
+ aspectRatio: 1.35,
+ header: {
+ left: 'title',
+ center: '',
+ right: 'today prev,next'
+ },
+ weekends: true,
+
+ // editing
+ //editable: false,
+ //disableDragging: false,
+ //disableResizing: false,
+
+ allDayDefault: true,
+
+ // event ajax
+ lazyFetching: true,
+ startParam: 'start',
+ endParam: 'end',
+
+ // time formats
+ titleFormat: {
+ month: 'MMMM yyyy',
+ week: "MMM d[ yyyy]{ '—'[ MMM] d yyyy}",
+ day: 'dddd, MMM d, yyyy'
+ },
+ columnFormat: {
+ month: 'ddd',
+ week: 'ddd M/d',
+ day: 'dddd M/d'
+ },
+ timeFormat: { // for event elements
+ '': 'h(:mm)t' // default
+ },
+
+ // locale
+ isRTL: false,
+ firstDay: 0,
+ monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'],
+ monthNamesShort: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
+ dayNames: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
+ dayNamesShort: ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
+ buttonText: {
+ prev: ' ◄ ',
+ next: ' ► ',
+ prevYear: ' << ',
+ nextYear: ' >> ',
+ today: 'today',
+ month: 'month',
+ week: 'week',
+ day: 'day'
+ },
+
+ // jquery-ui theming
+ theme: false,
+ buttonIcons: {
+ prev: 'circle-triangle-w',
+ next: 'circle-triangle-e'
+ }
+
+};
+
+// right-to-left defaults
+var rtlDefaults = {
+ header: {
+ left: 'next,prev today',
+ center: '',
+ right: 'title'
+ },
+ buttonText: {
+ prev: ' ► ',
+ next: ' ◄ ',
+ prevYear: ' >> ',
+ nextYear: ' << '
+ },
+ buttonIcons: {
+ prev: 'circle-triangle-e',
+ next: 'circle-triangle-w'
+ }
+};
+
+// function for adding/overriding defaults
+var setDefaults = fc.setDefaults = function(d) {
+ $.extend(true, defaults, d);
+}
+
+
+
+/* .fullCalendar jQuery function
+-----------------------------------------------------------------------------*/
+
+$.fn.fullCalendar = function(options) {
+
+ // method calling
+ if (typeof options == 'string') {
+ var args = Array.prototype.slice.call(arguments, 1),
+ res;
+ this.each(function() {
+ var data = $.data(this, 'fullCalendar');
+ if (data) {
+ var r = data[options].apply(this, args);
+ if (res == undefined) {
+ res = r;
+ }
+ }
+ });
+ if (res != undefined) {
+ return res;
+ }
+ return this;
+ }
+
+ // pluck the 'events' and 'eventSources' options
+ var eventSources = options.eventSources || [];
+ delete options.eventSources;
+ if (options.events) {
+ eventSources.push(options.events);
+ delete options.events;
+ }
+
+ // first event source reserved for 'sticky' events
+ eventSources.unshift([]);
+
+ // initialize options
+ options = $.extend(true, {},
+ defaults,
+ (options.isRTL || options.isRTL==undefined && defaults.isRTL) ? rtlDefaults : {},
+ options
+ );
+ var tm = options.theme ? 'ui' : 'fc'; // for making theme classes
+
+
+ this.each(function() {
+
+
+ /* Instance Initialization
+ -----------------------------------------------------------------------------*/
+
+ // element
+ var _element = this,
+ element = $(_element).addClass('fc'),
+ elementOuterWidth,
+ content = $("<div class='fc-content " + tm + "-widget-content' style='position:relative'/>").prependTo(_element),
+ suggestedViewHeight,
+ resizeUID = 0,
+ ignoreWindowResize = 0,
+ date = new Date(),
+ viewName, // the current view name (TODO: look into getting rid of)
+ view, // the current view
+ viewInstances = {},
+ absoluteViewElement;
+
+
+
+ if (options.isRTL) {
+ element.addClass('fc-rtl');
+ }
+ if (options.theme) {
+ element.addClass('ui-widget');
+ }
+
+ if (options.year != undefined && options.year != date.getFullYear()) {
+ date.setDate(1);
+ date.setMonth(0);
+ date.setFullYear(options.year);
+ }
+ if (options.month != undefined && options.month != date.getMonth()) {
+ date.setDate(1);
+ date.setMonth(options.month);
+ }
+ if (options.date != undefined) {
+ date.setDate(options.date);
+ }
+
+
+
+ /* View Rendering
+ -----------------------------------------------------------------------------*/
+
+ function changeView(v) {
+ if (v != viewName) {
+ ignoreWindowResize++; // because setMinHeight might change the height before render (and subsequently setSize) is reached
+
+ var oldView = view,
+ newViewElement;
+
+ if (oldView) {
+ if (oldView.eventsChanged) {
+ eventsDirty();
+ oldView.eventDirty = oldView.eventsChanged = false;
+ }
+ if (oldView.beforeHide) {
+ oldView.beforeHide(); // called before changing min-height. if called after, scroll state is reset (in Opera)
+ }
+ setMinHeight(content, content.height());
+ oldView.element.hide();
+ }else{
+ setMinHeight(content, 1); // needs to be 1 (not 0) for IE7, or else view dimensions miscalculated
+ }
+ content.css('overflow', 'hidden');
+
+ if (viewInstances[v]) {
+ (view = viewInstances[v]).element.show();
+ }else{
+ view = viewInstances[v] = $.fullCalendar.views[v](
+ newViewElement = absoluteViewElement =
+ $("<div class='fc-view fc-view-" + v + "' style='position:absolute'/>")
+ .appendTo(content),
+ options
+ );
+ }
+
+ if (header) {
+ // update 'active' view button
+ header.find('div.fc-button-' + viewName).removeClass(tm + '-state-active');
+ header.find('div.fc-button-' + v).addClass(tm + '-state-active');
+ }
+
+ view.name = viewName = v;
+ render(); // after height has been set, will make absoluteViewElement's position=relative, then set to null
+ content.css('overflow', '');
+ if (oldView) {
+ setMinHeight(content, 1);
+ }
+ if (!newViewElement && view.afterShow) {
+ view.afterShow(); // called after setting min-height/overflow, so in final scroll state (for Opera)
+ }
+
+ ignoreWindowResize--;
+ }
+ }
+
+
+ function render(inc) {
+ if (elementVisible()) {
+ ignoreWindowResize++; // because view.renderEvents might temporarily change the height before setSize is reached
+
+ if (suggestedViewHeight == undefined) {
+ calcSize();
+ }
+
+ if (!view.start || inc || date < view.start || date >= view.end) {
+ view.render(date, inc || 0); // responsible for clearing events
+ setSize(true);
+ if (!eventStart || !options.lazyFetching || view.visStart < eventStart || view.visEnd > eventEnd) {
+ fetchAndRenderEvents();
+ }else{
+ view.renderEvents(events); // don't refetch
+ }
+ }
+ else if (view.sizeDirty || view.eventsDirty || !options.lazyFetching) {
+ view.clearEvents();
+ if (view.sizeDirty) {
+ setSize();
+ }
+ if (options.lazyFetching) {
+ view.renderEvents(events); // don't refetch
+ }else{
+ fetchAndRenderEvents();
+ }
+ }
+ elementOuterWidth = element.outerWidth();
+ view.sizeDirty = false;
+ view.eventsDirty = false;
+
+ if (header) {
+ // update title text
+ header.find('h2.fc-header-title').html(view.title);
+ // enable/disable 'today' button
+ var today = new Date();
+ if (today >= view.start && today < view.end) {
+ header.find('div.fc-button-today').addClass(tm + '-state-disabled');
+ }else{
+ header.find('div.fc-button-today').removeClass(tm + '-state-disabled');
+ }
+ }
+
+ ignoreWindowResize--;
+ view.trigger('viewDisplay', _element);
+ }
+ }
+
+
+ function elementVisible() {
+ return _element.offsetWidth !== 0;
+ }
+
+ function bodyVisible() {
+ return $('body')[0].offsetWidth !== 0;
+ }
+
+
+ // called when any event objects have been added/removed/changed, rerenders
+ function eventsChanged() {
+ eventsDirty();
+ if (elementVisible()) {
+ view.clearEvents();
+ view.renderEvents(events);
+ view.eventsDirty = false;
+ }
+ }
+
+ // marks other views' events as dirty
+ function eventsDirty() {
+ $.each(viewInstances, function() {
+ this.eventsDirty = true;
+ });
+ }
+
+ // called when we know the element size has changed
+ function sizeChanged() {
+ sizesDirty();
+ if (elementVisible()) {
+ calcSize();
+ setSize();
+ view.rerenderEvents();
+ view.sizeDirty = false;
+ }
+ }
+
+ // marks other views' sizes as dirty
+ function sizesDirty() {
+ $.each(viewInstances, function() {
+ this.sizeDirty = true;
+ });
+ }
+
+
+
+
+ /* Event Sources and Fetching
+ -----------------------------------------------------------------------------*/
+
+ var events = [],
+ eventStart, eventEnd;
+
+ // Fetch from ALL sources. Clear 'events' array and populate
+ function fetchEvents(callback) {
+ events = [];
+ eventStart = cloneDate(view.visStart);
+ eventEnd = cloneDate(view.visEnd);
+ var queued = eventSources.length,
+ sourceDone = function() {
+ if (--queued == 0) {
+ if (callback) {
+ callback(events);
+ }
+ }
+ }, i=0;
+ for (; i<eventSources.length; i++) {
+ fetchEventSource(eventSources[i], sourceDone);
+ }
+ }
+
+ // Fetch from a particular source. Append to the 'events' array
+ function fetchEventSource(src, callback) {
+ var prevViewName = view.name,
+ prevDate = cloneDate(date),
+ reportEvents = function(a) {
+ if (prevViewName == view.name && +prevDate == +date && // protects from fast switching
+ $.inArray(src, eventSources) != -1) { // makes sure source hasn't been removed
+ for (var i=0; i<a.length; i++) {
+ normalizeEvent(a[i], options);
+ a[i].source = src;
+ }
+ events = events.concat(a);
+ if (callback) {
+ callback(a);
+ }
+ }
+ },
+ reportEventsAndPop = function(a) {
+ reportEvents(a);
+ popLoading();
+ };
+ if (typeof src == 'string') {
+ var params = {};
+ params[options.startParam] = Math.round(eventStart.getTime() / 1000);
+ params[options.endParam] = Math.round(eventEnd.getTime() / 1000);
+ if (options.cacheParam) {
+ params[options.cacheParam] = (new Date()).getTime(); // TODO: deprecate cacheParam
+ }
+ pushLoading();
+ $.ajax({
+ url: src,
+ dataType: 'json',
+ data: params,
+ cache: options.cacheParam || false, // don't let jquery prevent caching if cacheParam is being used
+ success: reportEventsAndPop
+ });
+ }
+ else if ($.isFunction(src)) {
+ pushLoading();
+ src(cloneDate(eventStart), cloneDate(eventEnd), reportEventsAndPop);
+ }
+ else {
+ reportEvents(src); // src is an array
+ }
+ }
+
+
+ // for convenience
+ function fetchAndRenderEvents() {
+ fetchEvents(function(events) {
+ view.renderEvents(events); // maintain `this` in view
+ });
+ }
+
+
+
+ /* Loading State
+ -----------------------------------------------------------------------------*/
+
+ var loadingLevel = 0;
+
+ function pushLoading() {
+ if (!loadingLevel++) {
+ view.trigger('loading', _element, true);
+ }
+ }
+
+ function popLoading() {
+ if (!--loadingLevel) {
+ view.trigger('loading', _element, false);
+ }
+ }
+
+
+
+ /* Public Methods
+ -----------------------------------------------------------------------------*/
+
+ var publicMethods = {
+
+ render: function() {
+ calcSize();
+ sizesDirty();
+ eventsDirty();
+ render();
+ },
+
+ changeView: changeView,
+
+ getView: function() {
+ return view;
+ },
+
+ getDate: function() {
+ return date;
+ },
+
+ option: function(name, value) {
+ if (value == undefined) {
+ return options[name];
+ }
+ if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {
+ options[name] = value;
+ sizeChanged();
+ }
+ },
+
+ destroy: function() {
+ $(window).unbind('resize', windowResize);
+ if (header) {
+ header.remove();
+ }
+ content.remove();
+ $.removeData(_element, 'fullCalendar');
+ },
+
+ //
+ // Navigation
+ //
+
+ prev: function() {
+ render(-1);
+ },
+
+ next: function() {
+ render(1);
+ },
+
+ prevYear: function() {
+ addYears(date, -1);
+ render();
+ },
+
+ nextYear: function() {
+ addYears(date, 1);
+ render();
+ },
+
+ today: function() {
+ date = new Date();
+ render();
+ },
+
+ gotoDate: function(year, month, dateNum) {
+ if (typeof year == 'object') {
+ date = cloneDate(year); // provided 1 argument, a Date
+ }else{
+ if (year != undefined) {
+ date.setFullYear(year);
+ }
+ if (month != undefined) {
+ date.setMonth(month);
+ }
+ if (dateNum != undefined) {
+ date.setDate(dateNum);
+ }
+ }
+ render();
+ },
+
+ incrementDate: function(years, months, days) {
+ if (years != undefined) {
+ addYears(date, years);
+ }
+ if (months != undefined) {
+ addMonths(date, months);
+ }
+ if (days != undefined) {
+ addDays(date, days);
+ }
+ render();
+ },
+
+ //
+ // Event Manipulation
+ //
+
+ updateEvent: function(event) { // update an existing event
+ var i, len = events.length, e,
+ startDelta = event.start - event._start,
+ endDelta = event.end ?
+ (event.end - (event._end || view.defaultEventEnd(event))) // event._end would be null if event.end
+ : 0; // was null and event was just resized
+ for (i=0; i<len; i++) {
+ e = events[i];
+ if (e._id == event._id && e != event) {
+ e.start = new Date(+e.start + startDelta);
+ if (event.end) {
+ if (e.end) {
+ e.end = new Date(+e.end + endDelta);
+ }else{
+ e.end = new Date(+view.defaultEventEnd(e) + endDelta);
+ }
+ }else{
+ e.end = null;
+ }
+ e.title = event.title;
+ e.url = event.url;
+ e.allDay = event.allDay;
+ e.className = event.className;
+ e.editable = event.editable;
+ normalizeEvent(e, options);
+ }
+ }
+ normalizeEvent(event, options);
+ eventsChanged();
+ },
+
+ renderEvent: function(event, stick) { // render a new event
+ normalizeEvent(event, options);
+ if (!event.source) {
+ if (stick) {
+ (event.source = eventSources[0]).push(event);
+ }
+ events.push(event);
+ }
+ eventsChanged();
+ },
+
+ removeEvents: function(filter) {
+ if (!filter) { // remove all
+ events = [];
+ // clear all array sources
+ for (var i=0; i<eventSources.length; i++) {
+ if (typeof eventSources[i] == 'object') {
+ eventSources[i] = [];
+ }
+ }
+ }else{
+ if (!$.isFunction(filter)) { // an event ID
+ var id = filter + '';
+ filter = function(e) {
+ return e._id == id;
+ };
+ }
+ events = $.grep(events, filter, true);
+ // remove events from array sources
+ for (var i=0; i<eventSources.length; i++) {
+ if (typeof eventSources[i] == 'object') {
+ eventSources[i] = $.grep(eventSources[i], filter, true);
+ }
+ }
+ }
+ eventsChanged();
+ },
+
+ clientEvents: function(filter) {
+ if ($.isFunction(filter)) {
+ return $.grep(events, filter);
+ }
+ else if (filter) { // an event ID
+ filter += '';
+ return $.grep(events, function(e) {
+ return e._id == filter;
+ });
+ }
+ return events; // else, return all
+ },
+
+ rerenderEvents: eventsChanged, // TODO: think of renaming eventsChanged
+
+ //
+ // Event Source
+ //
+
+ addEventSource: function(source) {
+ eventSources.push(source);
+ fetchEventSource(source, eventsChanged);
+ },
+
+ removeEventSource: function(source) {
+ eventSources = $.grep(eventSources, function(src) {
+ return src != source;
+ });
+ // remove all client events from that source
+ events = $.grep(events, function(e) {
+ return e.source != source;
+ });
+ eventsChanged();
+ },
+
+ refetchEvents: function() {
+ fetchEvents(eventsChanged);
+ }
+
+ };
+
+ $.data(this, 'fullCalendar', publicMethods);
+
+
+
+ /* Header
+ -----------------------------------------------------------------------------*/
+
+ var header,
+ sections = options.header;
+ if (sections) {
+ header = $("<table class='fc-header'/>")
+ .append($("<tr/>")
+ .append($("<td class='fc-header-left'/>").append(buildSection(sections.left)))
+ .append($("<td class='fc-header-center'/>").append(buildSection(sections.center)))
+ .append($("<td class='fc-header-right'/>").append(buildSection(sections.right))))
+ .prependTo(element);
+ }
+ function buildSection(buttonStr) {
+ if (buttonStr) {
+ var tr = $("<tr/>");
+ $.each(buttonStr.split(' '), function(i) {
+ if (i > 0) {
+ tr.append("<td><span class='fc-header-space'/></td>");
+ }
+ var prevButton;
+ $.each(this.split(','), function(j, buttonName) {
+ if (buttonName == 'title') {
+ tr.append("<td><h2 class='fc-header-title'> </h2></td>");
+ if (prevButton) {
+ prevButton.addClass(tm + '-corner-right');
+ }
+ prevButton = null;
+ }else{
+ var buttonClick;
+ if (publicMethods[buttonName]) {
+ buttonClick = publicMethods[buttonName];
+ }
+ else if (views[buttonName]) {
+ buttonClick = function() {
+ button.removeClass(tm + '-state-hover');
+ changeView(buttonName)
+ };
+ }
+ if (buttonClick) {
+ if (prevButton) {
+ prevButton.addClass(tm + '-no-right');
+ }
+ var button,
+ icon = options.theme ? smartProperty(options.buttonIcons, buttonName) : null,
+ text = smartProperty(options.buttonText, buttonName);
+ if (icon) {
+ button = $("<div class='fc-button-" + buttonName + " ui-state-default'>" +
+ "<a><span class='ui-icon ui-icon-" + icon + "'/></a></div>");
+ }
+ else if (text) {
+ button = $("<div class='fc-button-" + buttonName + " " + tm + "-state-default'>" +
+ "<a><span>" + text + "</span></a></div>");
+ }
+ if (button) {
+ button
+ .click(function() {
+ if (!button.hasClass(tm + '-state-disabled')) {
+ buttonClick();
+ }
+ })
+ .mousedown(function() {
+ button
+ .not('.' + tm + '-state-active')
+ .not('.' + tm + '-state-disabled')
+ .addClass(tm + '-state-down');
+ })
+ .mouseup(function() {
+ button.removeClass(tm + '-state-down');
+ })
+ .hover(
+ function() {
+ button
+ .not('.' + tm + '-state-active')
+ .not('.' + tm + '-state-disabled')
+ .addClass(tm + '-state-hover');
+ },
+ function() {
+ button
+ .removeClass(tm + '-state-hover')
+ .removeClass(tm + '-state-down');
+ }
+ )
+ .appendTo($("<td/>").appendTo(tr));
+ if (prevButton) {
+ prevButton.addClass(tm + '-no-right');
+ }else{
+ button.addClass(tm + '-corner-left');
+ }
+ prevButton = button;
+ }
+ }
+ }
+ });
+ if (prevButton) {
+ prevButton.addClass(tm + '-corner-right');
+ }
+ });
+ return $("<table/>").append(tr);
+ }
+ }
+
+
+
+ /* Resizing
+ -----------------------------------------------------------------------------*/
+
+
+ function calcSize() {
+ if (options.contentHeight) {
+ suggestedViewHeight = options.contentHeight;
+ }
+ else if (options.height) {
+ suggestedViewHeight = options.height - (header ? header.height() : 0) - vsides(content[0]);
+ }
+ else {
+ suggestedViewHeight = Math.round(content.width() / Math.max(options.aspectRatio, .5));
+ }
+ }
+
+
+ function setSize(dateChanged) {
+ ignoreWindowResize++;
+ view.setHeight(suggestedViewHeight, dateChanged);
+ if (absoluteViewElement) {
+ absoluteViewElement.css('position', 'relative');
+ absoluteViewElement = null;
+ }
+ view.setWidth(content.width(), dateChanged);
+ ignoreWindowResize--;
+ }
+
+
+ function windowResize() {
+ if (!ignoreWindowResize) {
+ if (view.start) { // view has already been rendered
+ var uid = ++resizeUID;
+ setTimeout(function() { // add a delay
+ if (uid == resizeUID && !ignoreWindowResize && elementVisible()) {
+ if (elementOuterWidth != (elementOuterWidth = element.outerWidth())) {
+ ignoreWindowResize++; // in case the windowResize callback changes the height
+ sizeChanged();
+ view.trigger('windowResize', _element);
+ ignoreWindowResize--;
+ }
+ }
+ }, 200);
+ }else{
+ // calendar must have been initialized in a 0x0 iframe that has just been resized
+ lateRender();
+ }
+ }
+ };
+ $(window).resize(windowResize);
+
+
+ // let's begin...
+ changeView(options.defaultView);
+
+
+ // needed for IE in a 0x0 iframe, b/c when it is resized, never triggers a windowResize
+ if (!bodyVisible()) {
+ lateRender();
+ }
+
+
+ // called when we know the calendar couldn't be rendered when it was initialized,
+ // but we think it's ready now
+ function lateRender() {
+ setTimeout(function() { // IE7 needs this so dimensions are calculated correctly
+ if (!view.start && bodyVisible()) { // !view.start makes sure this never happens more than once
+ render();
+ }
+ },0);
+ }
+
+
+ });
+
+ return this;
+
+};
+
+
+
+/* Important Event Utilities
+-----------------------------------------------------------------------------*/
+
+var fakeID = 0;
+
+function normalizeEvent(event, options) {
+ event._id = event._id || (event.id == undefined ? '_fc' + fakeID++ : event.id + '');
+ if (event.date) {
+ if (!event.start) {
+ event.start = event.date;
+ }
+ delete event.date;
+ }
+ event._start = cloneDate(event.start = parseDate(event.start));
+ event.end = parseDate(event.end);
+ if (event.end && event.end <= event.start) {
+ event.end = null;
+ }
+ event._end = event.end ? cloneDate(event.end) : null;
+ if (event.allDay == undefined) {
+ event.allDay = options.allDayDefault;
+ }
+ if (event.className) {
+ if (typeof event.className == 'string') {
+ event.className = event.className.split(/\s+/);
+ }
+ }else{
+ event.className = [];
+ }
+}
+// TODO: if there is no title or start date, return false to indicate an invalid event
+
+
+/* Grid-based Views: month, basicWeek, basicDay
+-----------------------------------------------------------------------------*/
+
+setDefaults({
+ weekMode: 'fixed'
+});
+
+views.month = function(element, options) {
+ return new Grid(element, options, {
+ render: function(date, delta) {
+ if (delta) {
+ addMonths(date, delta);
+ date.setDate(1);
+ }
+ // start/end
+ var start = this.start = cloneDate(date, true);
+ start.setDate(1);
+ this.end = addMonths(cloneDate(start), 1);
+ // visStart/visEnd
+ var visStart = this.visStart = cloneDate(start),
+ visEnd = this.visEnd = cloneDate(this.end),
+ nwe = options.weekends ? 0 : 1;
+ if (nwe) {
+ skipWeekend(visStart);
+ skipWeekend(visEnd, -1, true);
+ }
+ addDays(visStart, -((visStart.getDay() - Math.max(options.firstDay, nwe) + 7) % 7));
+ addDays(visEnd, (7 - visEnd.getDay() + Math.max(options.firstDay, nwe)) % 7);
+ // row count
+ var rowCnt = Math.round((visEnd - visStart) / (DAY_MS * 7));
+ if (options.weekMode == 'fixed') {
+ addDays(visEnd, (6 - rowCnt) * 7);
+ rowCnt = 6;
+ }
+ // title
+ this.title = formatDate(
+ start,
+ this.option('titleFormat'),
+ options
+ );
+ // render
+ this.renderGrid(
+ rowCnt, options.weekends ? 7 : 5,
+ this.option('columnFormat'),
+ true
+ );
+ }
+ });
+}
+
+views.basicWeek = function(element, options) {
+ return new Grid(element, options, {
+ render: function(date, delta) {
+ if (delta) {
+ addDays(date, delta * 7);
+ }
+ var visStart = this.visStart = cloneDate(
+ this.start = addDays(cloneDate(date), -((date.getDay() - options.firstDay + 7) % 7))
+ ),
+ visEnd = this.visEnd = cloneDate(
+ this.end = addDays(cloneDate(visStart), 7)
+ );
+ if (!options.weekends) {
+ skipWeekend(visStart);
+ skipWeekend(visEnd, -1, true);
+ }
+ this.title = formatDates(
+ visStart,
+ addDays(cloneDate(visEnd), -1),
+ this.option('titleFormat'),
+ options
+ );
+ this.renderGrid(
+ 1, options.weekends ? 7 : 5,
+ this.option('columnFormat'),
+ false
+ );
+ }
+ });
+};
+
+views.basicDay = function(element, options) {
+ return new Grid(element, options, {
+ render: function(date, delta) {
+ if (delta) {
+ addDays(date, delta);
+ if (!options.weekends) {
+ skipWeekend(date, delta < 0 ? -1 : 1);
+ }
+ }
+ this.title = formatDate(date, this.option('titleFormat'), options);
+ this.start = this.visStart = cloneDate(date, true);
+ this.end = this.visEnd = addDays(cloneDate(this.start), 1);
+ this.renderGrid(
+ 1, 1,
+ this.option('columnFormat'),
+ false
+ );
+ }
+ });
+}
+
+
+// rendering bugs
+
+var tdHeightBug;
+
+
+function Grid(element, options, methods) {
+
+ var tm, firstDay,
+ nwe, // no weekends (int)
+ rtl, dis, dit, // day index sign / translate
+ viewWidth, viewHeight,
+ rowCnt, colCnt,
+ colWidth,
+ thead, tbody,
+ cachedEvents=[],
+ segmentContainer,
+ dayContentPositions = new HorizontalPositionCache(function(dayOfWeek) {
+ return tbody.find('td:eq(' + ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt) + ') div div')
+ }),
+ // ...
+
+ // initialize superclass
+ view = $.extend(this, viewMethods, methods, {
+ renderGrid: renderGrid,
+ renderEvents: renderEvents,
+ rerenderEvents: rerenderEvents,
+ clearEvents: clearEvents,
+ setHeight: setHeight,
+ setWidth: setWidth,
+ defaultEventEnd: function(event) { // calculates an end if event doesnt have one, mostly for resizing
+ return cloneDate(event.start);
+ }
+ });
+ view.init(element, options);
+
+
+
+ /* Grid Rendering
+ -----------------------------------------------------------------------------*/
+
+
+ element.addClass('fc-grid');
+ if (element.disableSelection) {
+ element.disableSelection();
+ }
+
+ function renderGrid(r, c, colFormat, showNumbers) {
+ rowCnt = r;
+ colCnt = c;
+
+ // update option-derived variables
+ tm = options.theme ? 'ui' : 'fc';
+ nwe = options.weekends ? 0 : 1;
+ firstDay = options.firstDay;
+ if (rtl = options.isRTL) {
+ dis = -1;
+ dit = colCnt - 1;
+ }else{
+ dis = 1;
+ dit = 0;
+ }
+
+ var month = view.start.getMonth(),
+ today = clearTime(new Date()),
+ s, i, j, d = cloneDate(view.visStart);
+
+ if (!tbody) { // first time, build all cells from scratch
+
+ var table = $("<table/>").appendTo(element);
+
+ s = "<thead><tr>";
+ for (i=0; i<colCnt; i++) {
+ s += "<th class='fc-" +
+ dayIDs[d.getDay()] + ' ' + // needs to be first
+ tm + '-state-default' +
+ (i==dit ? ' fc-leftmost' : '') +
+ "'>" + formatDate(d, colFormat, options) + "</th>";
+ addDays(d, 1);
+ if (nwe) {
+ skipWeekend(d);
+ }
+ }
+ thead = $(s + "</tr></thead>").appendTo(table);
+
+ s = "<tbody>";
+ d = cloneDate(view.visStart);
+ for (i=0; i<rowCnt; i++) {
+ s += "<tr class='fc-week" + i + "'>";
+ for (j=0; j<colCnt; j++) {
+ s += "<td class='fc-" +
+ dayIDs[d.getDay()] + ' ' + // needs to be first
+ tm + '-state-default fc-day' + (i*colCnt+j) +
+ (j==dit ? ' fc-leftmost' : '') +
+ (rowCnt>1 && d.getMonth() != month ? ' fc-other-month' : '') +
+ (+d == +today ?
+ ' fc-today '+tm+'-state-highlight' :
+ ' fc-not-today') + "'>" +
+ (showNumbers ? "<div class='fc-day-number'>" + d.getDate() + "</div>" : '') +
+ "<div class='fc-day-content'><div style='position:relative'> </div></div></td>";
+ addDays(d, 1);
+ if (nwe) {
+ skipWeekend(d);
+ }
+ }
+ s += "</tr>";
+ }
+ tbody = $(s + "</tbody>").appendTo(table);
+ tbody.find('td').click(dayClick);
+
+ segmentContainer = $("<div style='position:absolute;z-index:8;top:0;left:0'/>").appendTo(element);
+
+ }else{ // NOT first time, reuse as many cells as possible
+
+ clearEvents();
+
+ var prevRowCnt = tbody.find('tr').length;
+ if (rowCnt < prevRowCnt) {
+ tbody.find('tr:gt(' + (rowCnt-1) + ')').remove(); // remove extra rows
+ }
+ else if (rowCnt > prevRowCnt) { // needs to create new rows...
+ s = '';
+ for (i=prevRowCnt; i<rowCnt; i++) {
+ s += "<tr class='fc-week" + i + "'>";
+ for (j=0; j<colCnt; j++) {
+ s += "<td class='fc-" +
+ dayIDs[d.getDay()] + ' ' + // needs to be first
+ tm + '-state-default fc-new fc-day' + (i*colCnt+j) +
+ (j==dit ? ' fc-leftmost' : '') + "'>" +
+ (showNumbers ? "<div class='fc-day-number'></div>" : '') +
+ "<div class='fc-day-content'><div style='position:relative'> </div></div>" +
+ "</td>";
+ addDays(d, 1);
+ if (nwe) {
+ skipWeekend(d);
+ }
+ }
+ s += "</tr>";
+ }
+ tbody.append(s);
+ }
+ tbody.find('td.fc-new').removeClass('fc-new').click(dayClick);
+
+ // re-label and re-class existing cells
+ d = cloneDate(view.visStart);
+ tbody.find('td').each(function() {
+ var td = $(this);
+ if (rowCnt > 1) {
+ if (d.getMonth() == month) {
+ td.removeClass('fc-other-month');
+ }else{
+ td.addClass('fc-other-month');
+ }
+ }
+ if (+d == +today) {
+ td.removeClass('fc-not-today')
+ .addClass('fc-today')
+ .addClass(tm + '-state-highlight');
+ }else{
+ td.addClass('fc-not-today')
+ .removeClass('fc-today')
+ .removeClass(tm + '-state-highlight');
+ }
+ td.find('div.fc-day-number').text(d.getDate());
+ addDays(d, 1);
+ if (nwe) {
+ skipWeekend(d);
+ }
+ });
+
+ if (rowCnt == 1) { // more changes likely (week or day view)
+
+ // redo column header text and class
+ d = cloneDate(view.visStart);
+ thead.find('th').each(function() {
+ $(this).text(formatDate(d, colFormat, options));
+ this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
+ addDays(d, 1);
+ if (nwe) {
+ skipWeekend(d);
+ }
+ });
+
+ // redo cell day-of-weeks
+ d = cloneDate(view.visStart);
+ tbody.find('td').each(function() {
+ this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
+ addDays(d, 1);
+ if (nwe) {
+ skipWeekend(d);
+ }
+ });
+
+ }
+
+ }
+
+ };
+
+
+ function dayClick(ev) {
+ var n = parseInt(this.className.match(/fc\-day(\d+)/)[1]),
+ date = addDays(
+ cloneDate(view.visStart),
+ Math.floor(n/colCnt) * 7 + n % colCnt
+ );
+ view.trigger('dayClick', this, date, true, ev);
+ }
+
+
+
+ function setHeight(height) {
+ viewHeight = height;
+ var leftTDs = tbody.find('tr td:first-child'),
+ tbodyHeight = viewHeight - thead.height(),
+ rowHeight1, rowHeight2;
+ if (options.weekMode == 'variable') {
+ rowHeight1 = rowHeight2 = Math.floor(tbodyHeight / (rowCnt==1 ? 2 : 6));
+ }else{
+ rowHeight1 = Math.floor(tbodyHeight / rowCnt);
+ rowHeight2 = tbodyHeight - rowHeight1*(rowCnt-1);
+ }
+ if (tdHeightBug == undefined) {
+ // bug in firefox where cell height includes padding
+ var tr = tbody.find('tr:first'),
+ td = tr.find('td:first');
+ td.height(rowHeight1);
+ tdHeightBug = rowHeight1 != td.height();
+ }
+ if (tdHeightBug) {
+ leftTDs.slice(0, -1).height(rowHeight1);
+ leftTDs.slice(-1).height(rowHeight2);
+ }else{
+ setOuterHeight(leftTDs.slice(0, -1), rowHeight1);
+ setOuterHeight(leftTDs.slice(-1), rowHeight2);
+ }
+ }
+
+
+ function setWidth(width) {
+ viewWidth = width;
+ dayContentPositions.clear();
+ setOuterWidth(
+ thead.find('th').slice(0, -1),
+ colWidth = Math.floor(viewWidth / colCnt)
+ );
+ }
+
+
+
+ /* Event Rendering
+ -----------------------------------------------------------------------------*/
+
+
+ function renderEvents(events) {
+ view.reportEvents(cachedEvents = events);
+ renderSegs(compileSegs(events));
+ }
+
+
+ function rerenderEvents(modifiedEventId) {
+ clearEvents();
+ renderSegs(compileSegs(cachedEvents), modifiedEventId);
+ }
+
+
+ function clearEvents() {
+ view._clearEvents(); // only clears the hashes
+ segmentContainer.empty();
+ }
+
+
+ function compileSegs(events) {
+ var d1 = cloneDate(view.visStart),
+ d2 = addDays(cloneDate(d1), colCnt),
+ visEventsEnds = $.map(events, visEventEnd),
+ i, row,
+ j, level,
+ k, seg,
+ segs=[];
+ for (i=0; i<rowCnt; i++) {
+ row = stackSegs(view.sliceSegs(events, visEventsEnds, d1, d2));
+ for (j=0; j<row.length; j++) {
+ level = row[j];
+ for (k=0; k<level.length; k++) {
+ seg = level[k];
+ seg.row = i;
+ seg.level = j;
+ segs.push(seg);
+ }
+ }
+ addDays(d1, 7);
+ addDays(d2, 7);
+ }
+ return segs;
+ }
+
+
+
+ function renderSegs(segs, modifiedEventId) {
+ _renderDaySegs(
+ segs,
+ rowCnt,
+ view,
+ 0,
+ viewWidth,
+ function(i) { return tbody.find('tr:eq('+i+')') },
+ dayContentPositions.left,
+ dayContentPositions.right,
+ segmentContainer,
+ bindSegHandlers,
+ modifiedEventId
+ );
+ }
+
+
+
+ function visEventEnd(event) { // returns exclusive 'visible' end, for rendering
+ if (event.end) {
+ var end = cloneDate(event.end);
+ return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
+ }else{
+ return addDays(cloneDate(event.start), 1);
+ }
+ }
+
+
+
+ function bindSegHandlers(event, eventElement, seg) {
+ view.eventElementHandlers(event, eventElement);
+ if (event.editable || event.editable == undefined && options.editable) {
+ draggableEvent(event, eventElement);
+ if (seg.isEnd) {
+ view.resizableDayEvent(event, eventElement, colWidth);
+ }
+ }
+ }
+
+
+
+ /* Event Dragging
+ -----------------------------------------------------------------------------*/
+
+
+ function draggableEvent(event, eventElement) {
+ if (!options.disableDragging && eventElement.draggable) {
+ var matrix;
+ eventElement.draggable({
+ zIndex: 9,
+ delay: 50,
+ opacity: view.option('dragOpacity'),
+ revertDuration: options.dragRevertDuration,
+ start: function(ev, ui) {
+ view.hideEvents(event, eventElement);
+ view.trigger('eventDragStart', eventElement, event, ev, ui);
+ matrix = new HoverMatrix(function(cell) {
+ eventElement.draggable('option', 'revert', !cell || !cell.rowDelta && !cell.colDelta);
+ if (cell) {
+ view.showOverlay(cell);
+ }else{
+ view.hideOverlay();
+ }
+ });
+ tbody.find('tr').each(function() {
+ matrix.row(this);
+ });
+ var tds = tbody.find('tr:first td');
+ if (rtl) {
+ tds = $(tds.get().reverse());
+ }
+ tds.each(function() {
+ matrix.col(this);
+ });
+ matrix.mouse(ev.pageX, ev.pageY);
+ },
+ drag: function(ev) {
+ matrix.mouse(ev.pageX, ev.pageY);
+ },
+ stop: function(ev, ui) {
+ view.hideOverlay();
+ view.trigger('eventDragStop', eventElement, event, ev, ui);
+ var cell = matrix.cell;
+ if (!cell || !cell.rowDelta && !cell.colDelta) {
+ if ($.browser.msie) {
+ eventElement.css('filter', ''); // clear IE opacity side-effects
+ }
+ view.showEvents(event, eventElement);
+ }else{
+ eventElement.find('a').removeAttr('href'); // prevents safari from visiting the link
+ view.eventDrop(this, event, cell.rowDelta*7+cell.colDelta*dis, 0, event.allDay, ev, ui);
+ }
+ }
+ });
+ }
+ }
+
+
+ // event resizing w/ 'view' methods...
+
+};
+
+
+function _renderDaySegs(segs, rowCnt, view, minLeft, maxLeft, getRow, dayContentLeft, dayContentRight, segmentContainer, bindSegHandlers, modifiedEventId) {
+
+ var options=view.options,
+ rtl=options.isRTL,
+ i, segCnt=segs.length, seg,
+ event,
+ className,
+ left, right,
+ html='',
+ eventElements,
+ eventElement,
+ triggerRes,
+ hsideCache={},
+ vmarginCache={},
+ key, val,
+ rowI, top, levelI, levelHeight,
+ rowDivs=[],
+ rowDivTops=[];
+
+ // calculate desired position/dimensions, create html
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ event = seg.event;
+ className = 'fc-event fc-event-hori ';
+ if (rtl) {
+ if (seg.isStart) {
+ className += 'fc-corner-right ';
+ }
+ if (seg.isEnd) {
+ className += 'fc-corner-left ';
+ }
+ left = seg.isEnd ? dayContentLeft(seg.end.getDay()-1) : minLeft;
+ right = seg.isStart ? dayContentRight(seg.start.getDay()) : maxLeft;
+ }else{
+ if (seg.isStart) {
+ className += 'fc-corner-left ';
+ }
+ if (seg.isEnd) {
+ className += 'fc-corner-right ';
+ }
+ left = seg.isStart ? dayContentLeft(seg.start.getDay()) : minLeft;
+ right = seg.isEnd ? dayContentRight(seg.end.getDay()-1) : maxLeft;
+ }
+ html +=
+ "<div class='" + className + event.className.join(' ') + "' style='position:absolute;z-index:8;left:"+left+"px'>" +
+ "<a" + (event.url ? " href='" + htmlEscape(event.url) + "'" : '') + ">" +
+ (!event.allDay && seg.isStart ?
+ "<span class='fc-event-time'>" +
+ htmlEscape(formatDates(event.start, event.end, view.option('timeFormat'), options)) +
+ "</span>"
+ :'') +
+ "<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
+ "</a>" +
+ ((event.editable || event.editable == undefined && options.editable) && !options.disableResizing && $.fn.resizable ?
+ "<div class='ui-resizable-handle ui-resizable-" + (rtl ? 'w' : 'e') + "'></div>"
+ : '') +
+ "</div>";
+ seg.left = left;
+ seg.outerWidth = right - left;
+ }
+ segmentContainer[0].innerHTML = html; // faster than html()
+ eventElements = segmentContainer.children();
+
+ // retrieve elements, run through eventRender callback, bind handlers
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ eventElement = $(eventElements[i]); // faster than eq()
+ event = seg.event;
+ triggerRes = view.trigger('eventRender', event, event, eventElement);
+ if (triggerRes === false) {
+ eventElement.remove();
+ }else{
+ if (triggerRes && triggerRes !== true) {
+ eventElement.remove();
+ eventElement = $(triggerRes)
+ .css({
+ position: 'absolute',
+ left: seg.left
+ })
+ .appendTo(segmentContainer);
+ }
+ seg.element = eventElement;
+ if (event._id === modifiedEventId) {
+ bindSegHandlers(event, eventElement, seg);
+ }else{
+ eventElement[0]._fci = i; // for lazySegBind
+ }
+ view.reportEventElement(event, eventElement);
+ }
+ }
+
+ lazySegBind(segmentContainer, segs, bindSegHandlers);
+
+ // record event horizontal sides
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ if (eventElement = seg.element) {
+ val = hsideCache[key = seg.key = cssKey(eventElement[0])];
+ seg.hsides = val == undefined ? (hsideCache[key] = hsides(eventElement[0], true)) : val;
+ }
+ }
+
+ // set event widths
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ if (eventElement = seg.element) {
+ eventElement[0].style.width = seg.outerWidth - seg.hsides + 'px';
+ }
+ }
+
+ // record event heights
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ if (eventElement = seg.element) {
+ val = vmarginCache[key = seg.key];
+ seg.outerHeight = eventElement[0].offsetHeight + (
+ val == undefined ? (vmarginCache[key] = vmargins(eventElement[0])) : val
+ );
+ }
+ }
+
+ // set row heights, calculate event tops (in relation to row top)
+ for (i=0, rowI=0; rowI<rowCnt; rowI++) {
+ top = levelI = levelHeight = 0;
+ while (i<segCnt && (seg = segs[i]).row == rowI) {
+ if (seg.level != levelI) {
+ top += levelHeight;
+ levelHeight = 0;
+ levelI++;
+ }
+ levelHeight = Math.max(levelHeight, seg.outerHeight||0);
+ seg.top = top;
+ i++;
+ }
+ rowDivs[rowI] = getRow(rowI).find('td:first div.fc-day-content > div') // optimal selector?
+ .height(top + levelHeight);
+ }
+
+ // calculate row tops
+ for (rowI=0; rowI<rowCnt; rowI++) {
+ rowDivTops[rowI] = rowDivs[rowI][0].offsetTop;
+ }
+
+ // set event tops
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ if (eventElement = seg.element) {
+ eventElement[0].style.top = rowDivTops[seg.row] + seg.top + 'px';
+ event = seg.event;
+ view.trigger('eventAfterRender', event, event, eventElement);
+ }
+ }
+
+}
+
+
+
+/* Agenda Views: agendaWeek/agendaDay
+-----------------------------------------------------------------------------*/
+
+setDefaults({
+ allDaySlot: true,
+ allDayText: 'all-day',
+ firstHour: 6,
+ slotMinutes: 30,
+ defaultEventMinutes: 120,
+ axisFormat: 'h(:mm)tt',
+ timeFormat: {
+ agenda: 'h:mm{ - h:mm}'
+ },
+ dragOpacity: {
+ agenda: .5
+ },
+ minTime: 0,
+ maxTime: 24
+});
+
+views.agendaWeek = function(element, options) {
+ return new Agenda(element, options, {
+ render: function(date, delta) {
+ if (delta) {
+ addDays(date, delta * 7);
+ }
+ var visStart = this.visStart = cloneDate(
+ this.start = addDays(cloneDate(date), -((date.getDay() - options.firstDay + 7) % 7))
+ ),
+ visEnd = this.visEnd = cloneDate(
+ this.end = addDays(cloneDate(visStart), 7)
+ );
+ if (!options.weekends) {
+ skipWeekend(visStart);
+ skipWeekend(visEnd, -1, true);
+ }
+ this.title = formatDates(
+ visStart,
+ addDays(cloneDate(visEnd), -1),
+ this.option('titleFormat'),
+ options
+ );
+ this.renderAgenda(
+ options.weekends ? 7 : 5,
+ this.option('columnFormat')
+ );
+ }
+ });
+};
+
+views.agendaDay = function(element, options) {
+ return new Agenda(element, options, {
+ render: function(date, delta) {
+ if (delta) {
+ addDays(date, delta);
+ if (!options.weekends) {
+ skipWeekend(date, delta < 0 ? -1 : 1);
+ }
+ }
+ this.title = formatDate(date, this.option('titleFormat'), options);
+ this.start = this.visStart = cloneDate(date, true);
+ this.end = this.visEnd = addDays(cloneDate(this.start), 1);
+ this.renderAgenda(
+ 1,
+ this.option('columnFormat')
+ );
+ }
+ });
+};
+
+function Agenda(element, options, methods) {
+
+ var head, body, bodyContent, bodyTable, bg,
+ colCnt,
+ axisWidth, colWidth, slotHeight,
+ viewWidth, viewHeight,
+ savedScrollTop,
+ cachedEvents=[],
+ daySegmentContainer,
+ slotSegmentContainer,
+ tm, firstDay,
+ nwe, // no weekends (int)
+ rtl, dis, dit, // day index sign / translate
+ minMinute, maxMinute,
+ colContentPositions = new HorizontalPositionCache(function(col) {
+ return bg.find('td:eq(' + col + ') div div');
+ }),
+ slotTopCache = {},
+ // ...
+
+ view = $.extend(this, viewMethods, methods, {
+ renderAgenda: renderAgenda,
+ renderEvents: renderEvents,
+ rerenderEvents: rerenderEvents,
+ clearEvents: clearEvents,
+ setHeight: setHeight,
+ setWidth: setWidth,
+ beforeHide: function() {
+ savedScrollTop = body.scrollTop();
+ },
+ afterShow: function() {
+ body.scrollTop(savedScrollTop);
+ },
+ defaultEventEnd: function(event) {
+ var start = cloneDate(event.start);
+ if (event.allDay) {
+ return start;
+ }
+ return addMinutes(start, options.defaultEventMinutes);
+ }
+ });
+ view.init(element, options);
+
+
+
+ /* Time-slot rendering
+ -----------------------------------------------------------------------------*/
+
+
+ element.addClass('fc-agenda');
+ if (element.disableSelection) {
+ element.disableSelection();
+ }
+
+ function renderAgenda(c, colFormat) {
+ colCnt = c;
+
+ // update option-derived variables
+ tm = options.theme ? 'ui' : 'fc';
+ nwe = options.weekends ? 0 : 1;
+ firstDay = options.firstDay;
+ if (rtl = options.isRTL) {
+ dis = -1;
+ dit = colCnt - 1;
+ }else{
+ dis = 1;
+ dit = 0;
+ }
+ minMinute = parseTime(options.minTime);
+ maxMinute = parseTime(options.maxTime);
+
+ var d0 = rtl ? addDays(cloneDate(view.visEnd), -1) : cloneDate(view.visStart),
+ d = cloneDate(d0),
+ today = clearTime(new Date());
+
+ if (!head) { // first time rendering, build from scratch
+
+ var i,
+ minutes,
+ slotNormal = options.slotMinutes % 15 == 0, //...
+
+ // head
+ s = "<div class='fc-agenda-head' style='position:relative;z-index:4'>" +
+ "<table style='width:100%'>" +
+ "<tr class='fc-first" + (options.allDaySlot ? '' : ' fc-last') + "'>" +
+ "<th class='fc-leftmost " +
+ tm + "-state-default'> </th>";
+ for (i=0; i<colCnt; i++) {
+ s += "<th class='fc-" +
+ dayIDs[d.getDay()] + ' ' + // needs to be first
+ tm + '-state-default' +
+ "'>" + formatDate(d, colFormat, options) + "</th>";
+ addDays(d, dis);
+ if (nwe) {
+ skipWeekend(d, dis);
+ }
+ }
+ s += "<th class='" + tm + "-state-default'> </th></tr>";
+ if (options.allDaySlot) {
+ s += "<tr class='fc-all-day'>" +
+ "<th class='fc-axis fc-leftmost " + tm + "-state-default'>" + options.allDayText + "</th>" +
+ "<td colspan='" + colCnt + "' class='" + tm + "-state-default'>" +
+ "<div class='fc-day-content'><div style='position:relative'> </div></div></td>" +
+ "<th class='" + tm + "-state-default'> </th>" +
+ "</tr><tr class='fc-divider fc-last'><th colspan='" + (colCnt+2) + "' class='" +
+ tm + "-state-default fc-leftmost'><div/></th></tr>";
+ }
+ s+= "</table></div>";
+ head = $(s).appendTo(element);
+ head.find('td').click(slotClick);
+
+ // all-day event container
+ daySegmentContainer = $("<div style='position:absolute;z-index:8;top:0;left:0'/>").appendTo(head);
+
+ // body
+ d = zeroDate();
+ var maxd = addMinutes(cloneDate(d), maxMinute);
+ addMinutes(d, minMinute);
+ s = "<table>";
+ for (i=0; d < maxd; i++) {
+ minutes = d.getMinutes();
+ s += "<tr class='" +
+ (i==0 ? 'fc-first' : (minutes==0 ? '' : 'fc-minor')) +
+ "'><th class='fc-axis fc-leftmost " + tm + "-state-default'>" +
+ ((!slotNormal || minutes==0) ? formatDate(d, options.axisFormat) : ' ') +
+ "</th><td class='fc-slot" + i + ' ' +
+ tm + "-state-default'><div style='position:relative'> </div></td></tr>";
+ addMinutes(d, options.slotMinutes);
+ }
+ s += "</table>";
+ body = $("<div class='fc-agenda-body' style='position:relative;z-index:2;overflow:auto'/>")
+ .append(bodyContent = $("<div style='position:relative;overflow:hidden'>")
+ .append(bodyTable = $(s)))
+ .appendTo(element);
+ body.find('td').click(slotClick);
+
+ // slot event container
+ slotSegmentContainer = $("<div style='position:absolute;z-index:8;top:0;left:0'/>").appendTo(bodyContent);
+
+ // background stripes
+ d = cloneDate(d0);
+ s = "<div class='fc-agenda-bg' style='position:absolute;z-index:1'>" +
+ "<table style='width:100%;height:100%'><tr class='fc-first'>";
+ for (i=0; i<colCnt; i++) {
+ s += "<td class='fc-" +
+ dayIDs[d.getDay()] + ' ' + // needs to be first
+ tm + '-state-default ' +
+ (i==0 ? 'fc-leftmost ' : '') +
+ (+d == +today ? tm + '-state-highlight fc-today' : 'fc-not-today') +
+ "'><div class='fc-day-content'><div> </div></div></td>";
+ addDays(d, dis);
+ if (nwe) {
+ skipWeekend(d, dis);
+ }
+ }
+ s += "</tr></table></div>";
+ bg = $(s).appendTo(element);
+
+ }else{ // skeleton already built, just modify it
+
+ clearEvents();
+
+ // redo column header text and class
+ head.find('tr:first th').slice(1, -1).each(function() {
+ $(this).text(formatDate(d, colFormat, options));
+ this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
+ addDays(d, dis);
+ if (nwe) {
+ skipWeekend(d, dis);
+ }
+ });
+
+ // change classes of background stripes
+ d = cloneDate(d0);
+ bg.find('td').each(function() {
+ this.className = this.className.replace(/^fc-\w+(?= )/, 'fc-' + dayIDs[d.getDay()]);
+ if (+d == +today) {
+ $(this)
+ .removeClass('fc-not-today')
+ .addClass('fc-today')
+ .addClass(tm + '-state-highlight');
+ }else{
+ $(this)
+ .addClass('fc-not-today')
+ .removeClass('fc-today')
+ .removeClass(tm + '-state-highlight');
+ }
+ addDays(d, dis);
+ if (nwe) {
+ skipWeekend(d, dis);
+ }
+ });
+
+ }
+
+ };
+
+
+ function resetScroll() {
+ var d0 = zeroDate(),
+ scrollDate = cloneDate(d0);
+ scrollDate.setHours(options.firstHour);
+ var top = timePosition(d0, scrollDate) + 1, // +1 for the border
+ scroll = function() {
+ body.scrollTop(top);
+ };
+ scroll();
+ setTimeout(scroll, 0); // overrides any previous scroll state made by the browser
+ }
+
+
+ function setHeight(height, dateChanged) {
+ viewHeight = height;
+ slotTopCache = {};
+
+ body.height(height - head.height());
+
+ slotHeight = body.find('tr:first div').height() + 1;
+
+ bg.css({
+ top: head.find('tr').height(),
+ height: height
+ });
+
+ if (dateChanged) {
+ resetScroll();
+ }
+ }
+
+
+ function setWidth(width) {
+ viewWidth = width;
+ colContentPositions.clear();
+
+ body.width(width);
+ bodyTable.width('');
+
+ var topTDs = head.find('tr:first th'),
+ stripeTDs = bg.find('td'),
+ clientWidth = body[0].clientWidth;
+
+ bodyTable.width(clientWidth);
+
+ // time-axis width
+ axisWidth = 0;
+ setOuterWidth(
+ head.find('tr:lt(2) th:first').add(body.find('tr:first th'))
+ .width('')
+ .each(function() {
+ axisWidth = Math.max(axisWidth, $(this).outerWidth());
+ }),
+ axisWidth
+ );
+
+ // column width
+ colWidth = Math.floor((clientWidth - axisWidth) / colCnt);
+ setOuterWidth(stripeTDs.slice(0, -1), colWidth);
+ setOuterWidth(topTDs.slice(1, -2), colWidth);
+ setOuterWidth(topTDs.slice(-2, -1), clientWidth - axisWidth - colWidth*(colCnt-1));
+
+ bg.css({
+ left: axisWidth,
+ width: clientWidth - axisWidth
+ });
+ }
+
+
+
+
+ function slotClick(ev) {
+ var col = Math.floor((ev.pageX - bg.offset().left) / colWidth),
+ date = addDays(cloneDate(view.visStart), dit + dis*col),
+ rowMatch = this.className.match(/fc-slot(\d+)/);
+ if (rowMatch) {
+ var mins = parseInt(rowMatch[1]) * options.slotMinutes,
+ hours = Math.floor(mins/60);
+ date.setHours(hours);
+ date.setMinutes(mins%60 + minMinute);
+ view.trigger('dayClick', this, date, false, ev);
+ }else{
+ view.trigger('dayClick', this, date, true, ev);
+ }
+ }
+
+
+
+ /* Event Rendering
+ -----------------------------------------------------------------------------*/
+
+ function renderEvents(events, modifiedEventId) {
+ view.reportEvents(cachedEvents = events);
+ var i, len=events.length,
+ dayEvents=[],
+ slotEvents=[];
+ for (i=0; i<len; i++) {
+ if (events[i].allDay) {
+ dayEvents.push(events[i]);
+ }else{
+ slotEvents.push(events[i]);
+ }
+ }
+ renderDaySegs(compileDaySegs(dayEvents), modifiedEventId);
+ renderSlotSegs(compileSlotSegs(slotEvents), modifiedEventId);
+ }
+
+
+ function rerenderEvents(modifiedEventId) {
+ clearEvents();
+ renderEvents(cachedEvents, modifiedEventId);
+ }
+
+
+ function clearEvents() {
+ view._clearEvents(); // only clears the hashes
+ daySegmentContainer.empty();
+ slotSegmentContainer.empty();
+ }
+
+
+
+
+
+ function compileDaySegs(events) {
+ var levels = stackSegs(view.sliceSegs(events, $.map(events, visEventEnd), view.visStart, view.visEnd)),
+ i, levelCnt=levels.length, level,
+ j, seg,
+ segs=[];
+ for (i=0; i<levelCnt; i++) {
+ level = levels[i];
+ for (j=0; j<level.length; j++) {
+ seg = level[j];
+ seg.row = 0;
+ seg.level = i;
+ segs.push(seg);
+ }
+ }
+ return segs;
+ }
+
+
+ function compileSlotSegs(events) {
+ var d = addMinutes(cloneDate(view.visStart), minMinute),
+ visEventEnds = $.map(events, visEventEnd),
+ i, col,
+ j, level,
+ k, seg,
+ segs=[];
+ for (i=0; i<colCnt; i++) {
+ col = stackSegs(view.sliceSegs(events, visEventEnds, d, addMinutes(cloneDate(d), maxMinute-minMinute)));
+ countForwardSegs(col);
+ for (j=0; j<col.length; j++) {
+ level = col[j];
+ for (k=0; k<level.length; k++) {
+ seg = level[k];
+ seg.col = i;
+ seg.level = j;
+ segs.push(seg);
+ }
+ }
+ addDays(d, 1, true);
+ }
+ return segs;
+ }
+
+
+
+
+ // renders 'all-day' events at the top
+
+ function renderDaySegs(segs, modifiedEventId) {
+ if (options.allDaySlot) {
+ _renderDaySegs(
+ segs,
+ 1,
+ view,
+ axisWidth,
+ viewWidth,
+ function() {
+ return head.find('tr.fc-all-day')
+ },
+ function(dayOfWeek) {
+ return axisWidth + colContentPositions.left(day2col(dayOfWeek));
+ },
+ function(dayOfWeek) {
+ return axisWidth + colContentPositions.right(day2col(dayOfWeek));
+ },
+ daySegmentContainer,
+ bindDaySegHandlers,
+ modifiedEventId
+ );
+ setHeight(viewHeight); // might have pushed the body down, so resize
+ }
+ }
+
+
+
+ // renders events in the 'time slots' at the bottom
+
+ function renderSlotSegs(segs, modifiedEventId) {
+
+ var i, segCnt=segs.length, seg,
+ event,
+ className,
+ top, bottom,
+ colI, levelI, forward,
+ leftmost,
+ availWidth,
+ outerWidth,
+ left,
+ html='',
+ eventElements,
+ eventElement,
+ triggerRes,
+ vsideCache={},
+ hsideCache={},
+ key, val,
+ titleSpan,
+ height;
+
+ // calculate position/dimensions, create html
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ event = seg.event;
+ className = 'fc-event fc-event-vert ';
+ if (seg.isStart) {
+ className += 'fc-corner-top ';
+ }
+ if (seg.isEnd) {
+ className += 'fc-corner-bottom ';
+ }
+ top = timePosition(seg.start, seg.start);
+ bottom = timePosition(seg.start, seg.end);
+ colI = seg.col;
+ levelI = seg.level;
+ forward = seg.forward || 0;
+ leftmost = axisWidth + colContentPositions.left(colI*dis + dit);
+ availWidth = axisWidth + colContentPositions.right(colI*dis + dit) - leftmost;
+ availWidth = Math.min(availWidth-6, availWidth*.95); // TODO: move this to CSS
+ if (levelI) {
+ // indented and thin
+ outerWidth = availWidth / (levelI + forward + 1);
+ }else{
+ if (forward) {
+ // moderately wide, aligned left still
+ outerWidth = ((availWidth / (forward + 1)) - (12/2)) * 2; // 12 is the predicted width of resizer =
+ }else{
+ // can be entire width, aligned left
+ outerWidth = availWidth;
+ }
+ }
+ left = leftmost + // leftmost possible
+ (availWidth / (levelI + forward + 1) * levelI) // indentation
+ * dis + (rtl ? availWidth - outerWidth : 0); // rtl
+ seg.top = top;
+ seg.left = left;
+ seg.outerWidth = outerWidth;
+ seg.outerHeight = bottom - top;
+ html +=
+ "<div class='" + className + event.className.join(' ') + "' style='position:absolute;z-index:8;top:" + top + "px;left:" + left + "px'>" +
+ "<a" + (event.url ? " href='" + htmlEscape(event.url) + "'" : '') + ">" +
+ "<span class='fc-event-bg'></span>" +
+ "<span class='fc-event-time'>" + htmlEscape(formatDates(event.start, event.end, view.option('timeFormat'))) + "</span>" +
+ "<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
+ "</a>" +
+ ((event.editable || event.editable == undefined && options.editable) && !options.disableResizing && $.fn.resizable ?
+ "<div class='ui-resizable-handle ui-resizable-s'>=</div>"
+ : '') +
+ "</div>";
+ }
+ slotSegmentContainer[0].innerHTML = html; // faster than html()
+ eventElements = slotSegmentContainer.children();
+
+ // retrieve elements, run through eventRender callback, bind event handlers
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ event = seg.event;
+ eventElement = $(eventElements[i]); // faster than eq()
+ triggerRes = view.trigger('eventRender', event, event, eventElement);
+ if (triggerRes === false) {
+ eventElement.remove();
+ }else{
+ if (triggerRes && triggerRes !== true) {
+ eventElement.remove();
+ eventElement = $(triggerRes)
+ .css({
+ position: 'absolute',
+ top: seg.top,
+ left: seg.left
+ })
+ .appendTo(slotSegmentContainer);
+ }
+ seg.element = eventElement;
+ if (event._id === modifiedEventId) {
+ bindSlotSegHandlers(event, eventElement, seg);
+ }else{
+ eventElement[0]._fci = i; // for lazySegBind
+ }
+ view.reportEventElement(event, eventElement);
+ }
+ }
+
+ lazySegBind(slotSegmentContainer, segs, bindSlotSegHandlers);
+
+ // record event sides and title positions
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ if (eventElement = seg.element) {
+ val = vsideCache[key = seg.key = cssKey(eventElement[0])];
+ seg.vsides = val == undefined ? (vsideCache[key] = vsides(eventElement[0], true)) : val;
+ val = hsideCache[key];
+ seg.hsides = val == undefined ? (hsideCache[key] = hsides(eventElement[0], true)) : val;
+ titleSpan = eventElement.find('span.fc-event-title');
+ if (titleSpan.length) {
+ seg.titleTop = titleSpan[0].offsetTop;
+ }
+ }
+ }
+
+ // set all positions/dimensions at once
+ for (i=0; i<segCnt; i++) {
+ seg = segs[i];
+ if (eventElement = seg.element) {
+ eventElement[0].style.width = seg.outerWidth - seg.hsides + 'px';
+ eventElement[0].style.height = (height = seg.outerHeight - seg.vsides) + 'px';
+ event = seg.event;
+ if (seg.titleTop != undefined && height - seg.titleTop < 10) {
+ // not enough room for title, put it in the time header
+ eventElement.find('span.fc-event-time')
+ .text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title);
+ eventElement.find('span.fc-event-title')
+ .remove();
+ }
+ view.trigger('eventAfterRender', event, event, eventElement);
+ }
+ }
+
+ }
+
+
+
+
+
+ function visEventEnd(event) { // returns exclusive 'visible' end, for rendering
+ if (event.allDay) {
+ if (event.end) {
+ var end = cloneDate(event.end);
+ return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
+ }else{
+ return addDays(cloneDate(event.start), 1);
+ }
+ }
+ if (event.end) {
+ return cloneDate(event.end);
+ }else{
+ return addMinutes(cloneDate(event.start), options.defaultEventMinutes);
+ }
+ }
+
+
+
+ function bindDaySegHandlers(event, eventElement, seg) {
+ view.eventElementHandlers(event, eventElement);
+ if (event.editable || event.editable == undefined && options.editable) {
+ draggableDayEvent(event, eventElement, seg.isStart);
+ if (seg.isEnd) {
+ view.resizableDayEvent(event, eventElement, colWidth);
+ }
+ }
+ }
+
+
+
+ function bindSlotSegHandlers(event, eventElement, seg) {
+ view.eventElementHandlers(event, eventElement);
+ if (event.editable || event.editable == undefined && options.editable) {
+ var timeElement = eventElement.find('span.fc-event-time');
+ draggableSlotEvent(event, eventElement, timeElement);
+ if (seg.isEnd) {
+ resizableSlotEvent(event, eventElement, timeElement);
+ }
+ }
+ }
+
+
+
+
+ /* Event Dragging
+ -----------------------------------------------------------------------------*/
+
+
+
+ // when event starts out FULL-DAY
+
+ function draggableDayEvent(event, eventElement, isStart) {
+ if (!options.disableDragging && eventElement.draggable) {
+ var origPosition, origWidth,
+ resetElement,
+ allDay=true,
+ matrix;
+ eventElement.draggable({
+ zIndex: 9,
+ opacity: view.option('dragOpacity', 'month'), // use whatever the month view was using
+ revertDuration: options.dragRevertDuration,
+ start: function(ev, ui) {
+ view.hideEvents(event, eventElement);
+ view.trigger('eventDragStart', eventElement, event, ev, ui);
+ origPosition = eventElement.position();
+ origWidth = eventElement.width();
+ resetElement = function() {
+ if (!allDay) {
+ eventElement
+ .width(origWidth)
+ .height('')
+ .draggable('option', 'grid', null);
+ allDay = true;
+ }
+ };
+ matrix = new HoverMatrix(function(cell) {
+ eventElement.draggable('option', 'revert', !cell || !cell.rowDelta && !cell.colDelta);
+ if (cell) {
+ if (!cell.row) { // on full-days
+ resetElement();
+ view.showOverlay(cell);
+ }else{ // mouse is over bottom slots
+ if (isStart && allDay) {
+ // convert event to temporary slot-event
+ setOuterHeight(
+ eventElement.width(colWidth - 10), // don't use entire width
+ slotHeight * Math.round(
+ (event.end ? ((event.end - event.start)/MINUTE_MS) : options.defaultEventMinutes)
+ /options.slotMinutes)
+ );
+ eventElement.draggable('option', 'grid', [colWidth, 1]);
+ allDay = false;
+ }
+ view.hideOverlay();
+ }
+ }else{ // mouse is outside of everything
+ view.hideOverlay();
+ }
+ });
+ matrix.row(head.find('td'));
+ bg.find('td').each(function() {
+ matrix.col(this);
+ });
+ matrix.row(body);
+ matrix.mouse(ev.pageX, ev.pageY);
+ },
+ drag: function(ev, ui) {
+ matrix.mouse(ev.pageX, ev.pageY);
+ },
+ stop: function(ev, ui) {
+ view.hideOverlay();
+ view.trigger('eventDragStop', eventElement, event, ev, ui);
+ var cell = matrix.cell,
+ dayDelta = dis * (
+ allDay ? // can't trust cell.colDelta when using slot grid
+ (cell ? cell.colDelta : 0) :
+ Math.floor((ui.position.left - origPosition.left) / colWidth)
+ );
+ if (!cell || !dayDelta && !cell.rowDelta) {
+ // over nothing (has reverted)
+ resetElement();
+ if ($.browser.msie) {
+ eventElement.css('filter', ''); // clear IE opacity side-effects
+ }
+ view.showEvents(event, eventElement);
+ }else{
+ eventElement.find('a').removeAttr('href'); // prevents safari from visiting the link
+ view.eventDrop(
+ this, event, dayDelta,
+ allDay ? 0 : // minute delta
+ Math.round((eventElement.offset().top - bodyContent.offset().top) / slotHeight)
+ * options.slotMinutes
+ + minMinute
+ - (event.start.getHours() * 60 + event.start.getMinutes()),
+ allDay, ev, ui
+ );
+ }
+ }
+ });
+ }
+ }
+
+
+
+ // when event starts out IN TIMESLOTS
+
+ function draggableSlotEvent(event, eventElement, timeElement) {
+ if (!options.disableDragging && eventElement.draggable) {
+ var origPosition,
+ resetElement,
+ prevSlotDelta, slotDelta,
+ allDay=false,
+ matrix;
+ eventElement.draggable({
+ zIndex: 9,
+ scroll: false,
+ grid: [colWidth, slotHeight],
+ axis: colCnt==1 ? 'y' : false,
+ opacity: view.option('dragOpacity'),
+ revertDuration: options.dragRevertDuration,
+ start: function(ev, ui) {
+ view.hideEvents(event, eventElement);
+ view.trigger('eventDragStart', eventElement, event, ev, ui);
+ if ($.browser.msie) {
+ eventElement.find('span.fc-event-bg').hide(); // nested opacities mess up in IE, just hide
+ }
+ origPosition = eventElement.position();
+ resetElement = function() {
+ // convert back to original slot-event
+ if (allDay) {
+ timeElement.css('display', ''); // show() was causing display=inline
+ eventElement.draggable('option', 'grid', [colWidth, slotHeight]);
+ allDay = false;
+ }
+ };
+ prevSlotDelta = 0;
+ matrix = new HoverMatrix(function(cell) {
+ eventElement.draggable('option', 'revert', !cell);
+ if (cell) {
+ if (!cell.row && options.allDaySlot) { // over full days
+ if (!allDay) {
+ // convert to temporary all-day event
+ allDay = true;
+ timeElement.hide();
+ eventElement.draggable('option', 'grid', null);
+ }
+ view.showOverlay(cell);
+ }else{ // on slots
+ resetElement();
+ view.hideOverlay();
+ }
+ }else{
+ view.hideOverlay();
+ }
+ });
+ if (options.allDaySlot) {
+ matrix.row(head.find('td'));
+ }
+ bg.find('td').each(function() {
+ matrix.col(this);
+ });
+ matrix.row(body);
+ matrix.mouse(ev.pageX, ev.pageY);
+ },
+ drag: function(ev, ui) {
+ slotDelta = Math.round((ui.position.top - origPosition.top) / slotHeight);
+ if (slotDelta != prevSlotDelta) {
+ if (!allDay) {
+ // update time header
+ var minuteDelta = slotDelta*options.slotMinutes,
+ newStart = addMinutes(cloneDate(event.start), minuteDelta),
+ newEnd;
+ if (event.end) {
+ newEnd = addMinutes(cloneDate(event.end), minuteDelta);
+ }
+ timeElement.text(formatDates(newStart, newEnd, view.option('timeFormat')));
+ }
+ prevSlotDelta = slotDelta;
+ }
+ matrix.mouse(ev.pageX, ev.pageY);
+ },
+ stop: function(ev, ui) {
+ view.hideOverlay();
+ view.trigger('eventDragStop', eventElement, event, ev, ui);
+ var cell = matrix.cell,
+ dayDelta = dis * (
+ allDay ? // can't trust cell.colDelta when using slot grid
+ (cell ? cell.colDelta : 0) :
+ Math.floor((ui.position.left - origPosition.left) / colWidth)
+ );
+ if (!cell || !slotDelta && !dayDelta) {
+ resetElement();
+ if ($.browser.msie) {
+ eventElement
+ .css('filter', '') // clear IE opacity side-effects
+ .find('span.fc-event-bg').css('display', ''); // .show() made display=inline
+ }
+ eventElement.css(origPosition); // sometimes fast drags make event revert to wrong position
+ view.showEvents(event, eventElement);
+ }else{
+ view.eventDrop(
+ this, event, dayDelta,
+ allDay ? 0 : slotDelta * options.slotMinutes, // minute delta
+ allDay, ev, ui
+ );
+ }
+ }
+ });
+ }
+ }
+
+
+
+
+ /* Event Resizing
+ -----------------------------------------------------------------------------*/
+
+ // for TIMESLOT events
+
+ function resizableSlotEvent(event, eventElement, timeElement) {
+ if (!options.disableResizing && eventElement.resizable) {
+ var slotDelta, prevSlotDelta;
+ eventElement.resizable({
+ handles: {
+ s: 'div.ui-resizable-s'
+ },
+ grid: slotHeight,
+ start: function(ev, ui) {
+ slotDelta = prevSlotDelta = 0;
+ view.hideEvents(event, eventElement);
+ if ($.browser.msie && $.browser.version == '6.0') {
+ eventElement.css('overflow', 'hidden');
+ }
+ eventElement.css('z-index', 9);
+ view.trigger('eventResizeStart', this, event, ev, ui);
+ },
+ resize: function(ev, ui) {
+ // don't rely on ui.size.height, doesn't take grid into account
+ slotDelta = Math.round((Math.max(slotHeight, eventElement.height()) - ui.originalSize.height) / slotHeight);
+ if (slotDelta != prevSlotDelta) {
+ timeElement.text(
+ formatDates(
+ event.start,
+ (!slotDelta && !event.end) ? null : // no change, so don't display time range
+ addMinutes(view.eventEnd(event), options.slotMinutes*slotDelta),
+ view.option('timeFormat')
+ )
+ );
+ prevSlotDelta = slotDelta;
+ }
+ },
+ stop: function(ev, ui) {
+ view.trigger('eventResizeStop', this, event, ev, ui);
+ if (slotDelta) {
+ view.eventResize(this, event, 0, options.slotMinutes*slotDelta, ev, ui);
+ }else{
+ eventElement.css('z-index', 8);
+ view.showEvents(event, eventElement);
+ // BUG: if event was really short, need to put title back in span
+ }
+ }
+ });
+ }
+ }
+
+
+
+
+ /* Misc
+ -----------------------------------------------------------------------------*/
+
+ // get the Y coordinate of the given time on the given day (both Date objects)
+
+ function timePosition(day, time) { // both date objects. day holds 00:00 of current day
+ day = cloneDate(day, true);
+ if (time < addMinutes(cloneDate(day), minMinute)) {
+ return 0;
+ }
+ if (time >= addMinutes(cloneDate(day), maxMinute)) {
+ return bodyContent.height();
+ }
+ var slotMinutes = options.slotMinutes,
+ minutes = time.getHours()*60 + time.getMinutes() - minMinute,
+ slotI = Math.floor(minutes / slotMinutes),
+ slotTop = slotTopCache[slotI];
+ if (slotTop == undefined) {
+ slotTop = slotTopCache[slotI] = body.find('tr:eq(' + slotI + ') td div')[0].offsetTop;
+ }
+ return Math.max(0, Math.round(
+ slotTop - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes)
+ ));
+ }
+
+
+
+
+ function day2col(dayOfWeek) {
+ return ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt)*dis+dit;
+ }
+
+
+}
+
+
+// count the number of colliding, higher-level segments (for event squishing)
+
+function countForwardSegs(levels) {
+ var i, j, k, level, segForward, segBack;
+ for (i=levels.length-1; i>0; i--) {
+ level = levels[i];
+ for (j=0; j<level.length; j++) {
+ segForward = level[j];
+ for (k=0; k<levels[i-1].length; k++) {
+ segBack = levels[i-1][k];
+ if (segsCollide(segForward, segBack)) {
+ segBack.forward = Math.max(segBack.forward||0, (segForward.forward||0)+1);
+ }
+ }
+ }
+ }
+}
+
+
+/* Methods & Utilities for All Views
+-----------------------------------------------------------------------------*/
+
+var viewMethods = {
+
+ // TODO: maybe change the 'vis' variables to 'excl'
+
+ /*
+ * Objects inheriting these methods must implement the following properties/methods:
+ * - title
+ * - start
+ * - end
+ * - visStart
+ * - visEnd
+ * - defaultEventEnd(event)
+ * - render(events)
+ * - rerenderEvents()
+ *
+ *
+ * z-index reservations:
+ * 3 - day-overlay
+ * 8 - events
+ * 9 - dragging/resizing events
+ *
+ */
+
+
+
+ init: function(element, options) {
+ this.element = element;
+ this.options = options;
+ this.eventsByID = {};
+ this.eventElements = [];
+ this.eventElementsByID = {};
+ },
+
+
+
+ // triggers an event handler, always append view as last arg
+
+ trigger: function(name, thisObj) {
+ if (this.options[name]) {
+ return this.options[name].apply(thisObj || this, Array.prototype.slice.call(arguments, 2).concat([this]));
+ }
+ },
+
+
+
+ // returns a Date object for an event's end
+
+ eventEnd: function(event) {
+ return event.end ? cloneDate(event.end) : this.defaultEventEnd(event); // TODO: make sure always using copies
+ },
+
+
+
+ // report when view receives new events
+
+ reportEvents: function(events) { // events are already normalized at this point
+ var i, len=events.length, event,
+ eventsByID = this.eventsByID = {};
+ for (i=0; i<len; i++) {
+ event = events[i];
+ if (eventsByID[event._id]) {
+ eventsByID[event._id].push(event);
+ }else{
+ eventsByID[event._id] = [event];
+ }
+ }
+ },
+
+
+
+ // report when view creates an element for an event
+
+ reportEventElement: function(event, element) {
+ this.eventElements.push(element);
+ var eventElementsByID = this.eventElementsByID;
+ if (eventElementsByID[event._id]) {
+ eventElementsByID[event._id].push(element);
+ }else{
+ eventElementsByID[event._id] = [element];
+ }
+ },
+
+
+
+ // event element manipulation
+
+ _clearEvents: function() { // only resets hashes
+ this.eventElements = [];
+ this.eventElementsByID = {};
+ },
+
+ showEvents: function(event, exceptElement) {
+ this._eee(event, exceptElement, 'show');
+ },
+
+ hideEvents: function(event, exceptElement) {
+ this._eee(event, exceptElement, 'hide');
+ },
+
+ _eee: function(event, exceptElement, funcName) { // event-element-each
+ var elements = this.eventElementsByID[event._id],
+ i, len = elements.length;
+ for (i=0; i<len; i++) {
+ if (elements[i][0] != exceptElement[0]) { // AHAHAHAHAHAHAHAH
+ elements[i][funcName]();
+ }
+ }
+ },
+
+
+
+ // event modification reporting
+
+ eventDrop: function(e, event, dayDelta, minuteDelta, allDay, ev, ui) {
+ var view = this,
+ oldAllDay = event.allDay,
+ eventId = event._id;
+ view.moveEvents(view.eventsByID[eventId], dayDelta, minuteDelta, allDay);
+ view.trigger('eventDrop', e, event, dayDelta, minuteDelta, allDay, function() { // TODO: change docs
+ // TODO: investigate cases where this inverse technique might not work
+ view.moveEvents(view.eventsByID[eventId], -dayDelta, -minuteDelta, oldAllDay);
+ view.rerenderEvents();
+ }, ev, ui);
+ view.eventsChanged = true;
+ view.rerenderEvents(eventId);
+ },
+
+ eventResize: function(e, event, dayDelta, minuteDelta, ev, ui) {
+ var view = this,
+ eventId = event._id;
+ view.elongateEvents(view.eventsByID[eventId], dayDelta, minuteDelta);
+ view.trigger('eventResize', e, event, dayDelta, minuteDelta, function() {
+ // TODO: investigate cases where this inverse technique might not work
+ view.elongateEvents(view.eventsByID[eventId], -dayDelta, -minuteDelta);
+ view.rerenderEvents();
+ }, ev, ui);
+ view.eventsChanged = true;
+ view.rerenderEvents(eventId);
+ },
+
+
+
+ // event modification
+
+ moveEvents: function(events, dayDelta, minuteDelta, allDay) {
+ minuteDelta = minuteDelta || 0;
+ for (var e, len=events.length, i=0; i<len; i++) {
+ e = events[i];
+ if (allDay != undefined) {
+ e.allDay = allDay;
+ }
+ addMinutes(addDays(e.start, dayDelta, true), minuteDelta);
+ if (e.end) {
+ e.end = addMinutes(addDays(e.end, dayDelta, true), minuteDelta);
+ }
+ normalizeEvent(e, this.options);
+ }
+ },
+
+ elongateEvents: function(events, dayDelta, minuteDelta) {
+ minuteDelta = minuteDelta || 0;
+ for (var e, len=events.length, i=0; i<len; i++) {
+ e = events[i];
+ e.end = addMinutes(addDays(this.eventEnd(e), dayDelta, true), minuteDelta);
+ normalizeEvent(e, this.options);
+ }
+ },
+
+
+
+ // semi-transparent overlay (while dragging)
+
+ showOverlay: function(props) {
+ if (!this.dayOverlay) {
+ this.dayOverlay = $("<div class='fc-cell-overlay' style='position:absolute;z-index:3;display:none'/>")
+ .appendTo(this.element);
+ }
+ var o = this.element.offset();
+ this.dayOverlay
+ .css({
+ top: props.top - o.top,
+ left: props.left - o.left,
+ width: props.width,
+ height: props.height
+ })
+ .show();
+ },
+
+ hideOverlay: function() {
+ if (this.dayOverlay) {
+ this.dayOverlay.hide();
+ }
+ },
+
+
+
+ // common horizontal event resizing
+
+ resizableDayEvent: function(event, eventElement, colWidth) {
+ var view = this;
+ if (!view.options.disableResizing && eventElement.resizable) {
+ eventElement.resizable({
+ handles: view.options.isRTL ? {w:'div.ui-resizable-w'} : {e:'div.ui-resizable-e'},
+ grid: colWidth,
+ minWidth: colWidth/2, // need this or else IE throws errors when too small
+ containment: view.element.parent().parent(), // the main element...
+ // ... a fix. wouldn't allow extending to last column in agenda views (jq ui bug?)
+ start: function(ev, ui) {
+ eventElement.css('z-index', 9);
+ view.hideEvents(event, eventElement);
+ view.trigger('eventResizeStart', this, event, ev, ui);
+ },
+ stop: function(ev, ui) {
+ view.trigger('eventResizeStop', this, event, ev, ui);
+ // ui.size.width wasn't working with grid correctly, use .width()
+ var dayDelta = Math.round((eventElement.width() - ui.originalSize.width) / colWidth);
+ if (dayDelta) {
+ view.eventResize(this, event, dayDelta, 0, ev, ui);
+ }else{
+ eventElement.css('z-index', 8);
+ view.showEvents(event, eventElement);
+ }
+ }
+ });
+ }
+ },
+
+
+
+ // attaches eventClick, eventMouseover, eventMouseout
+
+ eventElementHandlers: function(event, eventElement) {
+ var view = this;
+ eventElement
+ .click(function(ev) {
+ if (!eventElement.hasClass('ui-draggable-dragging') &&
+ !eventElement.hasClass('ui-resizable-resizing')) {
+ return view.trigger('eventClick', this, event, ev);
+ }
+ })
+ .hover(
+ function(ev) {
+ view.trigger('eventMouseover', this, event, ev);
+ },
+ function(ev) {
+ view.trigger('eventMouseout', this, event, ev);
+ }
+ );
+ },
+
+
+
+ // get a property from the 'options' object, using smart view naming
+
+ option: function(name, viewName) {
+ var v = this.options[name];
+ if (typeof v == 'object') {
+ return smartProperty(v, viewName || this.name);
+ }
+ return v;
+ },
+
+
+
+ // event rendering utilities
+
+ sliceSegs: function(events, visEventEnds, start, end) {
+ var segs = [],
+ i, len=events.length, event,
+ eventStart, eventEnd,
+ segStart, segEnd,
+ isStart, isEnd;
+ for (i=0; i<len; i++) {
+ event = events[i];
+ eventStart = event.start;
+ eventEnd = visEventEnds[i];
+ if (eventEnd > start && eventStart < end) {
+ if (eventStart < start) {
+ segStart = cloneDate(start);
+ isStart = false;
+ }else{
+ segStart = eventStart;
+ isStart = true;
+ }
+ if (eventEnd > end) {
+ segEnd = cloneDate(end);
+ isEnd = false;
+ }else{
+ segEnd = eventEnd;
+ isEnd = true;
+ }
+ segs.push({
+ event: event,
+ start: segStart,
+ end: segEnd,
+ isStart: isStart,
+ isEnd: isEnd,
+ msLength: segEnd - segStart
+ });
+ }
+ }
+ return segs.sort(segCmp);
+ }
+
+
+};
+
+
+
+function lazySegBind(container, segs, bindHandlers) {
+ container.unbind('mouseover').mouseover(function(ev) {
+ var parent=ev.target, e,
+ i, seg;
+ while (parent != this) {
+ e = parent;
+ parent = parent.parentNode;
+ }
+ if ((i = e._fci) != undefined) {
+ e._fci = undefined;
+ seg = segs[i];
+ bindHandlers(seg.event, seg.element, seg);
+ $(ev.target).trigger(ev);
+ }
+ ev.stopPropagation();
+ });
+}
+
+
+
+// event rendering calculation utilities
+
+function stackSegs(segs) {
+ var levels = [],
+ i, len = segs.length, seg,
+ j, collide, k;
+ for (i=0; i<len; i++) {
+ seg = segs[i];
+ j = 0; // the level index where seg should belong
+ while (true) {
+ collide = false;
+ if (levels[j]) {
+ for (k=0; k<levels[j].length; k++) {
+ if (segsCollide(levels[j][k], seg)) {
+ collide = true;
+ break;
+ }
+ }
+ }
+ if (collide) {
+ j++;
+ }else{
+ break;
+ }
+ }
+ if (levels[j]) {
+ levels[j].push(seg);
+ }else{
+ levels[j] = [seg];
+ }
+ }
+ return levels;
+}
+
+function segCmp(a, b) {
+ return (b.msLength - a.msLength) * 100 + (a.event.start - b.event.start);
+}
+
+function segsCollide(seg1, seg2) {
+ return seg1.end > seg2.start && seg1.start < seg2.end;
+}
+
+
+
+
+/* Date Math
+-----------------------------------------------------------------------------*/
+
+var DAY_MS = 86400000,
+ HOUR_MS = 3600000,
+ MINUTE_MS = 60000;
+
+function addYears(d, n, keepTime) {
+ d.setFullYear(d.getFullYear() + n);
+ if (!keepTime) {
+ clearTime(d);
+ }
+ return d;
+}
+
+function addMonths(d, n, keepTime) { // prevents day overflow/underflow
+ if (+d) { // prevent infinite looping on invalid dates
+ var m = d.getMonth() + n,
+ check = cloneDate(d);
+ check.setDate(1);
+ check.setMonth(m);
+ d.setMonth(m);
+ if (!keepTime) {
+ clearTime(d);
+ }
+ while (d.getMonth() != check.getMonth()) {
+ d.setDate(d.getDate() + (d < check ? 1 : -1));
+ }
+ }
+ return d;
+}
+
+function addDays(d, n, keepTime) { // deals with daylight savings
+ if (+d) {
+ var dd = d.getDate() + n,
+ check = cloneDate(d);
+ check.setHours(9); // set to middle of day
+ check.setDate(dd);
+ d.setDate(dd);
+ if (!keepTime) {
+ clearTime(d);
+ }
+ fixDate(d, check);
+ }
+ return d;
+}
+fc.addDays = addDays;
+
+function fixDate(d, check) { // force d to be on check's YMD, for daylight savings purposes
+ if (+d) { // prevent infinite looping on invalid dates
+ while (d.getDate() != check.getDate()) {
+ d.setTime(+d + (d < check ? 1 : -1) * HOUR_MS);
+ }
+ }
+}
+
+function addMinutes(d, n) {
+ d.setMinutes(d.getMinutes() + n);
+ return d;
+}
+
+function clearTime(d) {
+ d.setHours(0);
+ d.setMinutes(0);
+ d.setSeconds(0);
+ d.setMilliseconds(0);
+ return d;
+}
+
+function cloneDate(d, dontKeepTime) {
+ if (dontKeepTime) {
+ return clearTime(new Date(+d));
+ }
+ return new Date(+d);
+}
+
+function zeroDate() { // returns a Date with time 00:00:00 and dateOfMonth=1
+ var i=0, d;
+ do {
+ d = new Date(1970, i++, 1);
+ } while (d.getHours() != 0);
+ return d;
+}
+
+function skipWeekend(date, inc, excl) {
+ inc = inc || 1;
+ while (date.getDay()==0 || (excl && date.getDay()==1 || !excl && date.getDay()==6)) {
+ addDays(date, inc);
+ }
+ return date;
+}
+
+
+
+/* Date Parsing
+-----------------------------------------------------------------------------*/
+
+var parseDate = fc.parseDate = function(s) {
+ if (typeof s == 'object') { // already a Date object
+ return s;
+ }
+ if (typeof s == 'number') { // a UNIX timestamp
+ return new Date(s * 1000);
+ }
+ if (typeof s == 'string') {
+ if (s.match(/^\d+$/)) { // a UNIX timestamp
+ return new Date(parseInt(s) * 1000);
+ }
+ return parseISO8601(s, true) || (s ? new Date(s) : null);
+ }
+ // TODO: never return invalid dates (like from new Date(<string>)), return null instead
+ return null;
+}
+
+var parseISO8601 = fc.parseISO8601 = function(s, ignoreTimezone) {
+ // derived from http://delete.me.uk/2005/03/iso8601.html
+ // TODO: for a know glitch/feature, read tests/issue_206_parseDate_dst.html
+ var m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/);
+ if (!m) {
+ return null;
+ }
+ var date = new Date(m[1], 0, 1),
+ check = new Date(m[1], 0, 1, 9, 0),
+ offset = 0;
+ if (m[3]) {
+ date.setMonth(m[3] - 1);
+ check.setMonth(m[3] - 1);
+ }
+ if (m[5]) {
+ date.setDate(m[5]);
+ check.setDate(m[5]);
+ }
+ fixDate(date, check);
+ if (m[7]) {
+ date.setHours(m[7]);
+ }
+ if (m[8]) {
+ date.setMinutes(m[8]);
+ }
+ if (m[10]) {
+ date.setSeconds(m[10]);
+ }
+ if (m[12]) {
+ date.setMilliseconds(Number("0." + m[12]) * 1000);
+ }
+ fixDate(date, check);
+ if (!ignoreTimezone) {
+ if (m[14]) {
+ offset = Number(m[16]) * 60 + Number(m[17]);
+ offset *= m[15] == '-' ? 1 : -1;
+ }
+ offset -= date.getTimezoneOffset();
+ }
+ return new Date(+date + (offset * 60 * 1000));
+}
+
+var parseTime = fc.parseTime = function(s) { // returns minutes since start of day
+ if (typeof s == 'number') { // an hour
+ return s * 60;
+ }
+ if (typeof s == 'object') { // a Date object
+ return s.getHours() * 60 + s.getMinutes();
+ }
+ var m = s.match(/(\d+)(?::(\d+))?\s*(\w+)?/);
+ if (m) {
+ var h = parseInt(m[1]);
+ if (m[3]) {
+ h %= 12;
+ if (m[3].toLowerCase().charAt(0) == 'p') {
+ h += 12;
+ }
+ }
+ return h * 60 + (m[2] ? parseInt(m[2]) : 0);
+ }
+};
+
+
+
+/* Date Formatting
+-----------------------------------------------------------------------------*/
+
+var formatDate = fc.formatDate = function(date, format, options) {
+ return formatDates(date, null, format, options);
+}
+
+var formatDates = fc.formatDates = function(date1, date2, format, options) {
+ options = options || defaults;
+ var date = date1,
+ otherDate = date2,
+ i, len = format.length, c,
+ i2, formatter,
+ res = '';
+ for (i=0; i<len; i++) {
+ c = format.charAt(i);
+ if (c == "'") {
+ for (i2=i+1; i2<len; i2++) {
+ if (format.charAt(i2) == "'") {
+ if (date) {
+ if (i2 == i+1) {
+ res += "'";
+ }else{
+ res += format.substring(i+1, i2);
+ }
+ i = i2;
+ }
+ break;
+ }
+ }
+ }
+ else if (c == '(') {
+ for (i2=i+1; i2<len; i2++) {
+ if (format.charAt(i2) == ')') {
+ var subres = formatDate(date, format.substring(i+1, i2), options);
+ if (parseInt(subres.replace(/\D/, ''))) {
+ res += subres;
+ }
+ i = i2;
+ break;
+ }
+ }
+ }
+ else if (c == '[') {
+ for (i2=i+1; i2<len; i2++) {
+ if (format.charAt(i2) == ']') {
+ var subformat = format.substring(i+1, i2);
+ var subres = formatDate(date, subformat, options);
+ if (subres != formatDate(otherDate, subformat, options)) {
+ res += subres;
+ }
+ i = i2;
+ break;
+ }
+ }
+ }
+ else if (c == '{') {
+ date = date2;
+ otherDate = date1;
+ }
+ else if (c == '}') {
+ date = date1;
+ otherDate = date2;
+ }
+ else {
+ for (i2=len; i2>i; i2--) {
+ if (formatter = dateFormatters[format.substring(i, i2)]) {
+ if (date) {
+ res += formatter(date, options);
+ }
+ i = i2 - 1;
+ break;
+ }
+ }
+ if (i2 == i) {
+ if (date) {
+ res += c;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+var dateFormatters = {
+ s : function(d) { return d.getSeconds() },
+ ss : function(d) { return zeroPad(d.getSeconds()) },
+ m : function(d) { return d.getMinutes() },
+ mm : function(d) { return zeroPad(d.getMinutes()) },
+ h : function(d) { return d.getHours() % 12 || 12 },
+ hh : function(d) { return zeroPad(d.getHours() % 12 || 12) },
+ H : function(d) { return d.getHours() },
+ HH : function(d) { return zeroPad(d.getHours()) },
+ d : function(d) { return d.getDate() },
+ dd : function(d) { return zeroPad(d.getDate()) },
+ ddd : function(d,o) { return o.dayNamesShort[d.getDay()] },
+ dddd: function(d,o) { return o.dayNames[d.getDay()] },
+ M : function(d) { return d.getMonth() + 1 },
+ MM : function(d) { return zeroPad(d.getMonth() + 1) },
+ MMM : function(d,o) { return o.monthNamesShort[d.getMonth()] },
+ MMMM: function(d,o) { return o.monthNames[d.getMonth()] },
+ yy : function(d) { return (d.getFullYear()+'').substring(2) },
+ yyyy: function(d) { return d.getFullYear() },
+ t : function(d) { return d.getHours() < 12 ? 'a' : 'p' },
+ tt : function(d) { return d.getHours() < 12 ? 'am' : 'pm' },
+ T : function(d) { return d.getHours() < 12 ? 'A' : 'P' },
+ TT : function(d) { return d.getHours() < 12 ? 'AM' : 'PM' },
+ u : function(d) { return formatDate(d, "yyyy-MM-dd'T'HH:mm:ss'Z'") },
+ S : function(d) {
+ var date = d.getDate();
+ if (date > 10 && date < 20) return 'th';
+ return ['st', 'nd', 'rd'][date%10-1] || 'th';
+ }
+};
+
+
+
+/* Element Dimensions
+-----------------------------------------------------------------------------*/
+
+function setOuterWidth(element, width, includeMargins) {
+ element.each(function(i, _element) {
+ _element.style.width = width - hsides(_element, includeMargins) + 'px';
+ });
+}
+
+function setOuterHeight(element, height, includeMargins) {
+ element.each(function(i, _element) {
+ _element.style.height = height - vsides(_element, includeMargins) + 'px';
+ });
+}
+
+
+function hsides(_element, includeMargins) {
+ return (parseFloat(jQuery.curCSS(_element, 'paddingLeft', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'paddingRight', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'borderLeftWidth', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'borderRightWidth', true)) || 0) +
+ (includeMargins ? hmargins(_element) : 0);
+}
+
+function hmargins(_element) {
+ return (parseFloat(jQuery.curCSS(_element, 'marginLeft', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'marginRight', true)) || 0);
+}
+
+function vsides(_element, includeMargins) {
+ return (parseFloat(jQuery.curCSS(_element, 'paddingTop', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'paddingBottom', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'borderTopWidth', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'borderBottomWidth', true)) || 0) +
+ (includeMargins ? vmargins(_element) : 0);
+}
+
+function vmargins(_element) {
+ return (parseFloat(jQuery.curCSS(_element, 'marginTop', true)) || 0) +
+ (parseFloat(jQuery.curCSS(_element, 'marginBottom', true)) || 0);
+}
+
+
+
+
+function setMinHeight(element, h) {
+ h = typeof h == 'number' ? h + 'px' : h;
+ element[0].style.cssText += ';min-height:' + h + ';_height:' + h;
+}
+
+
+
+/* Position Calculation
+-----------------------------------------------------------------------------*/
+// nasty bugs in opera 9.25
+// position()'s top returning incorrectly with TR/TD or elements within TD
+
+var topBug;
+
+function topCorrect(tr) { // tr/th/td or anything else
+ if (topBug !== false) {
+ var cell;
+ if (tr.is('th,td')) {
+ tr = (cell = tr).parent();
+ }
+ if (topBug == undefined && tr.is('tr')) {
+ topBug = tr.position().top != tr.children().position().top;
+ }
+ if (topBug) {
+ return tr.parent().position().top + (cell ? tr.position().top - cell.position().top : 0);
+ }
+ }
+ return 0;
+}
+
+
+
+/* Hover Matrix
+-----------------------------------------------------------------------------*/
+
+function HoverMatrix(changeCallback) {
+
+ var t=this,
+ tops=[], lefts=[],
+ prevRowE, prevColE,
+ origRow, origCol,
+ currRow, currCol;
+
+ t.row = function(e) {
+ prevRowE = $(e);
+ tops.push(prevRowE.offset().top + topCorrect(prevRowE));
+ };
+
+ t.col = function(e) {
+ prevColE = $(e);
+ lefts.push(prevColE.offset().left);
+ };
+
+ t.mouse = function(x, y) {
+ if (origRow == undefined) {
+ tops.push(tops[tops.length-1] + prevRowE.outerHeight());
+ lefts.push(lefts[lefts.length-1] + prevColE.outerWidth());
+ currRow = currCol = -1;
+ }
+ var r, c;
+ for (r=0; r<tops.length && y>=tops[r]; r++) ;
+ for (c=0; c<lefts.length && x>=lefts[c]; c++) ;
+ r = r >= tops.length ? -1 : r - 1;
+ c = c >= lefts.length ? -1 : c - 1;
+ if (r != currRow || c != currCol) {
+ currRow = r;
+ currCol = c;
+ if (r == -1 || c == -1) {
+ t.cell = null;
+ }else{
+ if (origRow == undefined) {
+ origRow = r;
+ origCol = c;
+ }
+ t.cell = {
+ row: r,
+ col: c,
+ top: tops[r],
+ left: lefts[c],
+ width: lefts[c+1] - lefts[c],
+ height: tops[r+1] - tops[r],
+ isOrig: r==origRow && c==origCol,
+ rowDelta: r-origRow,
+ colDelta: c-origCol
+ };
+ }
+ changeCallback(t.cell);
+ }
+ };
+
+}
+
+
+
+/* Misc Utils
+-----------------------------------------------------------------------------*/
+
+var undefined,
+ dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
+ arrayPop = Array.prototype.pop;
+
+function zeroPad(n) {
+ return (n < 10 ? '0' : '') + n;
+}
+
+function smartProperty(obj, name) { // get a camel-cased/namespaced property of an object
+ if (obj[name] != undefined) {
+ return obj[name];
+ }
+ var parts = name.split(/(?=[A-Z])/),
+ i=parts.length-1, res;
+ for (; i>=0; i--) {
+ res = obj[parts[i].toLowerCase()];
+ if (res != undefined) {
+ return res;
+ }
+ }
+ return obj[''];
+}
+
+function htmlEscape(s) {
+ return s
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/'/g, ''')
+ .replace(/"/g, '"')
+}
+
+
+
+function HorizontalPositionCache(getElement) {
+
+ var t = this,
+ elements = {},
+ lefts = {},
+ rights = {};
+
+ function e(i) {
+ return elements[i] =
+ elements[i] || getElement(i);
+ }
+
+ t.left = function(i) {
+ return lefts[i] =
+ lefts[i] == undefined ? e(i).position().left : lefts[i];
+ };
+
+ t.right = function(i) {
+ return rights[i] =
+ rights[i] == undefined ? t.left(i) + e(i).width() : rights[i];
+ };
+
+ t.clear = function() {
+ elements = {};
+ lefts = {};
+ rights = {};
+ };
+
+}
+
+
+
+function cssKey(_element) {
+ return _element.id + '/' + _element.className + '/' + _element.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig, '');
+}
+
+
+
+
+})(jQuery);
\ No newline at end of file
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/index.jsp
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/index.jsp (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/index.jsp 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,6 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1" %>
+
+<%
+ response.sendRedirect("faces/page.xhtml");
+%>
\ No newline at end of file
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/jquery.js
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/jquery.js (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/jquery.js 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(!
H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(fun!
ction(){var G=this;while(G.firstChild){G=G.firstChild}return G!
}).appen
d(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.no!
CloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pu!
shStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilt!
er(E,thi
s)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.!
makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;functi!
on K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?!
(N.getEl
ementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"}!
,isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?!
I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\!
s+/),fun
ction(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}ret!
urn o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("di!
v");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S!
){return
}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.le!
ngth){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}!
if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return !
I&&I.spe
cified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}!
return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){retu!
rn o.nth(E,2,"previousSibling")},nextAll:function(E){return o.!
dir(E,"n
extSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeo!
f E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"q!
ueue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.ma!
keArray(
H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)!
}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){!
if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=!
false;if
(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{!
"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementByI!
d!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]!
:[]}},NA
ME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}ret!
urn X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"sub!
mit"===T.type},image:function(T){return"image"===T.type},reset!
:functio
n(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}!
}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var !
M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[!
O].sourc
e+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplic!
ate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undef!
ined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.h!
ref=func
tion(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;f!
or(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.!
match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}!
T=I.rela
tive[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);!
H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort(!
).join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}!
else{for
(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)!
}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaK!
ey newValue originalTarget pageX pageY prevValue relatedNode r!
elatedTa
rget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},s!
pecial:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagatio!
nStopped:k,isImmediatePropagationStopped:k};var a=function(F){!
var E=F.
relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}r!
eturn this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/!
\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false!
,readyLi
st:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,e!
rror").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.st!
yle.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:fal!
se,noClo
neEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.s!
lice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o!
.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend!
({get:fu
nction(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.dat!
a=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.h!
ost)){var H=document.getElementsByTagName("head")[0];var T=doc!
ument.cr
eateElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState!
==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxSt!
op")}}return J},handleError:function(F,H,E,G){if(F.error){F.er!
ror(H,E,
G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunctio!
n(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G]!
,"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.le!
ngth;G<F
;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cu!
r(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};retur!
n E},easing:{linear:function(G,H,E,F){return E+F*G},swing:func!
tion(G,H
,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n)!
;n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.e!
lem)}return false}else{var J=G-this.startTime;this.state=J/thi!
s.option
s.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this!
[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{to!
p:N,left:I}}}o.offset={initialize:function(){if(this.initializ!
ed){retu
rn}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:functi!
on(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||th!
is[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxMode!
l&&docum
ent.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/page.xhtml
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/page.xhtml (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/page.xhtml 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:a4j="http://richfaces.org/a4j"
+ xmlns:rich="http://richfaces.org/rich"
+ xmlns:c="http://java.sun.com/jstl/core">
+
+<head>
+ <a4j:loadScript src="resource:///org.ajax4jsf.javascript.AjaxScript" />
+ <a4j:loadScript src="/jquery.js" />
+ <a4j:loadScript src="/ui.core.js" />
+ <a4j:loadScript src="/ui.dragable.js" />
+ <a4j:loadScript src="/ui.resizeable.js" />
+ <a4j:loadScript src="/fullcalendar.js" />
+ <a4j:loadScript src="/richfaces.fullcalendar.js" />
+
+ <style type='text/css'>
+ body {
+ margin-top: 40px;
+ text-align: center;
+ font-size: 14px;
+ font-family: "Lucida Grande", Helvetica, Arial, Verdana, sans-serif;
+ }
+
+ .rich-fullc-loading {
+ position: absolute;
+ top: 5px;
+ right: 5px;
+ }
+
+ .rich-fullc {
+ width: 900px;
+ margin: 0 auto;
+ }
+ </style>
+</head>
+
+<body>
+
+ <h:form>
+ <ui:fragment binding="#{componentBean.component}">
+ <f:facet name="loading">
+ wait: loading...
+ </f:facet>
+ </ui:fragment>
+ </h:form>
+
+</body>
+
+
+</html>
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/richfaces.fullcalendar.js
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/richfaces.fullcalendar.js (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/richfaces.fullcalendar.js 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,60 @@
+window.RichFaces = window.RichFaces || {};
+
+window.RichFaces.FullCalendar = (function() {
+ var formatDateParam = function(date) {
+ return Math.round(date.getTime() / 1000);
+ }
+
+ return function(id, ajaxFunc) {
+ this.id = id;
+ this.ajaxFunc = ajaxFunc;
+ var elt = document.getElementById(id);
+ if (!elt) {
+ //TODO handle missing element
+ return ;
+ }
+
+ var _this = this;
+ var fillCalendarFunction = function(startDate, endDate, callback) {
+ var event = {};
+ _this.ajaxFunc({} /* stub event */,
+ formatDateParam(startDate),
+ formatDateParam(endDate),
+ function(request, event, data) {
+ callback(data);
+ }
+ );
+ };
+
+ jQuery(document).ready(function() {
+
+ jQuery(elt).fullCalendar({
+
+ editable: true,
+
+ events: fillCalendarFunction,
+
+ eventDrop: function(event, delta) {
+ alert(event.title + ' was moved ' + delta + ' days\n' +
+ '(should probably update your database)');
+ },
+
+ loading: function(bool) {
+ var loadingElt = document.getElementById(id + ":loading");
+ if (loadingElt) {
+ if (bool) {
+ jQuery(loadingElt).show();
+ } else {
+ jQuery(loadingElt).hide();
+ }
+ }
+ }
+
+ });
+
+ });
+ };
+
+}());
+
+
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.core.js
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.core.js (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.core.js 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,519 @@
+/*
+ * jQuery UI 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+;jQuery.ui || (function($) {
+
+var _remove = $.fn.remove,
+ isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);
+
+//Helper functions and ui object
+$.ui = {
+ version: "1.7.2",
+
+ // $.ui.plugin is deprecated. Use the proxy pattern instead.
+ plugin: {
+ add: function(module, option, set) {
+ var proto = $.ui[module].prototype;
+ for(var i in set) {
+ proto.plugins[i] = proto.plugins[i] || [];
+ proto.plugins[i].push([option, set[i]]);
+ }
+ },
+ call: function(instance, name, args) {
+ var set = instance.plugins[name];
+ if(!set || !instance.element[0].parentNode) { return; }
+
+ for (var i = 0; i < set.length; i++) {
+ if (instance.options[set[i][0]]) {
+ set[i][1].apply(instance.element, args);
+ }
+ }
+ }
+ },
+
+ contains: function(a, b) {
+ return document.compareDocumentPosition
+ ? a.compareDocumentPosition(b) & 16
+ : a !== b && a.contains(b);
+ },
+
+ hasScroll: function(el, a) {
+
+ //If overflow is hidden, the element might have extra content, but the user wants to hide it
+ if ($(el).css('overflow') == 'hidden') { return false; }
+
+ var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
+ has = false;
+
+ if (el[scroll] > 0) { return true; }
+
+ // TODO: determine which cases actually cause this to happen
+ // if the element doesn't have the scroll set, see if it's possible to
+ // set the scroll
+ el[scroll] = 1;
+ has = (el[scroll] > 0);
+ el[scroll] = 0;
+ return has;
+ },
+
+ isOverAxis: function(x, reference, size) {
+ //Determines when x coordinate is over "b" element axis
+ return (x > reference) && (x < (reference + size));
+ },
+
+ isOver: function(y, x, top, left, height, width) {
+ //Determines when x, y coordinates is over "b" element
+ return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
+ },
+
+ keyCode: {
+ BACKSPACE: 8,
+ CAPS_LOCK: 20,
+ COMMA: 188,
+ CONTROL: 17,
+ DELETE: 46,
+ DOWN: 40,
+ END: 35,
+ ENTER: 13,
+ ESCAPE: 27,
+ HOME: 36,
+ INSERT: 45,
+ LEFT: 37,
+ NUMPAD_ADD: 107,
+ NUMPAD_DECIMAL: 110,
+ NUMPAD_DIVIDE: 111,
+ NUMPAD_ENTER: 108,
+ NUMPAD_MULTIPLY: 106,
+ NUMPAD_SUBTRACT: 109,
+ PAGE_DOWN: 34,
+ PAGE_UP: 33,
+ PERIOD: 190,
+ RIGHT: 39,
+ SHIFT: 16,
+ SPACE: 32,
+ TAB: 9,
+ UP: 38
+ }
+};
+
+// WAI-ARIA normalization
+if (isFF2) {
+ var attr = $.attr,
+ removeAttr = $.fn.removeAttr,
+ ariaNS = "http://www.w3.org/2005/07/aaa",
+ ariaState = /^aria-/,
+ ariaRole = /^wairole:/;
+
+ $.attr = function(elem, name, value) {
+ var set = value !== undefined;
+
+ return (name == 'role'
+ ? (set
+ ? attr.call(this, elem, name, "wairole:" + value)
+ : (attr.apply(this, arguments) || "").replace(ariaRole, ""))
+ : (ariaState.test(name)
+ ? (set
+ ? elem.setAttributeNS(ariaNS,
+ name.replace(ariaState, "aaa:"), value)
+ : attr.call(this, elem, name.replace(ariaState, "aaa:")))
+ : attr.apply(this, arguments)));
+ };
+
+ $.fn.removeAttr = function(name) {
+ return (ariaState.test(name)
+ ? this.each(function() {
+ this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
+ }) : removeAttr.call(this, name));
+ };
+}
+
+//jQuery plugins
+$.fn.extend({
+ remove: function() {
+ // Safari has a native remove event which actually removes DOM elements,
+ // so we have to use triggerHandler instead of trigger (#3037).
+ $("*", this).add(this).each(function() {
+ $(this).triggerHandler("remove");
+ });
+ return _remove.apply(this, arguments );
+ },
+
+ enableSelection: function() {
+ return this
+ .attr('unselectable', 'off')
+ .css('MozUserSelect', '')
+ .unbind('selectstart.ui');
+ },
+
+ disableSelection: function() {
+ return this
+ .attr('unselectable', 'on')
+ .css('MozUserSelect', 'none')
+ .bind('selectstart.ui', function() { return false; });
+ },
+
+ scrollParent: function() {
+ var scrollParent;
+ if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
+ scrollParent = this.parents().filter(function() {
+ 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));
+ }).eq(0);
+ } else {
+ scrollParent = this.parents().filter(function() {
+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
+ }).eq(0);
+ }
+
+ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
+ }
+});
+
+
+//Additional selectors
+$.extend($.expr[':'], {
+ data: function(elem, i, match) {
+ return !!$.data(elem, match[3]);
+ },
+
+ focusable: function(element) {
+ var nodeName = element.nodeName.toLowerCase(),
+ tabIndex = $.attr(element, 'tabindex');
+ return (/input|select|textarea|button|object/.test(nodeName)
+ ? !element.disabled
+ : 'a' == nodeName || 'area' == nodeName
+ ? element.href || !isNaN(tabIndex)
+ : !isNaN(tabIndex))
+ // the element and all of its ancestors must be visible
+ // the browser may report that the area is hidden
+ && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
+ },
+
+ tabbable: function(element) {
+ var tabIndex = $.attr(element, 'tabindex');
+ return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
+ }
+});
+
+
+// $.widget is a factory to create jQuery plugins
+// taking some boilerplate code out of the plugin code
+function getter(namespace, plugin, method, args) {
+ function getMethods(type) {
+ var methods = $[namespace][plugin][type] || [];
+ return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
+ }
+
+ var methods = getMethods('getter');
+ if (args.length == 1 && typeof args[0] == 'string') {
+ methods = methods.concat(getMethods('getterSetter'));
+ }
+ return ($.inArray(method, methods) != -1);
+}
+
+$.widget = function(name, prototype) {
+ var namespace = name.split(".")[0];
+ name = name.split(".")[1];
+
+ // create plugin method
+ $.fn[name] = function(options) {
+ var isMethodCall = (typeof options == 'string'),
+ args = Array.prototype.slice.call(arguments, 1);
+
+ // prevent calls to internal methods
+ if (isMethodCall && options.substring(0, 1) == '_') {
+ return this;
+ }
+
+ // handle getter methods
+ if (isMethodCall && getter(namespace, name, options, args)) {
+ var instance = $.data(this[0], name);
+ return (instance ? instance[options].apply(instance, args)
+ : undefined);
+ }
+
+ // handle initialization and non-getter methods
+ return this.each(function() {
+ var instance = $.data(this, name);
+
+ // constructor
+ (!instance && !isMethodCall &&
+ $.data(this, name, new $[namespace][name](this, options))._init());
+
+ // method call
+ (instance && isMethodCall && $.isFunction(instance[options]) &&
+ instance[options].apply(instance, args));
+ });
+ };
+
+ // create widget constructor
+ $[namespace] = $[namespace] || {};
+ $[namespace][name] = function(element, options) {
+ var self = this;
+
+ this.namespace = namespace;
+ this.widgetName = name;
+ this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
+ this.widgetBaseClass = namespace + '-' + name;
+
+ this.options = $.extend({},
+ $.widget.defaults,
+ $[namespace][name].defaults,
+ $.metadata && $.metadata.get(element)[name],
+ options);
+
+ this.element = $(element)
+ .bind('setData.' + name, function(event, key, value) {
+ if (event.target == element) {
+ return self._setData(key, value);
+ }
+ })
+ .bind('getData.' + name, function(event, key) {
+ if (event.target == element) {
+ return self._getData(key);
+ }
+ })
+ .bind('remove', function() {
+ return self.destroy();
+ });
+ };
+
+ // add widget prototype
+ $[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
+
+ // TODO: merge getter and getterSetter properties from widget prototype
+ // and plugin prototype
+ $[namespace][name].getterSetter = 'option';
+};
+
+$.widget.prototype = {
+ _init: function() {},
+ destroy: function() {
+ this.element.removeData(this.widgetName)
+ .removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
+ .removeAttr('aria-disabled');
+ },
+
+ option: function(key, value) {
+ var options = key,
+ self = this;
+
+ if (typeof key == "string") {
+ if (value === undefined) {
+ return this._getData(key);
+ }
+ options = {};
+ options[key] = value;
+ }
+
+ $.each(options, function(key, value) {
+ self._setData(key, value);
+ });
+ },
+ _getData: function(key) {
+ return this.options[key];
+ },
+ _setData: function(key, value) {
+ this.options[key] = value;
+
+ if (key == 'disabled') {
+ this.element
+ [value ? 'addClass' : 'removeClass'](
+ this.widgetBaseClass + '-disabled' + ' ' +
+ this.namespace + '-state-disabled')
+ .attr("aria-disabled", value);
+ }
+ },
+
+ enable: function() {
+ this._setData('disabled', false);
+ },
+ disable: function() {
+ this._setData('disabled', true);
+ },
+
+ _trigger: function(type, event, data) {
+ var callback = this.options[type],
+ eventName = (type == this.widgetEventPrefix
+ ? type : this.widgetEventPrefix + type);
+
+ event = $.Event(event);
+ event.type = eventName;
+
+ // copy original event properties over to the new event
+ // this would happen if we could call $.event.fix instead of $.Event
+ // but we don't have a way to force an event to be fixed multiple times
+ if (event.originalEvent) {
+ for (var i = $.event.props.length, prop; i;) {
+ prop = $.event.props[--i];
+ event[prop] = event.originalEvent[prop];
+ }
+ }
+
+ this.element.trigger(event, data);
+
+ return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
+ || event.isDefaultPrevented());
+ }
+};
+
+$.widget.defaults = {
+ disabled: false
+};
+
+
+/** Mouse Interaction Plugin **/
+
+$.ui.mouse = {
+ _mouseInit: function() {
+ var self = this;
+
+ this.element
+ .bind('mousedown.'+this.widgetName, function(event) {
+ return self._mouseDown(event);
+ })
+ .bind('click.'+this.widgetName, function(event) {
+ if(self._preventClickEvent) {
+ self._preventClickEvent = false;
+ event.stopImmediatePropagation();
+ return false;
+ }
+ });
+
+ // Prevent text selection in IE
+ if ($.browser.msie) {
+ this._mouseUnselectable = this.element.attr('unselectable');
+ this.element.attr('unselectable', 'on');
+ }
+
+ this.started = false;
+ },
+
+ // TODO: make sure destroying one instance of mouse doesn't mess with
+ // other instances of mouse
+ _mouseDestroy: function() {
+ this.element.unbind('.'+this.widgetName);
+
+ // Restore text selection in IE
+ ($.browser.msie
+ && this.element.attr('unselectable', this._mouseUnselectable));
+ },
+
+ _mouseDown: function(event) {
+ // don't let more than one widget handle mouseStart
+ // TODO: figure out why we have to use originalEvent
+ event.originalEvent = event.originalEvent || {};
+ if (event.originalEvent.mouseHandled) { return; }
+
+ // we may have missed mouseup (out of window)
+ (this._mouseStarted && this._mouseUp(event));
+
+ this._mouseDownEvent = event;
+
+ var self = this,
+ btnIsLeft = (event.which == 1),
+ elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
+ return true;
+ }
+
+ this.mouseDelayMet = !this.options.delay;
+ if (!this.mouseDelayMet) {
+ this._mouseDelayTimer = setTimeout(function() {
+ self.mouseDelayMet = true;
+ }, this.options.delay);
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted = (this._mouseStart(event) !== false);
+ if (!this._mouseStarted) {
+ event.preventDefault();
+ return true;
+ }
+ }
+
+ // these delegates are required to keep context
+ this._mouseMoveDelegate = function(event) {
+ return self._mouseMove(event);
+ };
+ this._mouseUpDelegate = function(event) {
+ return self._mouseUp(event);
+ };
+ $(document)
+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ // preventDefault() is used to prevent the selection of text here -
+ // however, in Safari, this causes select boxes not to be selectable
+ // anymore, so this fix is needed
+ ($.browser.safari || event.preventDefault());
+
+ event.originalEvent.mouseHandled = true;
+ return true;
+ },
+
+ _mouseMove: function(event) {
+ // IE mouseup check - mouseup happened when mouse was out of window
+ if ($.browser.msie && !event.button) {
+ return this._mouseUp(event);
+ }
+
+ if (this._mouseStarted) {
+ this._mouseDrag(event);
+ return event.preventDefault();
+ }
+
+ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
+ this._mouseStarted =
+ (this._mouseStart(this._mouseDownEvent, event) !== false);
+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
+ }
+
+ return !this._mouseStarted;
+ },
+
+ _mouseUp: function(event) {
+ $(document)
+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
+
+ if (this._mouseStarted) {
+ this._mouseStarted = false;
+ this._preventClickEvent = (event.target == this._mouseDownEvent.target);
+ this._mouseStop(event);
+ }
+
+ return false;
+ },
+
+ _mouseDistanceMet: function(event) {
+ return (Math.max(
+ Math.abs(this._mouseDownEvent.pageX - event.pageX),
+ Math.abs(this._mouseDownEvent.pageY - event.pageY)
+ ) >= this.options.distance
+ );
+ },
+
+ _mouseDelayMet: function(event) {
+ return this.mouseDelayMet;
+ },
+
+ // These are placeholder methods, to be overriden by extending plugin
+ _mouseStart: function(event) {},
+ _mouseDrag: function(event) {},
+ _mouseStop: function(event) {},
+ _mouseCapture: function(event) { return true; }
+};
+
+$.ui.mouse.defaults = {
+ cancel: null,
+ distance: 1,
+ delay: 0
+};
+
+})(jQuery);
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.draggable.js
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.draggable.js (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.draggable.js 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,766 @@
+/*
+ * jQuery UI Draggable 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function($) {
+
+$.widget("ui.draggable", $.extend({}, $.ui.mouse, {
+
+ _init: function() {
+
+ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))
+ this.element[0].style.position = 'relative';
+
+ (this.options.addClasses && this.element.addClass("ui-draggable"));
+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));
+
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+ if(!this.element.data('draggable')) return;
+ this.element
+ .removeData("draggable")
+ .unbind(".draggable")
+ .removeClass("ui-draggable"
+ + " ui-draggable-dragging"
+ + " ui-draggable-disabled");
+ this._mouseDestroy();
+ },
+
+ _mouseCapture: function(event) {
+
+ var o = this.options;
+
+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))
+ return false;
+
+ //Quit if we're not on a valid handle
+ this.handle = this._getHandle(event);
+ if (!this.handle)
+ return false;
+
+ return true;
+
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options;
+
+ //Create and append the visible helper
+ this.helper = this._createHelper(event);
+
+ //Cache the helper size
+ this._cacheHelperProportions();
+
+ //If ddmanager is used for droppables, set the global draggable
+ if($.ui.ddmanager)
+ $.ui.ddmanager.current = this;
+
+ /*
+ * - Position generation -
+ * This block generates everything position related - it's the core of draggables.
+ */
+
+ //Cache the margins of the original element
+ this._cacheMargins();
+
+ //Store the helper's css position
+ this.cssPosition = this.helper.css("position");
+ this.scrollParent = this.helper.scrollParent();
+
+ //The element's absolute position on the page minus margins
+ this.offset = this.element.offset();
+ this.offset = {
+ top: this.offset.top - this.margins.top,
+ left: this.offset.left - this.margins.left
+ };
+
+ $.extend(this.offset, {
+ click: { //Where the click happened, relative to the element
+ left: event.pageX - this.offset.left,
+ top: event.pageY - this.offset.top
+ },
+ parent: this._getParentOffset(),
+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
+ });
+
+ //Generate the original position
+ this.originalPosition = this._generatePosition(event);
+ this.originalPageX = event.pageX;
+ this.originalPageY = event.pageY;
+
+ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
+ if(o.cursorAt)
+ this._adjustOffsetFromHelper(o.cursorAt);
+
+ //Set a containment if given in the options
+ if(o.containment)
+ this._setContainment();
+
+ //Call plugins and callbacks
+ this._trigger("start", event);
+
+ //Recache the helper size
+ this._cacheHelperProportions();
+
+ //Prepare the droppable offsets
+ if ($.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(this, event);
+
+ this.helper.addClass("ui-draggable-dragging");
+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
+ return true;
+ },
+
+ _mouseDrag: function(event, noPropagation) {
+
+ //Compute the helpers position
+ this.position = this._generatePosition(event);
+ this.positionAbs = this._convertPositionTo("absolute");
+
+ //Call plugins and callbacks and use the resulting position if something is returned
+ if (!noPropagation) {
+ var ui = this._uiHash();
+ this._trigger('drag', event, ui);
+ this.position = ui.position;
+ }
+
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ //If we are using droppables, inform the manager about the drop
+ var dropped = false;
+ if ($.ui.ddmanager && !this.options.dropBehaviour)
+ dropped = $.ui.ddmanager.drop(this, event);
+
+ //if a drop comes from outside (a sortable)
+ if(this.dropped) {
+ dropped = this.dropped;
+ this.dropped = false;
+ }
+
+ 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))) {
+ var self = this;
+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
+ self._trigger("stop", event);
+ self._clear();
+ });
+ } else {
+ this._trigger("stop", event);
+ this._clear();
+ }
+
+ return false;
+ },
+
+ _getHandle: function(event) {
+
+ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;
+ $(this.options.handle, this.element)
+ .find("*")
+ .andSelf()
+ .each(function() {
+ if(this == event.target) handle = true;
+ });
+
+ return handle;
+
+ },
+
+ _createHelper: function(event) {
+
+ var o = this.options;
+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);
+
+ if(!helper.parents('body').length)
+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));
+
+ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))
+ helper.css("position", "absolute");
+
+ return helper;
+
+ },
+
+ _adjustOffsetFromHelper: function(obj) {
+ if(obj.left != undefined) this.offset.click.left = obj.left + this.margins.left;
+ if(obj.right != undefined) this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
+ if(obj.top != undefined) this.offset.click.top = obj.top + this.margins.top;
+ if(obj.bottom != undefined) this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
+ },
+
+ _getParentOffset: function() {
+
+ //Get the offsetParent and cache its position
+ this.offsetParent = this.helper.offsetParent();
+ var po = this.offsetParent.offset();
+
+ // This is a special case where we need to modify a offset calculated on start, since the following happened:
+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {
+ po.left += this.scrollParent.scrollLeft();
+ po.top += this.scrollParent.scrollTop();
+ }
+
+ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information
+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix
+ po = { top: 0, left: 0 };
+
+ return {
+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
+ };
+
+ },
+
+ _getRelativeOffset: function() {
+
+ if(this.cssPosition == "relative") {
+ var p = this.element.position();
+ return {
+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
+ };
+ } else {
+ return { top: 0, left: 0 };
+ }
+
+ },
+
+ _cacheMargins: function() {
+ this.margins = {
+ left: (parseInt(this.element.css("marginLeft"),10) || 0),
+ top: (parseInt(this.element.css("marginTop"),10) || 0)
+ };
+ },
+
+ _cacheHelperProportions: function() {
+ this.helperProportions = {
+ width: this.helper.outerWidth(),
+ height: this.helper.outerHeight()
+ };
+ },
+
+ _setContainment: function() {
+
+ var o = this.options;
+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;
+ if(o.containment == 'document' || o.containment == 'window') this.containment = [
+ 0 - this.offset.relative.left - this.offset.parent.left,
+ 0 - this.offset.relative.top - this.offset.parent.top,
+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,
+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
+ ];
+
+ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {
+ var ce = $(o.containment)[0]; if(!ce) return;
+ var co = $(o.containment).offset();
+ var over = ($(ce).css("overflow") != 'hidden');
+
+ this.containment = [
+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
+ 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,
+ 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
+ ];
+ } else if(o.containment.constructor == Array) {
+ this.containment = o.containment;
+ }
+
+ },
+
+ _convertPositionTo: function(d, pos) {
+
+ if(!pos) pos = this.position;
+ var mod = d == "absolute" ? 1 : -1;
+ 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);
+
+ return {
+ top: (
+ pos.top // The absolute mouse position
+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
+ ),
+ left: (
+ pos.left // The absolute mouse position
+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent
+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)
+ - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
+ )
+ };
+
+ },
+
+ _generatePosition: function(event) {
+
+ 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);
+
+ // This is another very weird special case that only happens for relative elements:
+ // 1. If the css position is relative
+ // 2. and the scroll parent is the document or similar to the offset parent
+ // we have to refresh the relative offset during the scroll so there are no jumps
+ if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) {
+ this.offset.relative = this._getRelativeOffset();
+ }
+
+ var pageX = event.pageX;
+ var pageY = event.pageY;
+
+ /*
+ * - Position constraining -
+ * Constrain the position to a mix of grid, containment.
+ */
+
+ if(this.originalPosition) { //If we are not dragging yet, we won't check for options
+
+ if(this.containment) {
+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
+ }
+
+ if(o.grid) {
+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
+ 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;
+
+ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
+ 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;
+ }
+
+ }
+
+ return {
+ top: (
+ pageY // The absolute mouse position
+ - this.offset.click.top // Click offset (relative to the element)
+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
+ ),
+ left: (
+ pageX // The absolute mouse position
+ - this.offset.click.left // Click offset (relative to the element)
+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent
+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)
+ + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
+ )
+ };
+
+ },
+
+ _clear: function() {
+ this.helper.removeClass("ui-draggable-dragging");
+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();
+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;
+ this.helper = null;
+ this.cancelHelperRemoval = false;
+ },
+
+ // From now on bulk stuff - mainly helpers
+
+ _trigger: function(type, event, ui) {
+ ui = ui || this._uiHash();
+ $.ui.plugin.call(this, type, [event, ui]);
+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins
+ return $.widget.prototype._trigger.call(this, type, event, ui);
+ },
+
+ plugins: {},
+
+ _uiHash: function(event) {
+ return {
+ helper: this.helper,
+ position: this.position,
+ absolutePosition: this.positionAbs, //deprecated
+ offset: this.positionAbs
+ };
+ }
+
+}));
+
+$.extend($.ui.draggable, {
+ version: "1.7.2",
+ eventPrefix: "drag",
+ defaults: {
+ addClasses: true,
+ appendTo: "parent",
+ axis: false,
+ cancel: ":input,option",
+ connectToSortable: false,
+ containment: false,
+ cursor: "auto",
+ cursorAt: false,
+ delay: 0,
+ distance: 1,
+ grid: false,
+ handle: false,
+ helper: "original",
+ iframeFix: false,
+ opacity: false,
+ refreshPositions: false,
+ revert: false,
+ revertDuration: 500,
+ scope: "default",
+ scroll: true,
+ scrollSensitivity: 20,
+ scrollSpeed: 20,
+ snap: false,
+ snapMode: "both",
+ snapTolerance: 20,
+ stack: false,
+ zIndex: false
+ }
+});
+
+$.ui.plugin.add("draggable", "connectToSortable", {
+ start: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options,
+ uiSortable = $.extend({}, ui, { item: inst.element });
+ inst.sortables = [];
+ $(o.connectToSortable).each(function() {
+ var sortable = $.data(this, 'sortable');
+ if (sortable && !sortable.options.disabled) {
+ inst.sortables.push({
+ instance: sortable,
+ shouldRevert: sortable.options.revert
+ });
+ sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache
+ sortable._trigger("activate", event, uiSortable);
+ }
+ });
+
+ },
+ stop: function(event, ui) {
+
+ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
+ var inst = $(this).data("draggable"),
+ uiSortable = $.extend({}, ui, { item: inst.element });
+
+ $.each(inst.sortables, function() {
+ if(this.instance.isOver) {
+
+ this.instance.isOver = 0;
+
+ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
+
+ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'
+ if(this.shouldRevert) this.instance.options.revert = true;
+
+ //Trigger the stop of the sortable
+ this.instance._mouseStop(event);
+
+ this.instance.options.helper = this.instance.options._helper;
+
+ //If the helper has been the original item, restore properties in the sortable
+ if(inst.options.helper == 'original')
+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });
+
+ } else {
+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
+ this.instance._trigger("deactivate", event, uiSortable);
+ }
+
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), self = this;
+
+ var checkPos = function(o) {
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
+ var itemHeight = o.height, itemWidth = o.width;
+ var itemTop = o.top, itemLeft = o.left;
+
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
+ };
+
+ $.each(inst.sortables, function(i) {
+
+ //Copy over some variables to allow calling the sortable's native _intersectsWith
+ this.instance.positionAbs = inst.positionAbs;
+ this.instance.helperProportions = inst.helperProportions;
+ this.instance.offset.click = inst.offset.click;
+
+ if(this.instance._intersectsWith(this.instance.containerCache)) {
+
+ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
+ if(!this.instance.isOver) {
+
+ this.instance.isOver = 1;
+ //Now we fake the start of dragging for the sortable instance,
+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
+ //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)
+ this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);
+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
+ this.instance.options.helper = function() { return ui.helper[0]; };
+
+ event.target = this.instance.currentItem[0];
+ this.instance._mouseCapture(event, true);
+ this.instance._mouseStart(event, true, true);
+
+ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
+ this.instance.offset.click.top = inst.offset.click.top;
+ this.instance.offset.click.left = inst.offset.click.left;
+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
+
+ inst._trigger("toSortable", event);
+ inst.dropped = this.instance.element; //draggable revert needs that
+ //hack so receive/update callbacks work (mostly)
+ inst.currentItem = inst.element;
+ this.instance.fromOutside = inst;
+
+ }
+
+ //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
+ if(this.instance.currentItem) this.instance._mouseDrag(event);
+
+ } else {
+
+ //If it doesn't intersect with the sortable, and it intersected before,
+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
+ if(this.instance.isOver) {
+
+ this.instance.isOver = 0;
+ this.instance.cancelHelperRemoval = true;
+
+ //Prevent reverting on this forced stop
+ this.instance.options.revert = false;
+
+ // The out event needs to be triggered independently
+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));
+
+ this.instance._mouseStop(event, true);
+ this.instance.options.helper = this.instance.options._helper;
+
+ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
+ this.instance.currentItem.remove();
+ if(this.instance.placeholder) this.instance.placeholder.remove();
+
+ inst._trigger("fromSortable", event);
+ inst.dropped = false; //draggable revert needs that
+ }
+
+ };
+
+ });
+
+ }
+});
+
+$.ui.plugin.add("draggable", "cursor", {
+ start: function(event, ui) {
+ var t = $('body'), o = $(this).data('draggable').options;
+ if (t.css("cursor")) o._cursor = t.css("cursor");
+ t.css("cursor", o.cursor);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if (o._cursor) $('body').css("cursor", o._cursor);
+ }
+});
+
+$.ui.plugin.add("draggable", "iframeFix", {
+ start: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
+ .css({
+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",
+ position: "absolute", opacity: "0.001", zIndex: 1000
+ })
+ .css($(this).offset())
+ .appendTo("body");
+ });
+ },
+ stop: function(event, ui) {
+ $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers
+ }
+});
+
+$.ui.plugin.add("draggable", "opacity", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data('draggable').options;
+ if(t.css("opacity")) o._opacity = t.css("opacity");
+ t.css('opacity', o.opacity);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data('draggable').options;
+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);
+ }
+});
+
+$.ui.plugin.add("draggable", "scroll", {
+ start: function(event, ui) {
+ var i = $(this).data("draggable");
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();
+ },
+ drag: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options, scrolled = false;
+
+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {
+
+ if(!o.axis || o.axis != 'x') {
+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)
+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)
+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
+ }
+
+ } else {
+
+ if(!o.axis || o.axis != 'x') {
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
+ }
+
+ if(!o.axis || o.axis != 'y') {
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
+ }
+
+ }
+
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
+ $.ui.ddmanager.prepareOffsets(i, event);
+
+ }
+});
+
+$.ui.plugin.add("draggable", "snap", {
+ start: function(event, ui) {
+
+ var i = $(this).data("draggable"), o = i.options;
+ i.snapElements = [];
+
+ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {
+ var $t = $(this); var $o = $t.offset();
+ if(this != i.element[0]) i.snapElements.push({
+ item: this,
+ width: $t.outerWidth(), height: $t.outerHeight(),
+ top: $o.top, left: $o.left
+ });
+ });
+
+ },
+ drag: function(event, ui) {
+
+ var inst = $(this).data("draggable"), o = inst.options;
+ var d = o.snapTolerance;
+
+ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
+
+ for (var i = inst.snapElements.length - 1; i >= 0; i--){
+
+ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,
+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;
+
+ //Yes, I know, this is insane ;)
+ 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))) {
+ 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 })));
+ inst.snapElements[i].snapping = false;
+ continue;
+ }
+
+ if(o.snapMode != 'inner') {
+ var ts = Math.abs(t - y2) <= d;
+ var bs = Math.abs(b - y1) <= d;
+ var ls = Math.abs(l - x2) <= d;
+ var rs = Math.abs(r - x1) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
+ }
+
+ var first = (ts || bs || ls || rs);
+
+ if(o.snapMode != 'outer') {
+ var ts = Math.abs(t - y1) <= d;
+ var bs = Math.abs(b - y2) <= d;
+ var ls = Math.abs(l - x1) <= d;
+ var rs = Math.abs(r - x2) <= d;
+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
+ }
+
+ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))
+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
+
+ };
+
+ }
+});
+
+$.ui.plugin.add("draggable", "stack", {
+ start: function(event, ui) {
+
+ var o = $(this).data("draggable").options;
+
+ var group = $.makeArray($(o.stack.group)).sort(function(a,b) {
+ return (parseInt($(a).css("zIndex"),10) || o.stack.min) - (parseInt($(b).css("zIndex"),10) || o.stack.min);
+ });
+
+ $(group).each(function(i) {
+ this.style.zIndex = o.stack.min + i;
+ });
+
+ this[0].style.zIndex = o.stack.min + group.length;
+
+ }
+});
+
+$.ui.plugin.add("draggable", "zIndex", {
+ start: function(event, ui) {
+ var t = $(ui.helper), o = $(this).data("draggable").options;
+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");
+ t.css('zIndex', o.zIndex);
+ },
+ stop: function(event, ui) {
+ var o = $(this).data("draggable").options;
+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);
+ }
+});
+
+})(jQuery);
Added: branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.resizable.js
===================================================================
--- branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.resizable.js (rev 0)
+++ branches/community/3.3.X/sandbox/samples/full-calendar/src/main/webapp/ui.resizable.js 2010-04-29 01:40:35 UTC (rev 16835)
@@ -0,0 +1,800 @@
+/*
+ * jQuery UI Resizable 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function($) {
+
+$.widget("ui.resizable", $.extend({}, $.ui.mouse, {
+
+ _init: function() {
+
+ var self = this, o = this.options;
+ this.element.addClass("ui-resizable");
+
+ $.extend(this, {
+ _aspectRatio: !!(o.aspectRatio),
+ aspectRatio: o.aspectRatio,
+ originalElement: this.element,
+ _proportionallyResizeElements: [],
+ _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null
+ });
+
+ //Wrap the element if it cannot hold child nodes
+ if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
+
+ //Opera fix for relative positioning
+ if (/relative/.test(this.element.css('position')) && $.browser.opera)
+ this.element.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ //Create a wrapper element and set the wrapper to the new current internal element
+ this.element.wrap(
+ $('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({
+ position: this.element.css('position'),
+ width: this.element.outerWidth(),
+ height: this.element.outerHeight(),
+ top: this.element.css('top'),
+ left: this.element.css('left')
+ })
+ );
+
+ //Overwrite the original this.element
+ this.element = this.element.parent().data(
+ "resizable", this.element.data('resizable')
+ );
+
+ this.elementIsWrapper = true;
+
+ //Move margins to the wrapper
+ this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
+ this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
+
+ //Prevent Safari textarea resize
+ this.originalResizeStyle = this.originalElement.css('resize');
+ this.originalElement.css('resize', 'none');
+
+ //Push the actual element to our proportionallyResize internal array
+ this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' }));
+
+ // avoid IE jump (hard set the margin)
+ this.originalElement.css({ margin: this.originalElement.css('margin') });
+
+ // fix handlers offset
+ this._proportionallyResize();
+
+ }
+
+ 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' });
+ if(this.handles.constructor == String) {
+
+ if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw';
+ var n = this.handles.split(","); this.handles = {};
+
+ for(var i = 0; i < n.length; i++) {
+
+ var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle;
+ var axis = $('<div class="ui-resizable-handle ' + hname + '"></div>');
+
+ // increase zIndex of sw, se, ne, nw axis
+ //TODO : this modifies original option
+ if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex });
+
+ //TODO : What's going on here?
+ if ('se' == handle) {
+ axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se');
+ };
+
+ //Insert into internal handles object and append to element
+ this.handles[handle] = '.ui-resizable-'+handle;
+ this.element.append(axis);
+ }
+
+ }
+
+ this._renderAxis = function(target) {
+
+ target = target || this.element;
+
+ for(var i in this.handles) {
+
+ if(this.handles[i].constructor == String)
+ this.handles[i] = $(this.handles[i], this.element).show();
+
+ //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
+ if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
+
+ var axis = $(this.handles[i], this.element), padWrapper = 0;
+
+ //Checking the correct pad and border
+ padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
+
+ //The padding type i have to apply...
+ var padPos = [ 'padding',
+ /ne|nw|n/.test(i) ? 'Top' :
+ /se|sw|s/.test(i) ? 'Bottom' :
+ /^e$/.test(i) ? 'Right' : 'Left' ].join("");
+
+ target.css(padPos, padWrapper);
+
+ this._proportionallyResize();
+
+ }
+
+ //TODO: What's that good for? There's not anything to be executed left
+ if(!$(this.handles[i]).length)
+ continue;
+
+ }
+ };
+
+ //TODO: make renderAxis a prototype function
+ this._renderAxis(this.element);
+
+ this._handles = $('.ui-resizable-handle', this.element)
+ .disableSelection();
+
+ //Matching axis name
+ this._handles.mouseover(function() {
+ if (!self.resizing) {
+ if (this.className)
+ var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
+ //Axis, default = se
+ self.axis = axis && axis[1] ? axis[1] : 'se';
+ }
+ });
+
+ //If we want to auto hide the elements
+ if (o.autoHide) {
+ this._handles.hide();
+ $(this.element)
+ .addClass("ui-resizable-autohide")
+ .hover(function() {
+ $(this).removeClass("ui-resizable-autohide");
+ self._handles.show();
+ },
+ function(){
+ if (!self.resizing) {
+ $(this).addClass("ui-resizable-autohide");
+ self._handles.hide();
+ }
+ });
+ }
+
+ //Initialize the mouse interaction
+ this._mouseInit();
+
+ },
+
+ destroy: function() {
+
+ this._mouseDestroy();
+
+ var _destroy = function(exp) {
+ $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
+ .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove();
+ };
+
+ //TODO: Unwrap at same DOM position
+ if (this.elementIsWrapper) {
+ _destroy(this.element);
+ var wrapper = this.element;
+ wrapper.parent().append(
+ this.originalElement.css({
+ position: wrapper.css('position'),
+ width: wrapper.outerWidth(),
+ height: wrapper.outerHeight(),
+ top: wrapper.css('top'),
+ left: wrapper.css('left')
+ })
+ ).end().remove();
+ }
+
+ this.originalElement.css('resize', this.originalResizeStyle);
+ _destroy(this.originalElement);
+
+ },
+
+ _mouseCapture: function(event) {
+
+ var handle = false;
+ for(var i in this.handles) {
+ if($(this.handles[i])[0] == event.target) handle = true;
+ }
+
+ return this.options.disabled || !!handle;
+
+ },
+
+ _mouseStart: function(event) {
+
+ var o = this.options, iniPos = this.element.position(), el = this.element;
+
+ this.resizing = true;
+ this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() };
+
+ // bugfix for http://dev.jquery.com/ticket/1749
+ if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) {
+ el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left });
+ }
+
+ //Opera fixing relative position
+ if ($.browser.opera && (/relative/).test(el.css('position')))
+ el.css({ position: 'relative', top: 'auto', left: 'auto' });
+
+ this._renderProxy();
+
+ var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top'));
+
+ if (o.containment) {
+ curleft += $(o.containment).scrollLeft() || 0;
+ curtop += $(o.containment).scrollTop() || 0;
+ }
+
+ //Store needed variables
+ this.offset = this.helper.offset();
+ this.position = { left: curleft, top: curtop };
+ this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
+ this.originalPosition = { left: curleft, top: curtop };
+ this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
+ this.originalMousePosition = { left: event.pageX, top: event.pageY };
+
+ //Aspect Ratio
+ this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
+
+ var cursor = $('.ui-resizable-' + this.axis).css('cursor');
+ $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor);
+
+ el.addClass("ui-resizable-resizing");
+ this._propagate("start", event);
+ return true;
+ },
+
+ _mouseDrag: function(event) {
+
+ //Increase performance, avoid regex
+ var el = this.helper, o = this.options, props = {},
+ self = this, smp = this.originalMousePosition, a = this.axis;
+
+ var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0;
+ var trigger = this._change[a];
+ if (!trigger) return false;
+
+ // Calculate the attrs that will be change
+ var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff;
+
+ if (this._aspectRatio || event.shiftKey)
+ data = this._updateRatio(data, event);
+
+ data = this._respectSize(data, event);
+
+ // plugins callbacks need to be called first
+ this._propagate("resize", event);
+
+ el.css({
+ top: this.position.top + "px", left: this.position.left + "px",
+ width: this.size.width + "px", height: this.size.height + "px"
+ });
+
+ if (!this._helper && this._proportionallyResizeElements.length)
+ this._proportionallyResize();
+
+ this._updateCache(data);
+
+ // calling the user callback at the end
+ this._trigger('resize', event, this.ui());
+
+ return false;
+ },
+
+ _mouseStop: function(event) {
+
+ this.resizing = false;
+ var o = this.options, self = this;
+
+ if(this._helper) {
+ var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var s = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ if (!o.animate)
+ this.element.css($.extend(s, { top: top, left: left }));
+
+ self.helper.height(self.size.height);
+ self.helper.width(self.size.width);
+
+ if (this._helper && !o.animate) this._proportionallyResize();
+ }
+
+ $('body').css('cursor', 'auto');
+
+ this.element.removeClass("ui-resizable-resizing");
+
+ this._propagate("stop", event);
+
+ if (this._helper) this.helper.remove();
+ return false;
+
+ },
+
+ _updateCache: function(data) {
+ var o = this.options;
+ this.offset = this.helper.offset();
+ if (isNumber(data.left)) this.position.left = data.left;
+ if (isNumber(data.top)) this.position.top = data.top;
+ if (isNumber(data.height)) this.size.height = data.height;
+ if (isNumber(data.width)) this.size.width = data.width;
+ },
+
+ _updateRatio: function(data, event) {
+
+ var o = this.options, cpos = this.position, csize = this.size, a = this.axis;
+
+ if (data.height) data.width = (csize.height * this.aspectRatio);
+ else if (data.width) data.height = (csize.width / this.aspectRatio);
+
+ if (a == 'sw') {
+ data.left = cpos.left + (csize.width - data.width);
+ data.top = null;
+ }
+ if (a == 'nw') {
+ data.top = cpos.top + (csize.height - data.height);
+ data.left = cpos.left + (csize.width - data.width);
+ }
+
+ return data;
+ },
+
+ _respectSize: function(data, event) {
+
+ var el = this.helper, o = this.options, pRatio = this._aspectRatio || event.shiftKey, a = this.axis,
+ ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
+ isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height);
+
+ if (isminw) data.width = o.minWidth;
+ if (isminh) data.height = o.minHeight;
+ if (ismaxw) data.width = o.maxWidth;
+ if (ismaxh) data.height = o.maxHeight;
+
+ var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height;
+ var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
+
+ if (isminw && cw) data.left = dw - o.minWidth;
+ if (ismaxw && cw) data.left = dw - o.maxWidth;
+ if (isminh && ch) data.top = dh - o.minHeight;
+ if (ismaxh && ch) data.top = dh - o.maxHeight;
+
+ // fixing jump error on top/left - bug #2330
+ var isNotwh = !data.width && !data.height;
+ if (isNotwh && !data.left && data.top) data.top = null;
+ else if (isNotwh && !data.top && data.left) data.left = null;
+
+ return data;
+ },
+
+ _proportionallyResize: function() {
+
+ var o = this.options;
+ if (!this._proportionallyResizeElements.length) return;
+ var element = this.helper || this.element;
+
+ for (var i=0; i < this._proportionallyResizeElements.length; i++) {
+
+ var prel = this._proportionallyResizeElements[i];
+
+ if (!this.borderDif) {
+ var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')],
+ p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')];
+
+ this.borderDif = $.map(b, function(v, i) {
+ var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0;
+ return border + padding;
+ });
+ }
+
+ if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length)))
+ continue;
+
+ prel.css({
+ height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
+ width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
+ });
+
+ };
+
+ },
+
+ _renderProxy: function() {
+
+ var el = this.element, o = this.options;
+ this.elementOffset = el.offset();
+
+ if(this._helper) {
+
+ this.helper = this.helper || $('<div style="overflow:hidden;"></div>');
+
+ // fix ie6 offset TODO: This seems broken
+ var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0),
+ pxyoffset = ( ie6 ? 2 : -1 );
+
+ this.helper.addClass(this._helper).css({
+ width: this.element.outerWidth() + pxyoffset,
+ height: this.element.outerHeight() + pxyoffset,
+ position: 'absolute',
+ left: this.elementOffset.left - ie6offset +'px',
+ top: this.elementOffset.top - ie6offset +'px',
+ zIndex: ++o.zIndex //TODO: Don't modify option
+ });
+
+ this.helper
+ .appendTo("body")
+ .disableSelection();
+
+ } else {
+ this.helper = this.element;
+ }
+
+ },
+
+ _change: {
+ e: function(event, dx, dy) {
+ return { width: this.originalSize.width + dx };
+ },
+ w: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { left: sp.left + dx, width: cs.width - dx };
+ },
+ n: function(event, dx, dy) {
+ var o = this.options, cs = this.originalSize, sp = this.originalPosition;
+ return { top: sp.top + dy, height: cs.height - dy };
+ },
+ s: function(event, dx, dy) {
+ return { height: this.originalSize.height + dy };
+ },
+ se: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ sw: function(event, dx, dy) {
+ return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ },
+ ne: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
+ },
+ nw: function(event, dx, dy) {
+ return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
+ }
+ },
+
+ _propagate: function(n, event) {
+ $.ui.plugin.call(this, n, [event, this.ui()]);
+ (n != "resize" && this._trigger(n, event, this.ui()));
+ },
+
+ plugins: {},
+
+ ui: function() {
+ return {
+ originalElement: this.originalElement,
+ element: this.element,
+ helper: this.helper,
+ position: this.position,
+ size: this.size,
+ originalSize: this.originalSize,
+ originalPosition: this.originalPosition
+ };
+ }
+
+}));
+
+$.extend($.ui.resizable, {
+ version: "1.7.2",
+ eventPrefix: "resize",
+ defaults: {
+ alsoResize: false,
+ animate: false,
+ animateDuration: "slow",
+ animateEasing: "swing",
+ aspectRatio: false,
+ autoHide: false,
+ cancel: ":input,option",
+ containment: false,
+ delay: 0,
+ distance: 1,
+ ghost: false,
+ grid: false,
+ handles: "e,s,se",
+ helper: false,
+ maxHeight: null,
+ maxWidth: null,
+ minHeight: 10,
+ minWidth: 10,
+ zIndex: 1000
+ }
+});
+
+/*
+ * Resizable Extensions
+ */
+
+$.ui.plugin.add("resizable", "alsoResize", {
+
+ start: function(event, ui) {
+
+ var self = $(this).data("resizable"), o = self.options;
+
+ _store = function(exp) {
+ $(exp).each(function() {
+ $(this).data("resizable-alsoresize", {
+ width: parseInt($(this).width(), 10), height: parseInt($(this).height(), 10),
+ left: parseInt($(this).css('left'), 10), top: parseInt($(this).css('top'), 10)
+ });
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) {
+ if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
+ else { $.each(o.alsoResize, function(exp, c) { _store(exp); }); }
+ }else{
+ _store(o.alsoResize);
+ }
+ },
+
+ resize: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition;
+
+ var delta = {
+ height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0,
+ top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0
+ },
+
+ _alsoResize = function(exp, c) {
+ $(exp).each(function() {
+ var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, css = c && c.length ? c : ['width', 'height', 'top', 'left'];
+
+ $.each(css || ['width', 'height', 'top', 'left'], function(i, prop) {
+ var sum = (start[prop]||0) + (delta[prop]||0);
+ if (sum && sum >= 0)
+ style[prop] = sum || null;
+ });
+
+ //Opera fixing relative position
+ if (/relative/.test(el.css('position')) && $.browser.opera) {
+ self._revertToRelativePosition = true;
+ el.css({ position: 'absolute', top: 'auto', left: 'auto' });
+ }
+
+ el.css(style);
+ });
+ };
+
+ if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) {
+ $.each(o.alsoResize, function(exp, c) { _alsoResize(exp, c); });
+ }else{
+ _alsoResize(o.alsoResize);
+ }
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable");
+
+ //Opera fixing relative position
+ if (self._revertToRelativePosition && $.browser.opera) {
+ self._revertToRelativePosition = false;
+ el.css({ position: 'relative' });
+ }
+
+ $(this).removeData("resizable-alsoresize-start");
+ }
+});
+
+$.ui.plugin.add("resizable", "animate", {
+
+ stop: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options;
+
+ var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName),
+ soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height,
+ soffsetw = ista ? 0 : self.sizeDiff.width;
+
+ var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) },
+ left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null,
+ top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null;
+
+ self.element.animate(
+ $.extend(style, top && left ? { top: top, left: left } : {}), {
+ duration: o.animateDuration,
+ easing: o.animateEasing,
+ step: function() {
+
+ var data = {
+ width: parseInt(self.element.css('width'), 10),
+ height: parseInt(self.element.css('height'), 10),
+ top: parseInt(self.element.css('top'), 10),
+ left: parseInt(self.element.css('left'), 10)
+ };
+
+ if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height });
+
+ // propagating resize, and updating values for each animation step
+ self._updateCache(data);
+ self._propagate("resize", event);
+
+ }
+ }
+ );
+ }
+
+});
+
+$.ui.plugin.add("resizable", "containment", {
+
+ start: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options, el = self.element;
+ var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
+ if (!ce) return;
+
+ self.containerElement = $(ce);
+
+ if (/document/.test(oc) || oc == document) {
+ self.containerOffset = { left: 0, top: 0 };
+ self.containerPosition = { left: 0, top: 0 };
+
+ self.parentData = {
+ element: $(document), left: 0, top: 0,
+ width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
+ };
+ }
+
+ // i'm a node, so compute top, left, right, bottom
+ else {
+ var element = $(ce), p = [];
+ $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
+
+ self.containerOffset = element.offset();
+ self.containerPosition = element.position();
+ self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
+
+ var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width,
+ width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
+
+ self.parentData = {
+ element: ce, left: co.left, top: co.top, width: width, height: height
+ };
+ }
+ },
+
+ resize: function(event, ui) {
+ var self = $(this).data("resizable"), o = self.options,
+ ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position,
+ pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement;
+
+ if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co;
+
+ if (cp.left < (self._helper ? co.left : 0)) {
+ self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left));
+ if (pRatio) self.size.height = self.size.width / o.aspectRatio;
+ self.position.left = o.helper ? co.left : 0;
+ }
+
+ if (cp.top < (self._helper ? co.top : 0)) {
+ self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top);
+ if (pRatio) self.size.width = self.size.height * o.aspectRatio;
+ self.position.top = self._helper ? co.top : 0;
+ }
+
+ self.offset.left = self.parentData.left+self.position.left;
+ self.offset.top = self.parentData.top+self.position.top;
+
+ var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ),
+ hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height );
+
+ var isParent = self.containerElement.get(0) == self.element.parent().get(0),
+ isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position'));
+
+ if(isParent && isOffsetRelative) woset -= self.parentData.left;
+
+ if (woset + self.size.width >= self.parentData.width) {
+ self.size.width = self.parentData.width - woset;
+ if (pRatio) self.size.height = self.size.width / self.aspectRatio;
+ }
+
+ if (hoset + self.size.height >= self.parentData.height) {
+ self.size.height = self.parentData.height - hoset;
+ if (pRatio) self.size.width = self.size.height * self.aspectRatio;
+ }
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options, cp = self.position,
+ co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement;
+
+ var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height;
+
+ if (self._helper && !o.animate && (/relative/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ if (self._helper && !o.animate && (/static/).test(ce.css('position')))
+ $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
+
+ }
+});
+
+$.ui.plugin.add("resizable", "ghost", {
+
+ start: function(event, ui) {
+
+ var self = $(this).data("resizable"), o = self.options, cs = self.size;
+
+ self.ghost = self.originalElement.clone();
+ self.ghost
+ .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
+ .addClass('ui-resizable-ghost')
+ .addClass(typeof o.ghost == 'string' ? o.ghost : '');
+
+ self.ghost.appendTo(self.helper);
+
+ },
+
+ resize: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width });
+ },
+
+ stop: function(event, ui){
+ var self = $(this).data("resizable"), o = self.options;
+ if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0));
+ }
+
+});
+
+$.ui.plugin.add("resizable", "grid", {
+
+ resize: function(event, ui) {
+ 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;
+ o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid;
+ var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1);
+
+ if (/^(se|s|e)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ }
+ else if (/^(ne)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ }
+ else if (/^(sw)$/.test(a)) {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.left = op.left - ox;
+ }
+ else {
+ self.size.width = os.width + ox;
+ self.size.height = os.height + oy;
+ self.position.top = op.top - oy;
+ self.position.left = op.left - ox;
+ }
+ }
+
+});
+
+var num = function(v) {
+ return parseInt(v, 10) || 0;
+};
+
+var isNumber = function(value) {
+ return !isNaN(parseInt(value, 10));
+};
+
+})(jQuery);
14 years, 10 months