JBoss Rich Faces SVN: r19145 - branches/RF-8992/examples/input-demo/src/main/webapp.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-09-09 09:57:49 -0400 (Thu, 09 Sep 2010)
New Revision: 19145
Modified:
branches/RF-8992/examples/input-demo/src/main/webapp/inplaceInput.xhtml
branches/RF-8992/examples/input-demo/src/main/webapp/inplaceSelect.xhtml
Log:
Modified: branches/RF-8992/examples/input-demo/src/main/webapp/inplaceInput.xhtml
===================================================================
--- branches/RF-8992/examples/input-demo/src/main/webapp/inplaceInput.xhtml 2010-09-09 13:56:31 UTC (rev 19144)
+++ branches/RF-8992/examples/input-demo/src/main/webapp/inplaceInput.xhtml 2010-09-09 13:57:49 UTC (rev 19145)
@@ -12,7 +12,7 @@
<h:body>
<h:form id="form">
- <in:inplaceInput showControls="false" value="New York"/>
+ <in:inplaceInput state="edit" showControls="true" value="New York"/>
<h:commandButton value="submit"/>
</h:form>
</h:body>
Modified: branches/RF-8992/examples/input-demo/src/main/webapp/inplaceSelect.xhtml
===================================================================
--- branches/RF-8992/examples/input-demo/src/main/webapp/inplaceSelect.xhtml 2010-09-09 13:56:31 UTC (rev 19144)
+++ branches/RF-8992/examples/input-demo/src/main/webapp/inplaceSelect.xhtml 2010-09-09 13:57:49 UTC (rev 19145)
@@ -13,11 +13,15 @@
<h:body>
<h:form id="form">
- <div id="scroll" style="width: 400px; height:100px; overflow:auto;" >
+ <div id="scroll" style="width: 400px; height:400px; overflow:auto;" >
<fieldset>
<legend>Test App</legend>
Fresh off his victory in the Florida primary, Sen. John McCain is poised to take another big prize. Former
<in:inplaceSelect defaultLabel="Edit Text" value="#{inputBean.value}">
+ <f:selectItem itemLabel="1#OptionLabel" itemValue="1#OptionValue"/>
+ <f:selectItem itemLabel="2#OptionLabel" itemValue="2#OptionValue"/>
+ <f:selectItem itemLabel="3#OptionLabel" itemValue="3#OptionValue"/>
+ <f:selectItem itemLabel="4#OptionLabel" itemValue="4#OptionValue"/>
</in:inplaceSelect>
Mayor Rudy Giuliani plans to drop out and endorse McCain, two GOP sources said. That would give McCain added momentum heading into a debate Wednesday and next week's Super Tuesday contests
</fieldset>
14 years, 3 months
JBoss Rich Faces SVN: r19144 - in branches/RF-8992/ui/input/ui/src/main: resources/META-INF/resources/org.richfaces and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: abelevich
Date: 2010-09-09 09:56:31 -0400 (Thu, 09 Sep 2010)
New Revision: 19144
Modified:
branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java
branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceSelectBaseRenderer.java
branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceInput.js
branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceSelect.js
branches/RF-8992/ui/input/ui/src/main/templates/inplaceSelect.template.xml
Log:
Modified: branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java
===================================================================
--- branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java 2010-09-09 11:17:48 UTC (rev 19143)
+++ branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceInputBaseRenderer.java 2010-09-09 13:56:31 UTC (rev 19144)
@@ -168,7 +168,7 @@
JSFunction function = new JSFunction(scriptName);
String clientId = component.getClientId(facesContext);
Map<String, Object> options = createInplaceComponentOptions(clientId, (InplaceComponent)component);
- addToOptions(component, options);
+ addToOptions(facesContext, component, options);
function.addParameter(clientId);
function.addParameter(options);
writer.write(function.toString());
@@ -199,7 +199,7 @@
return options;
}
- public void addToOptions(UIComponent component, Map<String, Object> parameters) {
+ public void addToOptions(FacesContext facesContext, UIComponent component, Map<String, Object> options) {
//override this method if you need additional options
}
Modified: branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceSelectBaseRenderer.java
===================================================================
--- branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceSelectBaseRenderer.java 2010-09-09 11:17:48 UTC (rev 19143)
+++ branches/RF-8992/ui/input/ui/src/main/java/org/richfaces/renderkit/InplaceSelectBaseRenderer.java 2010-09-09 13:56:31 UTC (rev 19144)
@@ -3,6 +3,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
@@ -25,14 +26,23 @@
*/
@ResourceDependencies({ @ResourceDependency(library = "javax.faces", name = "jsf.js"),
- @ResourceDependency(name = "jquery.js"), @ResourceDependency(name = "richfaces.js"),
+ @ResourceDependency(name = "jquery.js"),
+ @ResourceDependency(name = "jquery.position.js"),
+ @ResourceDependency(name = "richfaces.js"),
@ResourceDependency(name = "richfaces-event.js"),
@ResourceDependency(name = "richfaces-base-component.js"),
- @ResourceDependency(library="org.richfaces", name = "inplaceInput.js"),
- @ResourceDependency(library="org.richfaces", name = "inplaceSelect.js"),
- @ResourceDependency(library="org.richfaces", name = "inplaceSelect.ecss") })
+ @ResourceDependency(name = "richfaces-selection.js"),
+ @ResourceDependency(library = "org.richfaces", name = "inplaceInput.js"),
+ @ResourceDependency(library = "org.richfaces", name = "AutocompleteBase.js"),
+ @ResourceDependency(library = "org.richfaces", name = "Autocomplete.js"),
+ @ResourceDependency(library = "org.richfaces", name = "inplaceSelect.js"),
+ @ResourceDependency(library = "org.richfaces", name = "inplaceSelect.ecss") })
public class InplaceSelectBaseRenderer extends InplaceInputBaseRenderer {
+ public static final String OPTIONS_ITEM_CLASS = "itemClass";
+
+ public static final String OPTIONS_SELECTED_ITEM_CLASS = "selectedItemClass";
+
protected static final class ClientSelectItem implements ScriptString {
private String label;
private String convertedValue;
@@ -77,6 +87,12 @@
return clientSelectItems;
}
+ @Override
+ public void addToOptions(FacesContext facesContext, UIComponent component, Map<String, Object> options) {
+ options.put(OPTIONS_ITEM_CLASS, "insel_option");
+ options.put(OPTIONS_SELECTED_ITEM_CLASS, "insel_select");
+ }
+
public void encodeOptions(FacesContext facesContext, UIComponent component, List<ClientSelectItem> clientSelectItems) throws IOException {
AbstractInplaceSelect inplaceSelect = (AbstractInplaceSelect)component;
if(clientSelectItems != null && !clientSelectItems.isEmpty()) {
Modified: branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceInput.js
===================================================================
--- branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceInput.js 2010-09-09 11:17:48 UTC (rev 19143)
+++ branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceInput.js 2010-09-09 13:56:31 UTC (rev 19144)
@@ -67,12 +67,13 @@
// define super class link
var $super = rf.ui.InplaceInput.$super;
-
+
$.extend(rf.ui.InplaceInput.prototype, ( function () {
var isSaved = false;
var isValueChanged = false;
+
return {
name : "inplaceInput",
Modified: branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceSelect.js
===================================================================
--- branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceSelect.js 2010-09-09 11:17:48 UTC (rev 19143)
+++ branches/RF-8992/ui/input/ui/src/main/resources/META-INF/resources/org.richfaces/inplaceSelect.js 2010-09-09 13:56:31 UTC (rev 19144)
@@ -3,18 +3,32 @@
rf.ui = rf.ui || {};
rf.ui.InplaceSelect = function(id, options) {
- $super.constructor.call(this, id, options);
+ $super.constructor.call(this, id, options)
+ this.proxy = new rf.ui.Autocomplete(id, options.input, defaultOptions);
}
-
+
rf.ui.InplaceInput.extend(rf.ui.InplaceSelect);
-
var $super = rf.ui.InplaceSelect.$super;
- $.extend(rf.ui.InplaceSelect.prototype, function () {
+ var defaultOptions = {
+ selectedItemClass:'insel_select',
+ itemClass:'insel_option',
+ autofill:false,
+ minChars:0,
+ selectFirst:false,
+ ajaxMode:false,
+ lazyClientMode:false,
+ attachToBody:true,
+ filterFunction: function () {return true;}
+ };
+
+ $.extend(rf.ui.InplaceSelect.prototype, ( function () {
+
return{
name : "inplaceSelect"
}
- })
+
+ })());
})(jQuery, window.RichFaces);
Modified: branches/RF-8992/ui/input/ui/src/main/templates/inplaceSelect.template.xml
===================================================================
--- branches/RF-8992/ui/input/ui/src/main/templates/inplaceSelect.template.xml 2010-09-09 11:17:48 UTC (rev 19143)
+++ branches/RF-8992/ui/input/ui/src/main/templates/inplaceSelect.template.xml 2010-09-09 13:56:31 UTC (rev 19144)
@@ -78,7 +78,7 @@
</span>
</c:if>
<br/>
- <span class="insel_list_cord">
+ <span id="#{clientId}List" class="insel_list_cord">
<span class="insel_list_position" style="width: #{component.attributes['listWidth']}">
<span class="insel_shadow">
<span class="insel_shadow_t"></span>
@@ -86,7 +86,7 @@
<span class="insel_shadow_r"></span>
<span class="insel_shadow_b"></span>
<span class="insel_list_decoration">
- <span class="insel_list_scroll" style="height: #{component.attributes['listHeight']}">
+ <span class="insel_list_scroll" id="#{clientId}Items" style="height: #{component.attributes['listHeight']}">
<cdk:call expression="encodeOptions(facesContext, component, clientSelectItems);"/>
</span>
</span>
14 years, 3 months
JBoss Rich Faces SVN: r19143 - in modules/tests/metamer/trunk/ftest-source/src/main: java/org/richfaces/tests/metamer/ftest/a4jStatus and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: lfryc(a)redhat.com
Date: 2010-09-09 07:17:48 -0400 (Thu, 09 Sep 2010)
New Revision: 19143
Added:
modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRHalter.java
modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRState.java
modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/XHRHalter.js
Removed:
modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/SendHalt.java
modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/SendHalt.js
Modified:
modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/AbstracStatusTest.java
modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestInstantAttributes.java
modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestReferencedUsage.java
Log:
SendHalt replaced by more general implementation XHRHalter (able to step all the states of XHR request) - used in a4j:status tests
Deleted: modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/SendHalt.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/SendHalt.java 2010-09-09 11:03:11 UTC (rev 19142)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/SendHalt.java 2010-09-09 11:17:48 UTC (rev 19143)
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *******************************************************************************/
-package org.jboss.cheiron.halt;
-
-import static org.jboss.test.selenium.encapsulated.JavaScript.js;
-
-import org.jboss.test.selenium.encapsulated.JavaScript;
-import org.jboss.test.selenium.framework.AjaxSelenium;
-import org.jboss.test.selenium.framework.AjaxSeleniumProxy;
-
-/**
- * @author <a href="mailto:lfryc@redhat.com">Lukas Fryc</a>
- * @version $Revision$
- */
-public class SendHalt {
-
- private static JavaScript isHaltAvailable = js("selenium.browserbot.getCurrentWindow().SendHalt.isHaltAvailable()");
- private static JavaScript getHalt = js("selenium.browserbot.getCurrentWindow().SendHalt.getHalt()");
- private static JavaScript unhalt = js("selenium.browserbot.getCurrentWindow().SendHalt.unhalt({0})");
- private static JavaScript setEnabled = js("selenium.browserbot.getCurrentWindow().SendHalt.setEnabled({0})");
-
- private static final AbstractPageExtensions sendHaltExtensions = new AbstractPageExtensions() {
- {
- loadFromResource("javascript/cheiron/SendHalt.js");
- }
-
- public JavaScript isExtensionInstalledScript() {
- return js("selenium.browserbot.getCurrentWindow().SendHalt != undefined");
- }
- };
-
- int handle;
-
- private SendHalt(int handle) {
- this.handle = handle;
- }
-
- static AjaxSelenium selenium = AjaxSeleniumProxy.getInstance();
-
- public static void enable() {
- selenium.getPageExtensions().install();
- sendHaltExtensions.install();
- selenium.getEval(setEnabled.parametrize(true));
- }
-
- public static void disable() {
- selenium.getEval(setEnabled.parametrize(false));
- }
-
- public static SendHalt getHalt() {
- selenium.waitForCondition(isHaltAvailable);
- return new SendHalt(Integer.valueOf(selenium.getEval(getHalt)));
- }
-
- public void unhalt() {
- selenium.getEval(unhalt.parametrize(handle));
- }
-
-}
Added: modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRHalter.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRHalter.java (rev 0)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRHalter.java 2010-09-09 11:17:48 UTC (rev 19143)
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *******************************************************************************/
+package org.jboss.cheiron.halt;
+
+import static org.jboss.cheiron.halt.XHRState.*;
+import static org.jboss.test.selenium.encapsulated.JavaScript.js;
+
+import org.apache.commons.lang.Validate;
+import org.jboss.test.selenium.encapsulated.JavaScript;
+import org.jboss.test.selenium.framework.AjaxSelenium;
+import org.jboss.test.selenium.framework.AjaxSeleniumProxy;
+
+/**
+ * @author <a href="mailto:lfryc@redhat.com">Lukas Fryc</a>
+ * @version $Revision$
+ */
+public class XHRHalter {
+
+ private static JavaScript isHandleAvailable = js("selenium.browserbot.getCurrentWindow().XHRHalter.isHandleAvailable()");
+ private static JavaScript isWaitingForSend = js("selenium.browserbot.getCurrentWindow().XHRHalter.isWaitingForSend({0})");
+ private static JavaScript getHandle = js("selenium.browserbot.getCurrentWindow().XHRHalter.getHandle()");
+ private static JavaScript continueTo = js("selenium.browserbot.getCurrentWindow().XHRHalter.continueTo({0}, selenium.browserbot.getCurrentWindow().XHRHalter.STATE_{1})");
+ private static JavaScript setEnabled = js("selenium.browserbot.getCurrentWindow().XHRHalter.setEnabled({0})");
+
+ private static final AbstractPageExtensions halterExtensions = new AbstractPageExtensions() {
+ {
+ loadFromResource("javascript/cheiron/XHRHalter.js");
+ }
+
+ public JavaScript isExtensionInstalledScript() {
+ return js("selenium.browserbot.getCurrentWindow().XHRHalter != undefined");
+ }
+ };
+
+ int handle;
+
+ private XHRHalter(int handle) {
+ this.handle = handle;
+ }
+
+ static AjaxSelenium selenium = AjaxSeleniumProxy.getInstance();
+
+ public static void enable() {
+ selenium.getPageExtensions().install();
+ halterExtensions.install();
+ selenium.getEval(setEnabled.parametrize(true));
+ }
+
+ public static void disable() {
+ selenium.getEval(setEnabled.parametrize(false));
+ }
+
+ public static boolean isHandleAvailable() {
+ return Boolean.valueOf(selenium.getEval(isHandleAvailable));
+ }
+
+ public static void waitForHandleAvailable() {
+ selenium.waitForCondition(isHandleAvailable);
+ }
+
+ public static XHRHalter getHandle() {
+ int handle = Integer.valueOf(selenium.getEval(getHandle));
+ if (handle < 0) {
+ throw new IllegalStateException("Handle is not available");
+ }
+ return new XHRHalter(handle);
+ }
+
+ public static XHRHalter getHandleBlocking() {
+ waitForHandleAvailable();
+ return getHandle();
+ }
+
+ public void continueBefore(XHRState phase) {
+ Validate.notNull(phase);
+ XHRState phaseToContinueAfter = XHRState.values()[phase.ordinal() - 1];
+ continueAfter(phaseToContinueAfter);
+ }
+
+ public void continueAfter(XHRState phase) {
+ Validate.notNull(phase);
+ selenium.getEval(continueTo.parametrize(handle, phase.toString()));
+ }
+
+ public boolean isWaitingForSend() {
+ return Boolean.valueOf(selenium.getEval(isWaitingForSend.parametrize(handle)));
+ }
+
+ public void waitForOpen() {
+ selenium.waitForCondition(isWaitingForSend.parametrize(handle));
+ }
+
+ public void send() {
+ continueAfter(SEND);
+ }
+
+ public void initialize() {
+ continueAfter(UNITIALIZED);
+ }
+
+ public void loading() {
+ continueAfter(LOADING);
+ }
+
+ public void loaded() {
+ continueAfter(LOADED);
+ }
+
+ public void interactive() {
+ continueAfter(INTERACTIVE);
+ }
+
+ public void complete() {
+ continueAfter(COMPLETE);
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getName() + ": handle " + handle;
+ }
+}
Added: modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRState.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRState.java (rev 0)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/jboss/cheiron/halt/XHRState.java 2010-09-09 11:17:48 UTC (rev 19143)
@@ -0,0 +1,5 @@
+package org.jboss.cheiron.halt;
+
+public enum XHRState {
+ SEND, UNITIALIZED, LOADING, LOADED, INTERACTIVE, COMPLETE;
+}
Modified: modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/AbstracStatusTest.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/AbstracStatusTest.java 2010-09-09 11:03:11 UTC (rev 19142)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/AbstracStatusTest.java 2010-09-09 11:17:48 UTC (rev 19143)
@@ -23,11 +23,13 @@
import static org.testng.Assert.assertEquals;
-import org.jboss.cheiron.halt.SendHalt;
+import org.jboss.cheiron.halt.XHRHalter;
import org.jboss.test.selenium.locator.ElementLocator;
import org.jboss.test.selenium.locator.JQueryLocator;
import org.jboss.test.selenium.waiting.retrievers.TextRetriever;
import org.richfaces.tests.metamer.ftest.AbstractMetamerTest;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
/**
* @author <a href="mailto:lfryc@redhat.com">Lukas Fryc</a>
@@ -43,14 +45,30 @@
TextRetriever retrieveStatus = retrieveText.locator(status);
+ XHRHalter haltHandler;
+
+ @BeforeMethod
+ public void cleanXHRHalter() {
+ haltHandler = null;
+ }
+
+ protected XHRHalter getCurrentXHRHalter() {
+ if (haltHandler == null) {
+ haltHandler = XHRHalter.getHandleBlocking();
+ } else {
+ haltHandler.waitForOpen();
+ }
+ return haltHandler;
+ }
+
void testRequestButton(ElementLocator<?> button, String startStatusText, String stopStatusText) {
- SendHalt.enable();
+ XHRHalter.enable();
selenium.click(button);
- SendHalt halt = SendHalt.getHalt();
+ XHRHalter halt = getCurrentXHRHalter();
assertEquals(retrieveStatus.retrieve(), startStatusText);
- halt.unhalt();
+ halt.complete();
waitAjax.waitForChange(startStatusText, retrieveStatus);
assertEquals(retrieveStatus.retrieve(), stopStatusText);
- SendHalt.disable();
+ XHRHalter.disable();
}
}
Modified: modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestInstantAttributes.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestInstantAttributes.java 2010-09-09 11:03:11 UTC (rev 19142)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestInstantAttributes.java 2010-09-09 11:17:48 UTC (rev 19143)
@@ -28,7 +28,7 @@
import java.net.URL;
-import org.jboss.cheiron.halt.SendHalt;
+import org.jboss.cheiron.halt.XHRHalter;
import org.jboss.test.selenium.encapsulated.JavaScript;
import org.jboss.test.selenium.locator.ElementLocator;
import org.richfaces.tests.metamer.ftest.annotations.IssueTracking;
@@ -59,12 +59,12 @@
for (int i = 0; i < 2; i++) {
attributes.setOnStart(alert.parametrize("start" + 1));
- SendHalt.enable();
+ XHRHalter.enable();
selenium.click(button1);
selenium.waitForCondition(js("selenium.isAlertPresent()"));
assertEquals(selenium.getAlert(), "start" + 1);
- SendHalt.getHalt().unhalt();
- SendHalt.disable();
+ getCurrentXHRHalter().complete();
+ XHRHalter.disable();
}
}
Modified: modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestReferencedUsage.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestReferencedUsage.java 2010-09-09 11:03:11 UTC (rev 19142)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jStatus/TestReferencedUsage.java 2010-09-09 11:17:48 UTC (rev 19143)
@@ -26,7 +26,7 @@
import java.net.URL;
-import org.jboss.cheiron.halt.SendHalt;
+import org.jboss.cheiron.halt.XHRHalter;
import org.jboss.test.selenium.locator.JQueryLocator;
import org.jboss.test.selenium.waiting.retrievers.TextRetriever;
import org.testng.annotations.Test;
@@ -50,82 +50,82 @@
@Test
public void testClickBothButtonsInSequence() {
- SendHalt.enable();
+ XHRHalter.enable();
selenium.click(button1);
- SendHalt halt = SendHalt.getHalt();
+ XHRHalter halt = getCurrentXHRHalter();
assertEquals(retrieveStatus1.retrieve(), "START");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- halt.unhalt();
+ halt.complete();
waitAjax.waitForChange("START", retrieveStatus1);
selenium.click(button2);
- halt = SendHalt.getHalt();
+ halt = getCurrentXHRHalter();
assertEquals(retrieveStatus1.retrieve(), "STOP");
assertEquals(retrieveStatus2.retrieve(), "START");
- halt.unhalt();
+ halt.complete();
waitAjax.waitForChange("START", retrieveStatus2);
assertEquals(retrieveStatus1.retrieve(), "STOP");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- SendHalt.disable();
+ XHRHalter.disable();
}
@Test
public void testClickBothButtonsImmediately() {
- SendHalt.enable();
+ XHRHalter.enable();
selenium.click(button1);
selenium.click(button2);
- SendHalt halt = SendHalt.getHalt();
+ XHRHalter halt = getCurrentXHRHalter();
assertEquals(retrieveStatus1.retrieve(), "START");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- halt.unhalt();
- halt = SendHalt.getHalt();
+ halt.complete();
+ halt.waitForOpen();
assertEquals(retrieveStatus1.retrieve(), "STOP");
assertEquals(retrieveStatus2.retrieve(), "START");
- halt.unhalt();
+ halt.complete();
waitAjax.waitForChange("START", retrieveStatus2);
assertEquals(retrieveStatus1.retrieve(), "STOP");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- SendHalt.disable();
+ XHRHalter.disable();
}
/**
* @Test TODO: selenium is causing 3 requests, but manually we triggers 2 requests (use Firebug to reproduce)
*/
public void testClickFirstButtonThenSecondButtonThenAgainFirstButtonImmediately() {
- SendHalt.enable();
+ XHRHalter.enable();
selenium.click(button1);
selenium.click(button2);
selenium.click(button1);
- SendHalt halt = SendHalt.getHalt();
+ XHRHalter halt = XHRHalter.getHandleBlocking();
assertEquals(retrieveStatus1.retrieve(), "START");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- halt.unhalt();
- halt = SendHalt.getHalt();
+ halt.complete();
+ halt.waitForOpen();
assertEquals(retrieveStatus1.retrieve(), "START");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- halt.unhalt();
+ halt.complete();
waitAjax.waitForChange("START", retrieveStatus1);
assertEquals(retrieveStatus1.retrieve(), "STOP");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- SendHalt.disable();
+ XHRHalter.disable();
}
@Test
public void testDoubleClick() {
- SendHalt.enable();
+ XHRHalter.enable();
selenium.click(button1);
- SendHalt halt = SendHalt.getHalt();
+ XHRHalter halt = getCurrentXHRHalter();
assertEquals(retrieveStatus1.retrieve(), "START");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- halt.unhalt();
+ halt.complete();
selenium.click(button1);
- halt = SendHalt.getHalt();
+ halt.waitForOpen();
assertEquals(retrieveStatus1.retrieve(), "START");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- halt.unhalt();
+ halt.complete();
waitAjax.waitForChange("START", retrieveStatus1);
assertEquals(retrieveStatus1.retrieve(), "STOP");
assertEquals(retrieveStatus2.retrieve(), "STOP");
- SendHalt.disable();
+ XHRHalter.disable();
}
}
Deleted: modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/SendHalt.js
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/SendHalt.js 2010-09-09 11:03:11 UTC (rev 19142)
+++ modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/SendHalt.js 2010-09-09 11:17:48 UTC (rev 19143)
@@ -1,90 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright ${year}, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-var SendHalt = function(xhr, content, callback) {
- SendHalt._instances.push(this);
- this.halt = true;
- this.xhr = xhr;
- this.content = content;
- this.callback = callback;
- this.id = SendHalt._instances.length - 1;
-}
-
-SendHalt._instances = new Array();
-SendHalt._haltCounter = 0;
-SendHalt._enabled = false;
-
-SendHalt.setEnabled = function(enabled) {
- SendHalt._enabled = enabled;
-}
-
-SendHalt.isEnabled = function(enabled) {
- return SendHalt._enabled;
-}
-
-SendHalt.getLastId = function() {
- return SendHalt._instances.length - 1;
-}
-
-SendHalt.getHalt = function() {
- if (SendHalt.isHaltAvailable()) {
- SendHalt._haltCounter += 1;
- return SendHalt.getLastId();
- }
- return -1;
-}
-
-SendHalt.XHRWrapperInjection = {
- send : RichFacesSelenium.XHRWrapper.prototype.send
-}
-
-SendHalt._repeatWait = function(id) {
- var halt = SendHalt._instances[id];
- if (halt.halt) {
- setTimeout("SendHalt._repeatWait(" + id + ")", 100);
- } else {
- halt.callback(halt.xhr, halt.content);
- }
-}
-
-SendHalt.prototype.wait = function() {
- SendHalt._repeatWait(this.id);
-}
-
-SendHalt.unhalt = function(id) {
- var halt = SendHalt._instances[id];
- halt.halt = false;
-}
-
-SendHalt.isHaltAvailable = function() {
- return SendHalt.getLastId() == SendHalt._haltCounter;
-}
-
-RichFacesSelenium.XHRWrapper.prototype.send = function(content) {
- if (SendHalt.isEnabled()) {
- var metamerHalt = new SendHalt(this, content, function(xhr, content1) {
- SendHalt.XHRWrapperInjection.send.call(xhr, content1);
- });
- metamerHalt.wait();
- } else {
- SendHalt.XHRWrapperInjection.send.call(this, content);
- }
-};
\ No newline at end of file
Added: modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/XHRHalter.js
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/XHRHalter.js (rev 0)
+++ modules/tests/metamer/trunk/ftest-source/src/main/resources/javascript/cheiron/XHRHalter.js 2010-09-09 11:17:48 UTC (rev 19143)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+var XHRHalter = function(xhr) {
+ XHRHalter._associations[xhr] = this;
+ if (this.id == undefined) {
+ XHRHalter._instances.push(this);
+ this.id = XHRHalter._instances.length - 1;
+ }
+ this.currentState = XHRHalter.STATE_OPEN;
+ this.availableStates = new Array();
+ this.continueToState = XHRHalter.STATE_OPEN;
+ this.xhr = xhr;
+ this.sendParams = {};
+ this.xhrParams = new Array();
+ this.saveXhrParams();
+ this.callback = function(xhr) {
+ XHRHalter.XHRWrapperInjection.onreadystatechangeCallback.call(xhr);
+ };
+};
+
+XHRHalter.STATE_OPEN = -2;
+XHRHalter.STATE_SEND = -1;
+XHRHalter.STATE_UNITIALIZED = 0;
+XHRHalter.STATE_LOADING = 1;
+XHRHalter.STATE_LOADED = 2;
+XHRHalter.STATE_INTERACTIVE = 3;
+XHRHalter.STATE_COMPLETE = 4;
+
+XHRHalter._instances = new Array();
+XHRHalter._associations = {};
+XHRHalter._haltCounter = 0;
+XHRHalter._enabled = true;
+
+XHRHalter.setEnabled = function(enabled) {
+ XHRHalter._enabled = enabled;
+};
+
+XHRHalter.isEnabled = function(enabled) {
+ return XHRHalter._enabled;
+};
+
+XHRHalter.getHandle = function() {
+ if (XHRHalter.isHandleAvailable()) {
+ return XHRHalter._haltCounter++;
+ }
+ return -1;
+};
+
+XHRHalter.XHRWrapperInjection = {
+ onreadystatechangeCallback : RichFacesSelenium.XHRWrapper.prototype.onreadystatechangeCallback,
+ open : RichFacesSelenium.XHRWrapper.prototype.open,
+ send : RichFacesSelenium.XHRWrapper.prototype.send
+};
+
+XHRHalter._repeatWait = function(id) {
+ var halter = XHRHalter._instances[id];
+ halter.tryProcessStates();
+ if (!halter.isXhrCompleted()) {
+ setTimeout("XHRHalter._repeatWait(" + id + ")", 100);
+ }
+};
+
+XHRHalter.prototype.isXhrCompleted = function() {
+ return this.currentState == XHRHalter.STATE_COMPLETE;
+};
+
+XHRHalter.prototype.getLastAvailableState = function() {
+ return this.availableStates.length - 1;
+};
+
+XHRHalter.continueTo = function(id, state) {
+ var halter = XHRHalter._instances[id];
+ if (state < halter.continueToState) {
+ throw new Error("cannot continue to state (" + state + ") before the actual state (" + halter.continueToState + ")");
+ }
+ halter.continueToState = state;
+};
+
+XHRHalter.isWaitingForSend = function(id) {
+ var halter = XHRHalter._instances[id];
+ return halter.currentState == XHRHalter.STATE_OPEN && halter.continueToState == XHRHalter.STATE_OPEN;
+};
+
+XHRHalter.prototype.tryProcessStates = function() {
+ while (this.currentState < this.continueToState && this.currentState < this.getLastAvailableState()) {
+ this.currentState += 1;
+ this.processState(this.currentState);
+ }
+};
+
+XHRHalter.prototype.processState = function(state) {
+ this.loadXhrParams(state);
+ switch (state) {
+ case XHRHalter.STATE_SEND :
+ XHRHalter.XHRWrapperInjection.send.call(this.xhr, this.sendParams['content']);
+ break;
+ default :
+ this.callback(this.xhr);
+ }
+};
+
+XHRHalter.prototype.loadXhrParams = function(state) {
+ state = Math.max(state, XHRHalter.STATE_UNITIALIZED);
+ var holder = this.availableStates[state];
+ this.xhr.readyState = state;
+ this.xhr.responseText = holder.responseText;
+ this.xhr.responseXML = holder.responseXML;
+ this.xhr.status = holder.status;
+ this.xhr.statusText = holder.statusText;
+ this.xhr.onreadystatechange = holder.onreadystatechange;
+};
+
+XHRHalter.prototype.saveXhrParams = function() {
+ this.availableStates[this.xhr.readyState] = {};
+ var holder = this.availableStates[this.xhr.readyState];
+ holder.responseText = this.xhr.responseText;
+ holder.responseXML = this.xhr.responseXML;
+ holder.status = this.xhr.status;
+ holder.statusText = this.xhr.statusText;
+ holder.onreadystatechange = this.xhr.onreadystatechange;
+};
+
+XHRHalter.prototype.wait = function() {
+ XHRHalter._repeatWait(this.id);
+};
+
+XHRHalter.isHandleAvailable = function() {
+ return XHRHalter._instances.length - 1 >= XHRHalter._haltCounter;
+};
+
+RichFacesSelenium.XHRWrapper.prototype.onreadystatechangeCallback = function() {
+ if (XHRHalter.isEnabled()) {
+ var halter = XHRHalter._associations[this];
+ halter.saveXhrParams();
+ halter.loadXhrParams(halter.currentState);
+ } else {
+ XHRHalter.XHRWrapperInjection.onreadystatechangeCallback.call(this);
+ }
+};
+
+RichFacesSelenium.XHRWrapper.prototype.open = function(method, url, asyncFlag, userName, password) {
+ if (XHRHalter.isEnabled()) {
+ var halter = XHRHalter._associations[this];
+ if (halter === undefined) {
+ halter = new XHRHalter(this);
+ } else {
+ XHRHalter.call(halter, this);
+ }
+ halter.wait();
+ }
+ asyncFlag = (asyncFlag !== false);
+ return XHRHalter.XHRWrapperInjection.open.call(this, method, url, asyncFlag, userName, password);
+};
+
+
+RichFacesSelenium.XHRWrapper.prototype.send = function(content) {
+ if (XHRHalter.isEnabled()) {
+ var halter = XHRHalter._associations[this];
+ halter.sendParams['content'] = content;
+ } else {
+ return XHRHalter.XHRWrapperInjection.send.call(this, content);
+ }
+};
14 years, 3 months
JBoss Rich Faces SVN: r19142 - in sandbox/trunk/prototypes: csv and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: pyaschenko
Date: 2010-09-09 07:03:11 -0400 (Thu, 09 Sep 2010)
New Revision: 19142
Added:
sandbox/trunk/prototypes/csv/
sandbox/trunk/prototypes/csv/validator/
sandbox/trunk/prototypes/csv/validator/jquery.js
sandbox/trunk/prototypes/csv/validator/length.js
sandbox/trunk/prototypes/csv/validator/richfaces.js
sandbox/trunk/prototypes/csv/validator/test.html
Log:
https://jira.jboss.org/browse/RF-9329
https://jira.jboss.org/browse/RF-9215
csv prototype
Added: sandbox/trunk/prototypes/csv/validator/jquery.js
===================================================================
--- sandbox/trunk/prototypes/csv/validator/jquery.js (rev 0)
+++ sandbox/trunk/prototypes/csv/validator/jquery.js 2010-09-09 11:03:11 UTC (rev 19142)
@@ -0,0 +1,6240 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // Use the correct document accordingly with window argument (sandbox)
+ document = window.document,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // Has the ready events already been bound?
+ readyBound = false,
+
+ // The functions to execute on DOM ready
+ readyList = [],
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ indexOf = Array.prototype.indexOf;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = "body";
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ if ( elem ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $("TAG")
+ } else if ( !context && /^\w+$/.test( selector ) ) {
+ this.selector = selector;
+ this.context = document;
+ selector = document.getElementsByTagName( selector );
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return jQuery( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.4.2",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady ) {
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ } else if ( readyList ) {
+ // Add the function to the wait list
+ readyList.push( fn );
+ }
+
+ return this;
+ },
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || jQuery(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging object literal values or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+ : jQuery.isArray(copy) ? [] : {};
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 13 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( readyList ) {
+ // Execute all of them
+ var fn, i = 0;
+ while ( (fn = readyList[ i++ ]) ) {
+ fn.call( document, jQuery );
+ }
+
+ // Reset the list of functions
+ readyList = null;
+ }
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.triggerHandler ) {
+ jQuery( document ).triggerHandler( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyBound ) {
+ return;
+ }
+
+ readyBound = true;
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ return jQuery.ready();
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ return toString.call(obj) === "[object Array]";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor
+ && !hasOwnProperty.call(obj, "constructor")
+ && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwnProperty.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+ // Try to use the native JSON parser first
+ return window.JSON && window.JSON.parse ?
+ window.JSON.parse( data ) :
+ (new Function("return " + data))();
+
+ } else {
+ jQuery.error( "Invalid JSON: " + data );
+ }
+ },
+
+ noop: function() {},
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom...
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+
+ if ( jQuery.support.scriptEval ) {
+ script.appendChild( document.createTextNode( data ) );
+ } else {
+ script.text = data;
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction(object);
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+ }
+ }
+
+ return object;
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length, j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ if ( !inv !== !callback( elems[ i ], i ) ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var ret = [], value;
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ proxy: function( fn, proxy, thisObject ) {
+ if ( arguments.length === 2 ) {
+ if ( typeof proxy === "string" ) {
+ thisObject = fn;
+ fn = thisObject[ proxy ];
+ proxy = undefined;
+
+ } else if ( proxy && !jQuery.isFunction( proxy ) ) {
+ thisObject = proxy;
+ proxy = undefined;
+ }
+ }
+
+ if ( !proxy && fn ) {
+ proxy = function() {
+ return fn.apply( thisObject || this, arguments );
+ };
+ }
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ if ( fn ) {
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+ }
+
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+ /(msie) ([\w.]+)/.exec( ua ) ||
+ !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+ jQuery.inArray = function( elem, array ) {
+ return indexOf.call( array, elem );
+ };
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+}
+
+function now() {
+ return (new Date).getTime();
+}
+(function() {
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + now();
+
+ div.style.display = "none";
+ div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType === 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
+
+ parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
+
+ // Will be defined later
+ deleteExpando: true,
+ checkClone: false,
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e) {}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete script.test;
+
+ } catch(e) {
+ jQuery.support.deleteExpando = false;
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function click() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", click);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ div = document.createElement("div");
+ div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function() {
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div ).style.display = 'none';
+
+ div = null;
+ });
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-b...
+ var eventSupported = function( eventName ) {
+ var el = document.createElement("div");
+ eventName = "on" + eventName;
+
+ var isSupported = (eventName in el);
+ if ( !isSupported ) {
+ el.setAttribute(eventName, "return;");
+ isSupported = typeof el[eventName] === "function";
+ }
+ el = null;
+
+ return isSupported;
+ };
+
+ jQuery.support.submitBubbles = eventSupported("submit");
+ jQuery.support.changeBubbles = eventSupported("change");
+
+ // release memory in IE
+ root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ tabindex: "tabIndex",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+ cache: {},
+
+ expando:expando,
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ "object": true,
+ "applet": true
+ },
+
+ data: function( elem, name, data ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+ if ( !id && typeof name === "string" && data === undefined ) {
+ return null;
+ }
+
+ // Compute a unique ID for the element
+ if ( !id ) {
+ id = ++uuid;
+ }
+
+ // Avoid generating a new cache unless none exists and we
+ // want to manipulate it.
+ if ( typeof name === "object" ) {
+ elem[ expando ] = id;
+ thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+
+ } else if ( !cache[ id ] ) {
+ elem[ expando ] = id;
+ cache[ id ] = {};
+ }
+
+ thisCache = cache[ id ];
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined ) {
+ thisCache[ name ] = data;
+ }
+
+ return typeof name === "string" ? thisCache[ name ] : thisCache;
+ },
+
+ removeData: function( elem, name ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( thisCache ) {
+ // Remove the section of cache data
+ delete thisCache[ name ];
+
+ // If we've removed all the data, remove the element's cache
+ if ( jQuery.isEmptyObject(thisCache) ) {
+ jQuery.removeData( elem );
+ }
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ if ( jQuery.support.deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ // Completely remove the data cache
+ delete cache[ id ];
+ }
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ if ( typeof key === "undefined" && this.length ) {
+ return jQuery.data( this[0] );
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ }
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else {
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+ jQuery.data( this, key, value );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ if ( !elem ) {
+ return;
+ }
+
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( !data ) {
+ return q || [];
+ }
+
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+ } else {
+ q.push( data );
+ }
+
+ return q;
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function( i, elem ) {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ }
+});
+var rclass = /[\n\t]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rspecialurl = /href|src|style/,
+ rtype = /(button|input)/i,
+ rfocusable = /(button|input|object|select|textarea)/i,
+ rclickable = /^(a|area)$/i,
+ rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name, fn ) {
+ return this.each(function(){
+ jQuery.attr( this, name, "" );
+ if ( this.nodeType === 1 ) {
+ this.removeAttribute( name );
+ }
+ });
+ },
+
+ addClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.addClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ var classNames = (value || "").split( rspace );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className ) {
+ elem.className = value;
+
+ } else {
+ var className = " " + elem.className + " ", setClass = elem.className;
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+ setClass += " " + classNames[c];
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.removeClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ var classNames = (value || "").split(rspace);
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ var className = (" " + elem.className + " ").replace(rclass, " ");
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[c] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value, isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className, i = 0, self = jQuery(this),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery.data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if ( jQuery.nodeName( elem, "option" ) ) {
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+ }
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(rreturn, "");
+
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction(value);
+
+ return this.each(function(i) {
+ var self = jQuery(this), val = value;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call(this, i, self.val());
+ }
+
+ // Typecast each time if the value is a Function and the appended
+ // value is therefore different each time.
+ if ( typeof val === "number" ) {
+ val += "";
+ }
+
+ if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+ this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+ } else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(val);
+
+ jQuery( "option", this ).each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ this.selectedIndex = -1;
+ }
+
+ } else {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attr: function( elem, name, value, pass ) {
+ // don't set attributes on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery(elem)[name](value);
+ }
+
+ var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ if ( elem.nodeType === 1 ) {
+ // These attributes require special treatment
+ var special = rspecialurl.test( name );
+
+ // Safari mis-reports the default selected property of an option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name === "selected" && !jQuery.support.optSelected ) {
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ }
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+ return elem.getAttributeNode( name ).nodeValue;
+ }
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabi...
+ if ( name === "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+ return attributeNode && attributeNode.specified ?
+ attributeNode.value :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name === "style" ) {
+ if ( set ) {
+ elem.style.cssText = "" + value;
+ }
+
+ return elem.style.cssText;
+ }
+
+ if ( set ) {
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special ?
+ // Some attributes require a special call on IE
+ elem.getAttribute( name, 2 ) :
+ elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+ // Using attr for specific style information is now deprecated. Use style instead.
+ return jQuery.style( elem, name, value );
+ }
+});
+var rnamespaces = /\.(.*)$/,
+ fcleanup = function( nm ) {
+ return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+ return "\\" + ch;
+ });
+ };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+ elem = window;
+ }
+
+ var handleObjIn, handleObj;
+
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure
+ var elemData = jQuery.data( elem );
+
+ // If no elemData is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !elemData ) {
+ return;
+ }
+
+ var events = elemData.events = elemData.events || {},
+ eventHandle = elemData.handle, eventHandle;
+
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function() {
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native events in IE.
+ eventHandle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ var type, i = 0, namespaces;
+
+ while ( (type = types[ i++ ]) ) {
+ handleObj = handleObjIn ?
+ jQuery.extend({}, handleObjIn) :
+ { handler: handler, data: data };
+
+ // Namespaced event handlers
+ if ( type.indexOf(".") > -1 ) {
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+ } else {
+ namespaces = [];
+ handleObj.namespace = "";
+ }
+
+ handleObj.type = type;
+ handleObj.guid = handler.guid;
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = jQuery.event.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers.push( handleObj );
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, pos ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+ elemData = jQuery.data( elem ),
+ events = elemData && elemData.events;
+
+ if ( !elemData || !events ) {
+ return;
+ }
+
+ // types is actually an event object here
+ if ( types && types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Unbind all events for the element
+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+ types = types || "";
+
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types );
+ }
+
+ return;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ while ( (type = types[ i++ ]) ) {
+ origType = type;
+ handleObj = null;
+ all = type.indexOf(".") < 0;
+ namespaces = [];
+
+ if ( !all ) {
+ // Namespaced event handlers
+ namespaces = type.split(".");
+ type = namespaces.shift();
+
+ namespace = new RegExp("(^|\\.)" +
+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
+ }
+
+ eventType = events[ type ];
+
+ if ( !eventType ) {
+ continue;
+ }
+
+ if ( !handler ) {
+ for ( var j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ jQuery.event.remove( elem, origType, handleObj.handler, j );
+ eventType.splice( j--, 1 );
+ }
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+
+ for ( var j = pos || 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( handler.guid === handleObj.guid ) {
+ // remove the given handler for the given type
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ if ( pos == null ) {
+ eventType.splice( j--, 1 );
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+
+ if ( pos != null ) {
+ break;
+ }
+ }
+ }
+
+ // remove generic event handler if no more handlers exist
+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ removeEvent( elem, type, elemData.handle );
+ }
+
+ ret = null;
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ var handle = elemData.handle;
+ if ( handle ) {
+ handle.elem = null;
+ }
+
+ delete elemData.events;
+ delete elemData.handle;
+
+ if ( jQuery.isEmptyObject( elemData ) ) {
+ jQuery.removeData( elem );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem /*, bubbling */ ) {
+ // Event object or event type
+ var type = event.type || event,
+ bubbling = arguments[3];
+
+ if ( !bubbling ) {
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+
+ // Only trigger if we've ever bound an event for it
+ if ( jQuery.event.global[ type ] ) {
+ jQuery.each( jQuery.cache, function() {
+ if ( this.events && this.events[type] ) {
+ jQuery.event.trigger( event, data, this.handle.elem );
+ }
+ });
+ }
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray( data );
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) {
+ handle.apply( elem, data );
+ }
+
+ var parent = elem.parentNode || elem.ownerDocument;
+
+ // Trigger an inline bound script
+ try {
+ if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+ if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+ event.result = false;
+ }
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( !event.isPropagationStopped() && parent ) {
+ jQuery.event.trigger( event, data, parent, true );
+
+ } else if ( !event.isDefaultPrevented() ) {
+ var target = event.target, old,
+ isClick = jQuery.nodeName(target, "a") && type === "click",
+ special = jQuery.event.special[ type ] || {};
+
+ if ( (!special._default || special._default.call( elem, event ) === false) &&
+ !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+
+ try {
+ if ( target[ type ] ) {
+ // Make sure that we don't accidentally re-trigger the onFOO events
+ old = target[ "on" + type ];
+
+ if ( old ) {
+ target[ "on" + type ] = null;
+ }
+
+ jQuery.event.triggered = true;
+ target[ type ]();
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( old ) {
+ target[ "on" + type ] = old;
+ }
+
+ jQuery.event.triggered = false;
+ }
+ }
+ },
+
+ handle: function( event ) {
+ var all, handlers, namespaces, namespace, events;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ all = event.type.indexOf(".") < 0 && !event.exclusive;
+
+ if ( !all ) {
+ namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+ namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ var events = jQuery.data(this, "events"), handlers = events[ event.type ];
+
+ if ( events && handlers ) {
+ // Clone the handlers to prevent manipulation
+ handlers = handlers.slice(0);
+
+ for ( var j = 0, l = handlers.length; j < l; j++ ) {
+ var handleObj = handlers[ j ];
+
+ // Filter the functions by class
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handleObj.handler;
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ var ret = handleObj.handler.apply( this, arguments );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ if ( event[ expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
+ event.which = event.charCode || event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( handleObj ) {
+ jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) );
+ },
+
+ remove: function( handleObj ) {
+ var remove = true,
+ type = handleObj.origType.replace(rnamespaces, "");
+
+ jQuery.each( jQuery.data(this, "events").live || [], function() {
+ if ( type === this.origType.replace(rnamespaces, "") ) {
+ remove = false;
+ return false;
+ }
+ });
+
+ if ( remove ) {
+ jQuery.event.remove( this, handleObj.origType, liveHandler );
+ }
+ }
+
+ },
+
+ beforeunload: {
+ setup: function( data, namespaces, eventHandle ) {
+ // We only want to do this special case on windows
+ if ( this.setInterval ) {
+ this.onbeforeunload = eventHandle;
+ }
+
+ return false;
+ },
+ teardown: function( namespaces, eventHandle ) {
+ if ( this.onbeforeunload === eventHandle ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+var removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ elem.removeEventListener( type, handle, false );
+ } :
+ function( elem, type, handle ) {
+ elem.detachEvent( "on" + type, handle );
+ };
+
+jQuery.Event = function( src ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[ expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-bind...
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+ }
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+
+ // Firefox sometimes assigns relatedTarget a XUL element
+ // which we cannot access the parentNode property of
+ try {
+ // Traverse up the tree
+ while ( parent && parent !== this ) {
+ parent = parent.parentNode;
+ }
+
+ if ( parent !== this ) {
+ // set the correct event type
+ event.type = event.data;
+
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+
+ // assuming we've left the element since we most likely mousedover a xul element
+ } catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function( data, namespaces ) {
+ if ( this.nodeName.toLowerCase() !== "form" ) {
+ jQuery.event.add(this, "click.specialSubmit", function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialSubmit" );
+ }
+ };
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+ var formElems = /textarea|input|select/i,
+
+ changeFilters,
+
+ getVal = function( elem ) {
+ var type = elem.type, val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( elem.nodeName.toLowerCase() === "select" ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+ },
+
+ testChange = function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery.data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery.data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ return jQuery.event.trigger( e, arguments[1], elem );
+ }
+ };
+
+ jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information/focus[in] is not needed anymore
+ beforeactivate: function( e ) {
+ var elem = e.target;
+ jQuery.data( elem, "_change_data", getVal(elem) );
+ }
+ },
+
+ setup: function( data, namespaces ) {
+ if ( this.type === "file" ) {
+ return false;
+ }
+
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+ }
+
+ return formElems.test( this.nodeName );
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialChange" );
+
+ return formElems.test( this.nodeName );
+ }
+ };
+
+ changeFilters = jQuery.event.special.change.filters;
+}
+
+function trigger( type, elem, args ) {
+ args[0].type = type;
+ return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ this.addEventListener( orig, handler, true );
+ },
+ teardown: function() {
+ this.removeEventListener( orig, handler, true );
+ }
+ };
+
+ function handler( e ) {
+ e = jQuery.event.fix( e );
+ e.type = fix;
+ return jQuery.event.handle.call( this, e );
+ }
+ });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+ jQuery.fn[ name ] = function( type, data, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ name ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ }) : fn;
+
+ if ( type === "unload" && name !== "one" ) {
+ this.one( type, data, fn );
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.add( this[i], type, handler, data );
+ }
+ }
+
+ return this;
+ };
+});
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.remove( this[i], type, fn );
+ }
+ }
+
+ return this;
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.live( types, data, fn, selector );
+ },
+
+ undelegate: function( selector, types, fn ) {
+ if ( arguments.length === 0 ) {
+ return this.unbind( "live" );
+
+ } else {
+ return this.die( types, null, fn, selector );
+ }
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ var event = jQuery.Event( type );
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while ( i < args.length ) {
+ jQuery.proxy( fn, args[ i++ ] );
+ }
+
+ return this.click( jQuery.proxy( fn, function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+var liveMap = {
+ focus: "focusin",
+ blur: "focusout",
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+ jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+ var type, i = 0, match, namespaces, preType,
+ selector = origSelector || this.selector,
+ context = origSelector ? this : jQuery( this.context );
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ types = (types || "").split(" ");
+
+ while ( (type = types[ i++ ]) != null ) {
+ match = rnamespaces.exec( type );
+ namespaces = "";
+
+ if ( match ) {
+ namespaces = match[0];
+ type = type.replace( rnamespaces, "" );
+ }
+
+ if ( type === "hover" ) {
+ types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+ continue;
+ }
+
+ preType = type;
+
+ if ( type === "focus" || type === "blur" ) {
+ types.push( liveMap[ type ] + namespaces );
+ type = type + namespaces;
+
+ } else {
+ type = (liveMap[ type ] || type) + namespaces;
+ }
+
+ if ( name === "live" ) {
+ // bind live handler
+ context.each(function(){
+ jQuery.event.add( this, liveConvert( type, selector ),
+ { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+ });
+
+ } else {
+ // unbind live handler
+ context.unbind( liveConvert( type, selector ), fn );
+ }
+ }
+
+ return this;
+ }
+});
+
+function liveHandler( event ) {
+ var stop, elems = [], selectors = [], args = arguments,
+ related, match, handleObj, elem, j, i, l, data,
+ events = jQuery.data( this, "events" );
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861)
+ if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+ return;
+ }
+
+ event.liveFired = this;
+
+ var live = events.live.slice(0);
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+ selectors.push( handleObj.selector );
+
+ } else {
+ live.splice( j--, 1 );
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( match[i].selector === handleObj.selector ) {
+ elem = match[i].elem;
+ related = null;
+
+ // Those two events require additional checking
+ if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+ related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, handleObj: handleObj });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+ event.currentTarget = match.elem;
+ event.data = match.handleObj.data;
+ event.handleObj = match.handleObj;
+
+ if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
+ stop = false;
+ break;
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( fn ) {
+ return fn ? this.bind( name, fn ) : this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+ window.attachEvent("onunload", function() {
+ for ( var id in jQuery.cache ) {
+ if ( jQuery.cache[ id ].handle ) {
+ // Try/Catch is to handle iframes being unloaded, see #4280
+ try {
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+ } catch(e) {}
+ }
+ }
+ });
+}
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ var origContext = context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+ }
+
+ if ( context ) {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context && context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function(results){
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var filter = Expr.filter[ type ], found, item, left = match[1];
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.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\))?/
+ },
+ leftMatch: {},
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = part.toLowerCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ return match[1].toLowerCase();
+ },
+ CHILD: function(match){
+ if ( match[1] === "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 === i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ Sizzle.error( "Syntax error, unrecognized expression: " + name );
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ if ( type === "first" ) {
+ return true;
+ }
+ node = elem;
+ case 'last':
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first === 0 ) {
+ return diff === 0;
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
+ return "\\" + (num - 0 + 1);
+ }));
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ if ( !a.sourceIndex || !b.sourceIndex ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.sourceIndex ? -1 : 1;
+ }
+
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ if ( !a.ownerDocument || !b.ownerDocument ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.ownerDocument ? -1 : 1;
+ }
+
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.setStart(a, 0);
+ aRange.setEnd(a, 0);
+ bRange.setStart(b, 0);
+ bRange.setEnd(b, 0);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+function getText( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+ root = form = null; // release memory in IE
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ div = null; // release memory in IE
+ })();
+}
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return !!(a.compareDocumentPosition(b) & 16);
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = getText;
+jQuery.isXMLDoc = isXML;
+jQuery.contains = contains;
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ slice = Array.prototype.slice;
+
+// Implement the identical functionality for filter and not
+var winnow = function( elements, qualifier, keep ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+};
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var ret = this.pushStack( "", "find", selector ), length = 0;
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( var n = length; n < ret.length; n++ ) {
+ for ( var r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.filter( selector, this ).length > 0;
+ },
+
+ closest: function( selectors, context ) {
+ if ( jQuery.isArray( selectors ) ) {
+ var ret = [], cur = this[0], match, matches = {}, selector;
+
+ if ( cur && selectors.length ) {
+ for ( var i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[selector] ) {
+ matches[selector] = jQuery.expr.match.POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[selector];
+
+ if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+ ret.push({ selector: selector, elem: cur });
+ delete matches[selector];
+ }
+ }
+ cur = cur.parentNode;
+ }
+ }
+
+ return ret;
+ }
+
+ var pos = jQuery.expr.match.POS.test( selectors ) ?
+ jQuery( selectors, context || this.context ) : null;
+
+ return this.map(function( i, cur ) {
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
+ return cur;
+ }
+ cur = cur.parentNode;
+ }
+ return null;
+ });
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ if ( !elem || typeof elem === "string" ) {
+ return jQuery.inArray( this[0],
+ // If it receives a string, the selector is used
+ // If it receives nothing, the siblings are used
+ elem ? jQuery( elem ) : this.parent().children() );
+ }
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context || this.context ) :
+ jQuery.makeArray( selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, slice.call(arguments).join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [], cur = elem[dir];
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
+ rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnocache = /<script|<object|<embed|<option|<style/i,
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
+ fcloseTag = function( all, front, tag ) {
+ return rselfClosing.test( tag ) ?
+ all :
+ front + "></" + tag + ">";
+ },
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.text( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ), contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ jQuery.cleanData( [ elem ] );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function() {
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML, ownerDocument = this.ownerDocument;
+ if ( !html ) {
+ var div = ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(rinlinejQuery, "")
+ // Handle the case in IE 8 where action=/test/> self-closes a tag
+ .replace(/=([^="'>\s]+\/)>/g, '="$1">')
+ .replace(rleadingWhitespace, "")], ownerDocument)[0];
+ } else {
+ return this.cloneNode(true);
+ }
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ cloneCopyEvent( this, ret );
+ cloneCopyEvent( this.find("*"), ret.find("*") );
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !rnocache.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, fcloseTag);
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery(this), old = self.html();
+ self.empty().append(function(){
+ return value.call( this, i, old );
+ });
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ if ( typeof value !== "string" ) {
+ value = jQuery(value).detach();
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling, parent = this.parentNode;
+
+ jQuery(this).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, value = args[0], scripts = [], fragment, parent;
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ parent = value && value.parentNode;
+
+ // If we're in a fragment, just use that instead of building a new one
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+ results = { fragment: parent };
+
+ } else {
+ results = buildFragment( args, this, scripts );
+ }
+
+ fragment = results.fragment;
+
+ if ( fragment.childNodes.length === 1 ) {
+ first = fragment = fragment.firstChild;
+ } else {
+ first = fragment.firstChild;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ i > 0 || results.cacheable || this.length > 1 ?
+ fragment.cloneNode(true) :
+ fragment
+ );
+ }
+ }
+
+ if ( scripts.length ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+});
+
+function cloneCopyEvent(orig, ret) {
+ var i = 0;
+
+ ret.each(function() {
+ if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+ return;
+ }
+
+ var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+ }
+ });
+}
+
+function buildFragment( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults,
+ doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+ // Only cache "small" (1/2 KB) strings that are associated with the main document
+ // Cloning options loses the selected state, so don't cache them
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+ !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+ cacheable = true;
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults ) {
+ if ( cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+ }
+
+ if ( !fragment ) {
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+}
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [], insert = jQuery( selector ),
+ parent = this.length === 1 && this[0].parentNode;
+
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+ insert[ original ]( this[0] );
+ return this;
+
+ } else {
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, insert.selector );
+ }
+ };
+});
+
+jQuery.extend({
+ clean: function( elems, context, fragment, scripts ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [];
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ continue;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+
+ } else if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, fcloseTag);
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = div.childNodes;
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+ }
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ var data, id, cache = jQuery.cache,
+ special = jQuery.event.special,
+ deleteExpando = jQuery.support.deleteExpando;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ id = elem[ jQuery.expando ];
+
+ if ( id ) {
+ data = cache[ id ];
+
+ if ( data.events ) {
+ for ( var type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ } else {
+ removeEvent( elem, type, data.handle );
+ }
+ }
+ }
+
+ if ( deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ delete cache[ id ];
+ }
+ }
+ }
+});
+// exclude the following css properties to add px
+var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ ralpha = /alpha\([^)]*\)/,
+ ropacity = /opacity=([^)]*)/,
+ rfloat = /float/i,
+ rdashAlpha = /-([a-z])/ig,
+ rupper = /([A-Z])/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display:"block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+
+ // cache check for defaultView.getComputedStyle
+ getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+ // normalize float css property
+ styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn.css = function( name, value ) {
+ return access( this, name, value, true, function( elem, name, value ) {
+ if ( value === undefined ) {
+ return jQuery.curCSS( elem, name );
+ }
+
+ if ( typeof value === "number" && !rexclude.test(name) ) {
+ value += "px";
+ }
+
+ jQuery.style( elem, name, value );
+ });
+};
+
+jQuery.extend({
+ style: function( elem, name, value ) {
+ // don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // ignore negative width and height values #1599
+ if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
+ value = undefined;
+ }
+
+ var style = elem.style || elem, set = value !== undefined;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
+ var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
+ style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
+ }
+
+ return style.filter && style.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
+ "";
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ name = name.replace(rdashAlpha, fcamelCase);
+
+ if ( set ) {
+ style[ name ] = value;
+ }
+
+ return style[ name ];
+ },
+
+ css: function( elem, name, force, extra ) {
+ if ( name === "width" || name === "height" ) {
+ var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
+
+ function getWH() {
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" ) {
+ return;
+ }
+
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ }
+
+ if ( extra === "margin" ) {
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+ } else {
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ }
+ });
+ }
+
+ if ( elem.offsetWidth !== 0 ) {
+ getWH();
+ } else {
+ jQuery.swap( elem, props, getWH );
+ }
+
+ return Math.max(0, Math.round(val));
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret, style = elem.style, filter;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
+ ret = ropacity.test(elem.currentStyle.filter || "") ?
+ (parseFloat(RegExp.$1) / 100) + "" :
+ "";
+
+ return ret === "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ if ( !force && style && style[ name ] ) {
+ ret = style[ name ];
+
+ } else if ( getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( rfloat.test( name ) ) {
+ name = "float";
+ }
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ var defaultView = elem.ownerDocument.defaultView;
+
+ if ( !defaultView ) {
+ return null;
+ }
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle ) {
+ ret = computedStyle.getPropertyValue( name );
+ }
+
+ // We should always get a number back from opacity
+ if ( name === "opacity" && ret === "" ) {
+ ret = "1";
+ }
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(rdashAlpha, fcamelCase);
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth, height = elem.offsetHeight,
+ skip = elem.nodeName.toLowerCase() === "tr";
+
+ return width === 0 && height === 0 && !skip ?
+ true :
+ width > 0 && height > 0 && !skip ?
+ false :
+ jQuery.curCSS(elem, "display") === "none";
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+var jsc = now(),
+ rscript = /<script(.|\s)*?\/script>/gi,
+ rselectTextarea = /select|textarea/i,
+ rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
+ jsre = /=\?(&|$)/,
+ rquery = /\?/,
+ rts = /(\?|&)_=.*?(&|$)/,
+ rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+ r20 = /%20/g,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load;
+
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" ) {
+ return _load.call( this, url );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function( res, status ) {
+ // If successful, inject the HTML into all the matched elements
+ if ( status === "success" || status === "notmodified" ) {
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div />")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [res.responseText, status, res] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function() {
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function() {
+ return this.name && !this.disabled &&
+ (this.checked || rselectTextarea.test(this.nodeName) ||
+ rinput.test(this.type));
+ })
+ .map(function( i, elem ) {
+ var val = jQuery(this).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function( val, i ) {
+ return { name: elem.name, value: val };
+ }) :
+ { name: elem.name, value: val };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+ jQuery.fn[o] = function( f ) {
+ return this.bind(o, f);
+ };
+});
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ traditional: false,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7 (can't request local files),
+ // so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
+ function() {
+ return new window.XMLHttpRequest();
+ } :
+ function() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch(e) {}
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajax: function( origSettings ) {
+ var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
+
+ var jsonp, status, data,
+ callbackContext = origSettings && origSettings.context || s,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType === "jsonp" ) {
+ if ( type === "GET" ) {
+ if ( !jsre.test( s.url ) ) {
+ s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ }
+ } else if ( !s.data || !jsre.test(s.data) ) {
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ }
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+ jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data ) {
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ }
+
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = window[ jsonp ] || function( tmp ) {
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+
+ try {
+ delete window[ jsonp ];
+ } catch(e) {}
+
+ if ( head ) {
+ head.removeChild( script );
+ }
+ };
+ }
+
+ if ( s.dataType === "script" && s.cache === null ) {
+ s.cache = false;
+ }
+
+ if ( s.cache === false && type === "GET" ) {
+ var ts = now();
+
+ // try replacing _= if it is there
+ var ret = s.url.replace(rts, "$1_=" + ts + "$2");
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type === "GET" ) {
+ s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // Matches an absolute URL, and saves the domain
+ var parts = rurl.exec( s.url ),
+ remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType === "script" && type === "GET" && remote ) {
+ var head = document.getElementsByTagName("head")[0] || document.documentElement;
+ var script = document.createElement("script");
+ script.src = s.url;
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function() {
+ if ( !done && (!this.readyState ||
+ this.readyState === "loaded" || this.readyState === "complete") ) {
+ done = true;
+ success();
+ complete();
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+ }
+ };
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ if ( !xhr ) {
+ return;
+ }
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ } else {
+ xhr.open(type, s.url, s.async);
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data || origSettings && origSettings.contentType ) {
+ xhr.setRequestHeader("Content-Type", s.contentType);
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[s.url] ) {
+ xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+ }
+
+ if ( jQuery.etag[s.url] ) {
+ xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+ }
+ }
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ // Only send the header if it's not a remote XHR
+ if ( !remote ) {
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e) {}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global ) {
+ trigger("ajaxSend", [xhr, s]);
+ }
+
+ // Wait for a response to come back
+ var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+ // The request was aborted
+ if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+ // Opera doesn't call onreadystatechange before this point
+ // so we simulate the call
+ if ( !requestDone ) {
+ complete();
+ }
+
+ requestDone = true;
+ if ( xhr ) {
+ xhr.onreadystatechange = jQuery.noop;
+ }
+
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+ requestDone = true;
+ xhr.onreadystatechange = jQuery.noop;
+
+ status = isTimeout === "timeout" ?
+ "timeout" :
+ !jQuery.httpSuccess( xhr ) ?
+ "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+ "notmodified" :
+ "success";
+
+ var errMsg;
+
+ if ( status === "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(err) {
+ status = "parsererror";
+ errMsg = err;
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status === "success" || status === "notmodified" ) {
+ // JSONP handles its own success callback
+ if ( !jsonp ) {
+ success();
+ }
+ } else {
+ jQuery.handleError(s, xhr, status, errMsg);
+ }
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout === "timeout" ) {
+ xhr.abort();
+ }
+
+ // Stop memory leaks
+ if ( s.async ) {
+ xhr = null;
+ }
+ }
+ };
+
+ // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
+ // Opera doesn't fire onreadystatechange at all on abort
+ try {
+ var oldAbort = xhr.abort;
+ xhr.abort = function() {
+ if ( xhr ) {
+ oldAbort.call( xhr );
+ }
+
+ onreadystatechange( "abort" );
+ };
+ } catch(e) { }
+
+ // Timeout checker
+ if ( s.async && s.timeout > 0 ) {
+ setTimeout(function() {
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone ) {
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ // Fire the complete handlers
+ complete();
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async ) {
+ onreadystatechange();
+ }
+
+ function success() {
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success ) {
+ s.success.call( callbackContext, data, status, xhr );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ trigger( "ajaxSuccess", [xhr, s] );
+ }
+ }
+
+ function complete() {
+ // Process result
+ if ( s.complete ) {
+ s.complete.call( callbackContext, xhr, status);
+ }
+
+ // The request was completed
+ if ( s.global ) {
+ trigger( "ajaxComplete", [xhr, s] );
+ }
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+
+ function trigger(type, args) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) {
+ s.error.call( s.context || s, xhr, status, e );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
+ }
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol === "file:" ||
+ // Opera returns 0 when status is 304
+ ( xhr.status >= 200 && xhr.status < 300 ) ||
+ xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
+ } catch(e) {}
+
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ var lastModified = xhr.getResponseHeader("Last-Modified"),
+ etag = xhr.getResponseHeader("Etag");
+
+ if ( lastModified ) {
+ jQuery.lastModified[url] = lastModified;
+ }
+
+ if ( etag ) {
+ jQuery.etag[url] = etag;
+ }
+
+ // Opera returns 0 when status is 304
+ return xhr.status === 304 || xhr.status === 0;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type") || "",
+ xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.nodeName === "parsererror" ) {
+ jQuery.error( "parsererror" );
+ }
+
+ // Allow a pre-filtering function to sanitize the response
+ // s is checked to keep backwards compatibility
+ if ( s && s.dataFilter ) {
+ data = s.dataFilter( data, type );
+ }
+
+ // The filter can actually parse the response
+ if ( typeof data === "string" ) {
+ // Get the JavaScript object, if JSON is used.
+ if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+ data = jQuery.parseJSON( data );
+
+ // If the type is "script", eval it in global context
+ } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+ jQuery.globalEval( data );
+ }
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [];
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray(a) || a.jquery ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[prefix] );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join("&").replace(r20, "+");
+
+ function buildParams( prefix, obj ) {
+ if ( jQuery.isArray(obj) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || /\[\]$/.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ jQuery.each( obj, function( k, v ) {
+ buildParams( prefix + "[" + k + "]", v );
+ });
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+ }
+
+ function add( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction(value) ? value() : value;
+ s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+ }
+ }
+});
+var elemdisplay = {},
+ rfxtypes = /toggle|show|hide/,
+ rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+jQuery.fn.extend({
+ show: function( speed, callback ) {
+ if ( speed || speed === 0) {
+ return this.animate( genFx("show", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var nodeName = this[i].nodeName, display;
+
+ if ( elemdisplay[ nodeName ] ) {
+ display = elemdisplay[ nodeName ];
+
+ } else {
+ var elem = jQuery("<" + nodeName + " />").appendTo("body");
+
+ display = elem.css("display");
+
+ if ( display === "none" ) {
+ display = "block";
+ }
+
+ elem.remove();
+
+ elemdisplay[ nodeName ] = display;
+ }
+
+ jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" ) {
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete );
+ }
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ var name = p.replace(rdashAlpha, fcamelCase);
+
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ p = name;
+ }
+
+ if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+ return opt.complete.call(this);
+ }
+
+ if ( ( p === "height" || p === "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+
+ if ( jQuery.isArray( prop[p] ) ) {
+ // Create (if needed) and add to specialEasing
+ (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+ prop[p] = prop[p][0];
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function( name, val ) {
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+ } else {
+ var parts = rfxnum.exec(val),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat( parts[2] ),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ var timers = jQuery.timers;
+
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, callback ) {
+ return this.animate( props, speed, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function() {
+ if ( opt.queue !== false ) {
+ jQuery(this).dequeue();
+ }
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig ) {
+ options.orig = {};
+ }
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
+ this.elem.style.display = "block";
+ }
+ },
+
+ // Get the current size
+ cur: function( force ) {
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(jQuery.fx.tick, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var t = now(), done = true;
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ for ( var i in this.options.curAnim ) {
+ if ( this.options.curAnim[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ var old = jQuery.data(this.elem, "olddisplay");
+ this.elem.style.display = old ? old : this.options.display;
+
+ if ( jQuery.css(this.elem, "display") === "none" ) {
+ this.elem.style.display = "block";
+ }
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide ) {
+ jQuery(this.elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show ) {
+ for ( var p in this.options.curAnim ) {
+ jQuery.style(this.elem, p, this.options.orig[p]);
+ }
+ }
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+ var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+ this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style(fx.elem, "opacity", fx.now);
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
+ html = "<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>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ body = container = innerDiv = checkDiv = table = td = null;
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop, left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
+ left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ // set position first, in-case top/left are set even on static elem
+ if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
+ elem.style.position = "relative";
+ }
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
+ curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ var props = {
+ top: (options.top - curOffset.top) + curTop,
+ left: (options.left - curOffset.left) + curLeft
+ };
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
+ offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
+ parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function(val) {
+ var elem = this[0], win;
+
+ if ( !elem ) {
+ return null;
+ }
+
+ if ( val !== undefined ) {
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery(win).scrollLeft(),
+ i ? val : jQuery(win).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ } else {
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+ };
+});
+
+function getWindow( elem ) {
+ return ("scrollTo" in elem && elem.document) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function() {
+ return this[0] ?
+ jQuery.css( this[0], type, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function( margin ) {
+ return this[0] ?
+ jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+ elem.document.body[ "client" + name ] :
+
+ // Get document width or height
+ (elem.nodeType === 9) ? // is it a document
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ jQuery.css( elem, type ) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+})(window);
\ No newline at end of file
Added: sandbox/trunk/prototypes/csv/validator/length.js
===================================================================
--- sandbox/trunk/prototypes/csv/validator/length.js (rev 0)
+++ sandbox/trunk/prototypes/csv/validator/length.js 2010-09-09 11:03:11 UTC (rev 19142)
@@ -0,0 +1,80 @@
+(function($, rf) {
+
+ rf.csv = rf.csv || {};
+
+ var _messages = {};
+ var _validators = {};
+ var _converters = {};
+
+ var RE_MESSAGE_PATTERN = /\{(\d+)\}/g;
+
+ $.extend(rf.csv, {
+ // Messages API
+ addMessage: function (messagesObject) {
+ for (var id in messagesObject) {
+ _messages[id] = messagesObject[id].replace(RE_MESSAGE_PATTERN,"\n$1\n").split("\n");
+ }
+ },
+ getMessage: function(id, values) {
+ var msgObject = _messages[id];
+ var result="";
+ if (msgObject) {
+ var value;
+ for (var i=1; i<msgObject.length; i+=2) {
+ value = values[msgObject[i]];
+ msgObject[i] = typeof value == "undefined" ? "" : value;
+ }
+ result = msgObject.join('');
+ }
+ return result;
+ },
+ // Validators API
+ addValidator: function (validatorFunctions) {
+ $.extend(_validators, validatorFunctions);
+ },
+ validate: function (event, id, validatorList, messageComponentList, options) {
+ var value;
+ var element = rf.getDomElement(id);
+ if (element.value) {
+ value = element.value;
+ } else {
+ var component = rf.$(element);
+ value = component && typeof component["getValue"] == "function" ? component.getValue() : "";
+ }
+ var result;
+ var messageComponentsUpdated = false;
+ var validatorFunction;
+ for (var validator in validatorList) {
+ validatorFunction = _validators[validator];
+ if (validatorFunction) {
+ result = validatorFunction(value, validatorList[validator]);
+ }
+ if (result && result.length>0) {
+ messageComponentsUpdated = true;
+ //updateMessageComponents(messageElementIds, result);
+ alert(result);
+ break;
+ }
+ }
+ !messageComponentsUpdated && alert("");//updateMessageComponents(messageElementIds, "");
+ },
+ addFormValidators: function (formId, callValidatorFunctions) {
+
+ }
+ });
+})(jQuery, window.RichFaces || (window.RichFaces={}));
+
+
+RichFaces.csv.addValidator({"length":
+(function(rf) {
+ return function (value, params) {
+ var result = "";
+ if (value.length<params.min) {
+ result = rf.csv.getMessage('LengthValidator.MINIMUM', [params.min,value]);
+ } else if (value.length>params.max){
+ result = rf.csv.getMessage('LengthValidator.MAXIMUM', [params.max,value]);
+ }
+ return result;
+ }
+})(window.RichFaces || (window.RichFaces={}))
+});
\ No newline at end of file
Added: sandbox/trunk/prototypes/csv/validator/richfaces.js
===================================================================
--- sandbox/trunk/prototypes/csv/validator/richfaces.js (rev 0)
+++ sandbox/trunk/prototypes/csv/validator/richfaces.js 2010-09-09 11:03:11 UTC (rev 19142)
@@ -0,0 +1,749 @@
+
+if (!window.RichFaces) {
+ /**
+ * Global object container for RichFaces API.
+ * All classes should be defined here.
+ * @class
+ * @name RichFaces
+ * @static
+ *
+ * */
+ window.RichFaces = {};
+}
+
+(function(jQuery, richfaces) {
+
+ // get DOM element by id or DOM element or jQuery object
+ richfaces.getDomElement = function (source) {
+ var type = typeof source;
+ var element;
+ if (type == "string") {
+ // id
+ element = document.getElementById(source);
+ } else if (type == "object") {
+ if (source.nodeType) {
+ // DOM element
+ element = source;
+ } else
+ if (source instanceof jQuery) {
+ // jQuery object
+ element = source.get(0);
+ }
+ }
+ return element;
+ }
+
+ // get RichFaces component object by component id or DOM element or jQuery object
+ richfaces.$ = function (source) {
+ var element = richfaces.getDomElement(source);
+
+ if (element) {
+ return (element["richfaces"] || {})["component"];
+ }
+ }
+
+ // find component and call his method
+ richfaces.invokeMethod = function(source, method) {
+ var c = richfaces.$(source);
+ if (c) {
+ var f = c[method];
+ if (typeof f == "function") {
+ return f.apply(c, Array.prototype.slice.call(arguments, 2));
+ }
+ }
+ }
+
+ //dom cleaner
+ richfaces.cleanDom = function(source) {
+ var e = (typeof source == "string") ? document.getElementById(source) : jQuery('body').get(0);
+ if (e) {
+ var elements = e.getElementsByTagName("*");
+ if (elements.length) {
+ jQuery.cleanData(elements);
+ jQuery.cleanData([e]);
+ jQuery.each(elements, function(index) {
+ richfaces.invokeMethod(this, "destroy");
+ });
+ richfaces.invokeMethod(e, "destroy");
+ }
+ }
+ }
+
+ //form.js
+ richfaces.submitForm = function(form, parameters, target) {
+ if (typeof form === "string") { form = jQuery(form) };
+ var initialTarget = form.attr("target");
+ var parameterInputs = new Array();
+ try {
+ form.attr("target", target);
+
+ if (parameters) {
+ for (var parameterName in parameters) {
+ var parameterValue = parameters[parameterName];
+
+ var input = jQuery("input[name='" + parameterName + "']", form);
+ if (input.length == 0) {
+ var newInput = jQuery("<input />").attr({type: 'hidden', name: parameterName, value: parameterValue});
+ if (parameterName === 'javax.faces.portletbridge.STATE_ID' /* fix for fileUpload in portlets */) {
+ input = newInput.prependTo(form);
+ } else {
+ input = newInput.appendTo(form);
+ }
+ } else {
+ input.val(parameterValue);
+ }
+
+ input.each(function() {parameterInputs.push(this)});
+ }
+ }
+
+ //TODO: inline onsubmit handler is not triggered - http://dev.jquery.com/ticket/4930
+ form.trigger("submit");
+ } finally {
+ form.attr("target", initialTarget);
+ jQuery(parameterInputs).remove();
+ }
+ };
+ //
+
+ //utils.js
+ jQuery.fn.toXML = function () {
+ var out = '';
+
+ if (this.length > 0) {
+ if (typeof XMLSerializer == 'function' ||
+ typeof XMLSerializer == 'object') {
+
+ var xs = new XMLSerializer();
+ this.each(function() { out += xs.serializeToString(this); });
+ } else if (this[0].xml !== undefined) {
+ this.each(function() { out += this.xml; });
+ } else {
+ this.each( function() { out += this; } );
+ }
+ }
+
+ return out;
+ };
+
+ //there is the same pattern in server-side code:
+ //org.ajax4jsf.javascript.ScriptUtils.escapeCSSMetachars(String)
+ var CSS_METACHARS_PATTERN = /([#;&,.+*~':"!^$\[\]()=>|\/])/g;
+
+ /**
+ * Escapes CSS meta-characters in string according to
+ * <a href="http://api.jquery.com/category/selectors/">jQuery selectors</a> document.
+ *
+ * @param s - string to escape meta-characters in
+ * @return string with meta-characters escaped
+ */
+ richfaces.escapeCSSMetachars = function(s) {
+ //TODO nick - cache results
+
+ return s.replace(CSS_METACHARS_PATTERN, "\\$1");
+ };
+
+ var logImpl;
+
+ richfaces.setLog = function(newLogImpl) {
+ logImpl = newLogImpl;
+ };
+
+ richfaces.log = {
+ debug: function(text) {
+ if (logImpl) {
+ logImpl.debug(text);
+ }
+ },
+
+ info: function(text) {
+ if (logImpl) {
+ logImpl.info(text);
+ }
+ },
+
+ warn: function(text) {
+ if (logImpl) {
+ logImpl.warn(text);
+ }
+ },
+
+ error: function(text) {
+ if (logImpl) {
+ logImpl.error(text);
+ }
+ },
+
+ setLevel: function(level) {
+ if (logImpl) {
+ logImpl.setLevel(level);
+ }
+ },
+
+ getLevel: function() {
+ if (logImpl) {
+ return logImpl.getLevel();
+ }
+ return 'info';
+ },
+
+ clear: function() {
+ if (logImpl) {
+ logImpl.clear();
+ }
+ }
+ };
+
+ /**
+ * Evaluates chained properties for the "base" object.
+ * For example, window.document.location is equivalent to
+ * "propertyNamesString" = "document.location" and "base" = window
+ * Evaluation is safe, so it stops on the first null or undefined object
+ *
+ * @param propertyNamesArray - array of strings that contains names of the properties to evaluate
+ * @param base - base object to evaluate properties on
+ * @return returns result of evaluation or empty string
+ */
+ richfaces.getValue = function(propertyNamesArray, base) {
+ var result = base;
+ var c = 0;
+ do {
+ result = result[propertyNamesArray[c++]];
+ } while (result && c != propertyNamesArray.length);
+
+ return result;
+ };
+
+ var VARIABLE_NAME_PATTERN_STRING = "[_A-Z,a-z]\\w*";
+ var VARIABLES_CHAIN = new RegExp("^\\s*"+VARIABLE_NAME_PATTERN_STRING+"(?:\\s*\\.\\s*"+VARIABLE_NAME_PATTERN_STRING+")*\\s*$");
+ var DOT_SEPARATOR = /\s*\.\s*/;
+
+ richfaces.evalMacro = function(macro, base) {
+ var value = "";
+ // variable evaluation
+ if (VARIABLES_CHAIN.test(macro)) {
+ // object's variable evaluation
+ var propertyNamesArray = jQuery.trim(macro).split(DOT_SEPARATOR);
+ value = richfaces.getValue(propertyNamesArray, base);
+ if (!value) {
+ value = richfaces.getValue(propertyNamesArray, window);
+ }
+ } else {
+ //js string evaluation
+ try {
+ if (base.eval) {
+ value = base.eval(macro);
+ } else with (base) {
+ value = eval(macro) ;
+ }
+ } catch (e) {
+ richfaces.log.warn("Exception: " + e.message + "\n[" + macro + "]");
+ }
+ }
+
+ if (typeof value == 'function') {
+ value = value(base);
+ }
+ //TODO 0 and false are also treated as null values
+ return value || "";
+ };
+
+ var ALPHA_NUMERIC_MULTI_CHAR_REGEXP = /^\w+$/;
+
+ richfaces.interpolate = function (placeholders, context) {
+ var contextVarsArray = new Array();
+ for (var contextVar in context) {
+ if (ALPHA_NUMERIC_MULTI_CHAR_REGEXP.test(contextVar)) {
+ //guarantees that no escaping for the below RegExp is necessary
+ contextVarsArray.push(contextVar);
+ }
+ }
+
+ var regexp = new RegExp("\\{(" + contextVarsArray.join("|") + ")\\}", "g");
+ return placeholders.replace(regexp, function(str, contextVar) {return context[contextVar];});
+ };
+
+ richfaces.clonePosition = function(element, baseElement, positioning, offset) {
+
+ };
+ //
+
+ var pollTracker = {};
+ richfaces.startPoll = function(options) {
+ var pollId = options.pollId;
+ var interval = options.pollinterval;
+ var ontimer = options.ontimer;
+ richfaces.stopPoll(pollId);
+
+ richfaces.setZeroRequestDelay(options);
+
+ pollTracker[pollId] = window.setTimeout(function(){
+ var pollElement = document.getElementById(pollId);
+ try {
+ ontimer.call(pollElement || window);
+ richfaces.startPoll(options);
+ } catch (e) {
+ // TODO: handle exception
+ }
+ },interval);
+ };
+
+ richfaces.stopPoll = function(id) {
+ if(pollTracker[id]){
+ window.clearTimeout(pollTracker[id]);
+ delete pollTracker[id];
+ }
+ };
+
+ var pushTracker = {};
+
+ richfaces.startPush = function(options) {
+ var clientId = options.clientId;
+ var pushResourceUrl = options.pushResourceUrl;
+ var pushId = options.pushId;
+ var interval = options.interval;
+ var ondataavailable = options.ondataavailable;
+ richfaces.setZeroRequestDelay(options);
+
+ richfaces.stopPush(pushId);
+
+ pushTracker[pushId] = setTimeout(function() { // TODO: define this function in richfaces object to avoid definition every time when call startPush
+ var ajaxOptions = {
+ type: "HEAD",
+ //TODO - encodeURIComponent; URL sessionId handling check
+ //TODO - add pushUri supports
+ url: pushResourceUrl + "?id=" + pushId,
+ dataType: "text",
+ complete: function(xhr) {
+ var isPushActive = !!pushTracker[pushId];
+
+ //TODO may someone wish to stop push from dataavailable handler?
+ delete pushTracker[pushId];
+
+ if (xhr.status == 200 && xhr.getResponseHeader("Ajax-Push-Status") == "READY") {
+ var pushElement = document.getElementById(clientId);
+ try {
+ ondataavailable.call(pushElement || window);
+ } catch (e) {
+ // TODO: handle exception
+ }
+ }
+
+ if (isPushActive) {
+ richfaces.startPush(options);
+ }
+ }
+ };
+
+ if (options.timeout) {
+ ajaxOptions.timeout = options.timeout;
+ }
+
+ jQuery.ajax(ajaxOptions);
+ }, interval);
+ };
+
+ richfaces.stopPush = function(id) {
+ if (pushTracker[id]){
+ window.clearTimeout(pushTracker[id]);
+ delete pushTracker[id];
+ }
+ };
+
+ var jsfEventsAdapterEventNames = {
+ event: {
+ 'begin': ['begin'],
+ 'complete': ['beforedomupdate'],
+ 'success': ['success', 'complete']
+ },
+ error: ['error', 'complete']
+ };
+
+ var getExtensionResponseElement = function(responseXML) {
+ return jQuery("partial-response > extension#org\\.richfaces\\.extension", responseXML);
+ };
+
+ var JSON_STRING_START = /^\s*(\[|\{)/;
+
+ var getJSONData = function(extensionElement, elementName) {
+ var dataString = jQuery.trim(extensionElement.children(elementName).text());
+ extensionElement.end();
+ try {
+ if (dataString) {
+ if (JSON_STRING_START.test(dataString)) {
+ return jQuery.parseJSON(dataString);
+ } else {
+ var parsedData = jQuery.parseJSON("{\"root\": " + dataString + "}");
+ return parsedData.root;
+ }
+ }
+ } catch (e) {
+ richfaces.log.warn("Error evaluating JSON data from element <" + elementName + ">: " + e.message);
+ }
+ return null;
+ };
+
+ richfaces.createJSFEventsAdapter = function(handlers) {
+ //hash of handlers
+ //supported are:
+ // - begin
+ // - beforedomupdate
+ // - success
+ // - error
+ // - complete
+ handlers = handlers || {};
+
+ return function(eventData) {
+ var source = eventData.source;
+ //that's request status, not status control data
+ var status = eventData.status;
+ var type = eventData.type;
+
+ var typeHandlers = jsfEventsAdapterEventNames[type];
+ var handlerNames = (typeHandlers || {})[status] || typeHandlers;
+
+ if (handlerNames) {
+ for (var i = 0; i < handlerNames.length; i++) {
+ var eventType = handlerNames[i];
+ var handler = handlers[eventType];
+ if (handler) {
+ var event = {};
+ jQuery.extend(event, eventData);
+ event.type = eventType;
+ if (type != 'error') {
+ delete event.status;
+
+ if (event.responseXML) {
+ var xml = getExtensionResponseElement(event.responseXML);
+ var data = getJSONData(xml, "data");
+ var componentData = getJSONData(xml, "componentData");
+
+ event.data = data;
+ event.componentData = componentData || {};
+ }
+ }
+
+ handler.call(source, event);
+ }
+ }
+ }
+ };
+ };
+
+ var setGlobalStatusNameVariable = function(statusName) {
+ //TODO: parallel requests
+ if (statusName) {
+ richfaces['statusName'] = statusName;
+ } else {
+ delete richfaces['statusName'];
+ }
+ }
+
+ richfaces.setZeroRequestDelay = function(options) {
+ if (typeof options.requestDelay == "undefined") {
+ options.requestDelay = 0;
+ }
+ };
+
+ var getGlobalStatusNameVariable = function() {
+ return richfaces.statusName;
+ }
+
+ var chain = function() {
+ var functions = arguments;
+ if (functions.length == 1) {
+ return functions[0];
+ } else {
+ return function() {
+ var callResult;
+ for (var i = 0; i < functions.length; i++) {
+ var f = functions[i];
+ callResult = f.apply(this, arguments);
+ }
+
+ return callResult;
+ };
+ }
+ };
+
+ /**
+ * curry (g, a) (b) -> g(a, b)
+ */
+ var curry = function(g, a) {
+ var _g = g;
+ var _a = a;
+
+ return function(b) {
+ _g(_a, b);
+ };
+ };
+
+ var createEventHandler = function(handlerCode) {
+ if (handlerCode) {
+ return new Function("event", handlerCode);
+ }
+
+ return null;
+ };
+
+ //TODO take events just from .java code using EL-expression
+ var AJAX_EVENTS = (function() {
+ var serverEventHandler = function(clientHandler, event) {
+ var xml = getExtensionResponseElement(event.responseXML);
+
+ var serverHandler = createEventHandler(xml.children(event.type).text());
+ xml.end();
+
+ if (clientHandler) {
+ clientHandler.call(window, event);
+ }
+
+ if (serverHandler) {
+ serverHandler.call(window, event);
+ }
+ };
+
+ return {
+ 'begin': null,
+ 'complete': serverEventHandler,
+ 'beforedomupdate': serverEventHandler
+ }
+ }());
+
+ richfaces.ajax = function(source, event, options) {
+ var sourceId = (typeof source == 'object' && source.id) ? source.id : source;
+
+ options = options || {};
+
+ parameters = options.parameters || {}; // TODO: change "parameters" to "richfaces.ajax.params"
+ parameters.execute = "@component";
+ parameters.render = "@component";
+
+ if (!parameters["org.richfaces.ajax.component"]) {
+ parameters["org.richfaces.ajax.component"] = sourceId;
+ }
+
+ var eventHandlers;
+
+ for (var eventName in AJAX_EVENTS) {
+ var handlerCode = options[eventName];
+ var handler = typeof handlerCode == "function" ? handlerCode : createEventHandler(handlerCode);
+
+ var serverHandler = AJAX_EVENTS[eventName];
+ if (serverHandler) {
+ handler = curry(serverHandler, handler);
+ }
+
+ if (handler) {
+ eventHandlers = eventHandlers || {};
+ eventHandlers[eventName] = handler;
+ }
+ }
+
+ if (options.status) {
+ var namedStatusEventHandler = function() { setGlobalStatusNameVariable(options.status); };
+
+ //TODO add support for options.submit
+ eventHandlers = eventHandlers || {};
+ if (eventHandlers.begin) {
+ eventHandlers.begin = chain(namedStatusEventHandler, eventHandlers.begin);
+ } else {
+ eventHandlers.begin = namedStatusEventHandler;
+ }
+ }
+
+ if (options.incId) {
+ parameters[sourceId] = sourceId;
+ }
+
+ if (eventHandlers) {
+ var eventsAdapter = richfaces.createJSFEventsAdapter(eventHandlers);
+ parameters['onevent'] = eventsAdapter;
+ parameters['onerror'] = eventsAdapter;
+ }
+
+ if (richfaces.queue) {
+ parameters.queueId = options.queueId;
+ }
+
+ jsf.ajax.request(source, event, parameters);
+ };
+
+ var RICHFACES_AJAX_STATUS = "richfaces:ajaxStatus";
+
+ var getStatusDataAttributeName = function(statusName) {
+ return statusName ? (RICHFACES_AJAX_STATUS + "@" + statusName) : RICHFACES_AJAX_STATUS;
+ };
+
+ var statusAjaxEventHandler = function(data, methodName) {
+ if (methodName) {
+ //global status name
+ var statusName = getGlobalStatusNameVariable();
+ var source = data.source;
+
+ var statusApplied = false;
+ var statusDataAttribute = getStatusDataAttributeName(statusName);
+
+ var statusContainers;
+ if (statusName) {
+ statusContainers = [jQuery(document)];
+ } else {
+ statusContainers = [jQuery(source).parents('form'), jQuery(document)];
+ }
+
+ for (var containerIdx = 0; containerIdx < statusContainers.length && !statusApplied;
+ containerIdx++) {
+
+ var statusContainer = statusContainers[containerIdx];
+ var statuses = statusContainer.data(statusDataAttribute);
+ if (statuses) {
+ for (var statusId in statuses) {
+ var status = statuses[statusId];
+ var result = status[methodName].apply(status, arguments);
+ if (result) {
+ statusApplied = true;
+ } else {
+ delete statuses[statusId];
+ }
+ }
+
+ if (!statusApplied) {
+ statusContainer.removeData(statusDataAttribute);
+ }
+ }
+ }
+ }
+ };
+
+ var initializeStatuses = function() {
+ var thisFunction = arguments.callee;
+ if (!thisFunction.initialized) {
+ thisFunction.initialized = true;
+
+ var jsfEventsListener = richfaces.createJSFEventsAdapter({
+ begin: function(event) { statusAjaxEventHandler(event, 'start'); },
+ error: function(event) { statusAjaxEventHandler(event, 'error'); },
+ success: function(event) { statusAjaxEventHandler(event, 'success'); },
+ complete: function() { setGlobalStatusNameVariable(null); }
+ });
+
+ jsf.ajax.addOnEvent(jsfEventsListener);
+ //TODO blocks default alert error handler
+ jsf.ajax.addOnError(jsfEventsListener);
+ }
+ };
+
+ richfaces.status = function(statusId, options) {
+ this.statusId = statusId;
+ this.options = options || {};
+ this.register();
+ };
+
+ jQuery.extend(richfaces.status.prototype, (function() {
+ //TODO - support for parallel requests
+
+ var getElement = function() {
+ var elt = document.getElementById(this.statusId);
+ return elt ? jQuery(elt) : null;
+ };
+
+ var showHide = function(selector) {
+ var element = getElement.call(this);
+ if (element) {
+ var statusElts = element.children();
+ statusElts.each(function() {
+ var t = jQuery(this);
+ t.css('display', t.is(selector) ? '': 'none');
+ });
+
+ return true;
+ }
+
+ return false;
+ };
+
+ return {
+ register: function() {
+ initializeStatuses();
+
+ var statusName = this.options.statusName;
+ var dataStatusAttribute = getStatusDataAttributeName(statusName);
+
+ var container;
+ if (statusName) {
+ container = jQuery(document);
+ } else {
+ container = getElement.call(this).parents('form');
+ if (container.length == 0) {
+ container = jQuery(document);
+ };
+ }
+
+ var statuses = container.data(dataStatusAttribute);
+ if (!statuses) {
+ statuses = {};
+ container.data(dataStatusAttribute, statuses);
+ }
+
+ statuses[this.statusId] = this;
+ },
+
+ start: function() {
+ if (this.options.onstart) {
+ this.options.onstart.apply(this, arguments);
+ }
+
+ return showHide.call(this, '.rich-status-start');
+ },
+
+ stop: function() {
+ if (this.options.onstop) {
+ this.options.onstop.apply(this, arguments);
+ }
+ },
+
+ success: function() {
+ if (this.options.onsuccess) {
+ this.options.onsuccess.apply(this, arguments);
+ }
+ this.stop();
+
+ return showHide.call(this, '.rich-status-stop');
+ },
+
+ error: function() {
+ if (this.options.onerror) {
+ this.options.onerror.apply(this, arguments);
+ }
+ this.stop();
+
+ return showHide.call(this, ':not(.rich-status-error) + .rich-status-stop, .rich-status-error');
+ }
+ };
+ }()));
+
+ var ajaxOnComplete = function (data) {
+ var type = data.type;
+ var responseXML = data.responseXML;
+
+ if (data.type == 'event' && data.status == 'complete' && responseXML) {
+ var partialResponse = jQuery(responseXML).children("partial-response");
+ if (partialResponse && partialResponse.length) {
+ var elements = partialResponse.children('changes').children('update, delete');
+ jQuery.each(elements, function () {
+ richfaces.cleanDom(jQuery(this).attr('id'));
+ });
+ }
+ }
+ };
+ // move this code to somewhere
+ if (typeof jsf != 'undefined') {
+ jsf.ajax.addOnEvent(ajaxOnComplete);
+ }
+ if (window.addEventListener) {
+ window.addEventListener("unload", richfaces.cleanDom, false);
+ } else {
+ window.attachEvent("onunload", richfaces.cleanDom);
+ }
+}(jQuery, RichFaces));
+
Added: sandbox/trunk/prototypes/csv/validator/test.html
===================================================================
--- sandbox/trunk/prototypes/csv/validator/test.html (rev 0)
+++ sandbox/trunk/prototypes/csv/validator/test.html 2010-09-09 11:03:11 UTC (rev 19142)
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
+
+<html>
+<head>
+ <title>Untitled</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Test Page</title>
+ <script type="text/javascript" src="jquery.js"></script>
+ <script type="text/javascript" src="richfaces.js"></script>
+ <script type="text/javascript" src="length.js"></script>
+
+</head>
+
+<body style="margin : 30px">
+<form id="myForm">
+<input id="myInput" type="text" value="aaa"/>
+<input type="button" onclick="v();" value="validate length"/>
+</form>
+<script>
+RichFaces.csv.addMessage({'LengthValidator.MINIMUM':'Hello, length of the "{1}" is smaller then {0} chars', 'LengthValidator.MAXIMUM':'Hello, length of the "{1}" is bigger then {0} chars'});
+var v = function () {
+ RichFaces.csv.validate(null, 'myInput', {'length':{min:1, max:5}}, null, null);
+};
+</script>
+</body>
+<html>
\ No newline at end of file
14 years, 3 months
JBoss Rich Faces SVN: r19141 - in modules/tests/metamer/trunk: application/src/main/webapp/resources/metamer and 1 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: lfryc(a)redhat.com
Date: 2010-09-09 06:36:33 -0400 (Thu, 09 Sep 2010)
New Revision: 19141
Added:
modules/tests/metamer/trunk/application/src/main/webapp/resources/metamer/clientTime.xhtml
Modified:
modules/tests/metamer/trunk/application/src/main/webapp/components/a4jPush/simple.xhtml
modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jPush/TestInterval.java
Log:
metamer:clientTime composite component + refactored push test accordingly
Modified: modules/tests/metamer/trunk/application/src/main/webapp/components/a4jPush/simple.xhtml
===================================================================
--- modules/tests/metamer/trunk/application/src/main/webapp/components/a4jPush/simple.xhtml 2010-09-09 10:33:24 UTC (rev 19140)
+++ modules/tests/metamer/trunk/application/src/main/webapp/components/a4jPush/simple.xhtml 2010-09-09 10:36:33 UTC (rev 19141)
@@ -34,7 +34,6 @@
</f:viewParam>
</f:metadata>
<h:outputStylesheet library="css" name="a4jPush.css"/>
- <h:outputScript library="script" name="date-format.js" />
</ui:define>
<ui:define name="outOfTemplateBefore">
@@ -48,16 +47,7 @@
<f:convertDateTime pattern="dd.MM.yyyy HH:mm:ss.SSS" />
</h:outputText>
***
- <h:outputText value="Client: " />
- <h:outputText id="clientDate" value="" title="" />
- <script type="text/javascript">
- //<![CDATA[
- var now = new Date();
- jQuery("div.content span[id$=clientDate]")
- .text(now.format("dd.mm.yyyy HH:MM:ss.l", false))
- .attr("title", now.getTime());
- //]]>
- </script>
+ <metamer:clientTime id="clientDate" label="Client: " />
***
<h:outputText value="Counter: " />
<h:outputText id="outputCounter" value="#{a4jPushBean.counter}"/>
Added: modules/tests/metamer/trunk/application/src/main/webapp/resources/metamer/clientTime.xhtml
===================================================================
--- modules/tests/metamer/trunk/application/src/main/webapp/resources/metamer/clientTime.xhtml (rev 0)
+++ modules/tests/metamer/trunk/application/src/main/webapp/resources/metamer/clientTime.xhtml 2010-09-09 10:36:33 UTC (rev 19141)
@@ -0,0 +1,28 @@
+<!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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:composite="http://java.sun.com/jsf/composite" xmlns:a4j="http://richfaces.org/a4j">
+
+ <h:body>
+ <composite:interface>
+ <composite:attribute name="label" type="java.lang.String" required="true" />
+ <composite:attribute name="name" type="java.lang.String" default="metamerOutputTime" />
+ </composite:interface>
+
+ <composite:implementation>
+ <h:outputLabel value="#{cc.attrs.label}" for="#{cc.attrs.name}" />
+ <h:outputText styleClass="metamerOutputTime" id="#{cc.attrs.name}" value="" title="" />
+ <h:outputScript library="script" name="date-format.js" />
+ <script type="text/javascript">
+ //<![CDATA[
+ function #{cc.attrs.name}Refresh() {
+ var now = new Date();
+ jQuery("span.metamerOutputTime[id$=#{cc.attrs.name}]")
+ .text(now.format("dd.mm.yyyy HH:MM:ss.l", false))
+ .attr("title", now.getTime());
+ }
+ #{cc.attrs.name}Refresh();
+ //]]>
+ </script>
+ </composite:implementation>
+ </h:body>
+</html>
Modified: modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jPush/TestInterval.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jPush/TestInterval.java 2010-09-09 10:33:24 UTC (rev 19140)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/a4jPush/TestInterval.java 2010-09-09 10:36:33 UTC (rev 19141)
@@ -43,7 +43,7 @@
* @version $Revision$
*/
public class TestInterval extends AbstractPushTest {
-
+
private static final int DEFAULT_COUNTER_STEP = 2;
private static final int ITERATION_COUNT = 3;
private static final int MULTIPLE_PUSH_COUNT = 5;
@@ -51,7 +51,7 @@
@Inject
int interval;
- AttributeLocator<?> clientTime = pjq("span[id$=clientDate]").getAttribute(Attribute.TITLE);
+ AttributeLocator<?> clientTime = pjq("span[id$=metamerOutputTime]").getAttribute(Attribute.TITLE);
long startTime;
int counter;
14 years, 3 months
JBoss Rich Faces SVN: r19140 - modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest.
by richfaces-svn-commits@lists.jboss.org
Author: lfryc(a)redhat.com
Date: 2010-09-09 06:33:24 -0400 (Thu, 09 Sep 2010)
New Revision: 19140
Modified:
modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/AbstractComponentAttributes.java
Log:
checkbox attributes fixed - needs to fire CHANGE event to apply
Modified: modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/AbstractComponentAttributes.java
===================================================================
--- modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/AbstractComponentAttributes.java 2010-09-09 10:07:04 UTC (rev 19139)
+++ modules/tests/metamer/trunk/ftest-source/src/main/java/org/richfaces/tests/metamer/ftest/AbstractComponentAttributes.java 2010-09-09 10:33:24 UTC (rev 19140)
@@ -21,6 +21,7 @@
*******************************************************************************/
package org.richfaces.tests.metamer.ftest;
+import org.jboss.test.selenium.dom.Event;
import org.jboss.test.selenium.framework.AjaxSelenium;
import org.jboss.test.selenium.framework.AjaxSeleniumProxy;
import org.jboss.test.selenium.locator.AttributeLocator;
@@ -71,6 +72,7 @@
}
protected void applyCheckbox(ElementLocator<?> locator, boolean checked) {
- guardHttp(selenium).check(locator, checked);
+ selenium.check(locator, checked);
+ guardHttp(selenium).fireEvent(locator, Event.CHANGE);
}
}
14 years, 3 months
JBoss Rich Faces SVN: r19139 - modules/tests/metamer/trunk/application.
by richfaces-svn-commits@lists.jboss.org
Author: lfryc(a)redhat.com
Date: 2010-09-09 06:07:04 -0400 (Thu, 09 Sep 2010)
New Revision: 19139
Modified:
modules/tests/metamer/trunk/application/pom.xml
Log:
checkstyle moved to own profile to allow build in Maven3 (resp. Eclipse)
Modified: modules/tests/metamer/trunk/application/pom.xml
===================================================================
--- modules/tests/metamer/trunk/application/pom.xml 2010-09-09 09:17:57 UTC (rev 19138)
+++ modules/tests/metamer/trunk/application/pom.xml 2010-09-09 10:07:04 UTC (rev 19139)
@@ -109,9 +109,6 @@
<plugins>
<plugin>
- <artifactId>maven-checkstyle-plugin</artifactId>
- </plugin>
- <plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
@@ -226,6 +223,21 @@
<profiles>
<profile>
+ <id>checkstyle</id>
+ <activation>
+ <property>
+ <name>!eclipse</name>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
<id>mojarra</id>
<activation>
<property>
14 years, 3 months
JBoss Rich Faces SVN: r19138 - in sandbox/trunk: archetypes and 21 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: ilya_shaikovsky
Date: 2010-09-09 05:17:57 -0400 (Thu, 09 Sep 2010)
New Revision: 19138
Added:
sandbox/trunk/archetypes/
sandbox/trunk/archetypes/rf-gae-sample/
sandbox/trunk/archetypes/rf-gae-sample/assembler.xml
sandbox/trunk/archetypes/rf-gae-sample/pom.xml
sandbox/trunk/archetypes/rf-gae-sample/readme.txt
sandbox/trunk/archetypes/rf-gae-sample/src/
sandbox/trunk/archetypes/rf-gae-sample/src/main/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/META-INF/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/META-INF/maven/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/META-INF/maven/archetype-metadata.xml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/pom.xml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/readme.txt
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/sun/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/sun/faces/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/sun/faces/config/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/sun/faces/config/WebConfiguration.java
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java/RichBean.java
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/resources/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/resources/logging.properties
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/appengine-web.xml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/web.xml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/faces-config.xml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/jboss-scanning.xml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.jsp
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.xhtml
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/templates/
sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/templates/template.xhtml
Log:
https://jira.jboss.org/browse/RF-9335
Added: sandbox/trunk/archetypes/rf-gae-sample/assembler.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/assembler.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/assembler.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,22 @@
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+ <formats>
+ <format>dir</format>
+ </formats>
+
+ <files>
+ <file>
+ <source>pom.xml</source>
+ </file>
+ <file>
+ <source>readme.txt</source>
+ </file>
+ </files>
+
+ <fileSets>
+ <fileSet>
+ <directory>src</directory>
+ </fileSet>
+ </fileSets>
+</assembly>
\ No newline at end of file
Added: sandbox/trunk/archetypes/rf-gae-sample/pom.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/pom.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/pom.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+
+ <parent>
+ <groupId>org.richfaces</groupId>
+ <artifactId>richfaces-parent</artifactId>
+ <version>10</version>
+ <relativePath>../../build/parent/pom.xml</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces.archetypes</groupId>
+ <artifactId>richfaces-archetype-gae-sample</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <packaging>maven-archetype</packaging>
+ <name>RichFaces Archetypes: GAE Application</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <build>
+ <extensions>
+ <extension>
+ <groupId>org.apache.maven.archetype</groupId>
+ <artifactId>archetype-packaging</artifactId>
+ <version>2.0-alpha-4</version>
+ </extension>
+ </extensions>
+ <plugins>
+ <plugin>
+ <artifactId>maven-archetype-plugin</artifactId>
+ <version>2.0-alpha-4</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>group-sources</id>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <finalName>sources</finalName>
+ <descriptor>assembler.xml</descriptor>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <classesDirectory>${basedir}/target/sources/sources</classesDirectory>
+ <classifier>sources</classifier>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <scm>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/richfaces/trunk/archetypes/richfac...</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/trunk/archetypes/richfaces-...</developerConnection>
+ <url>http://fisheye.jboss.org/browse/richfaces/</url>
+ </scm>
+</project>
+
Added: sandbox/trunk/archetypes/rf-gae-sample/readme.txt
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/readme.txt (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/readme.txt 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,9 @@
+RichFaces 4 Archetype
+
+
+This archetype creates a simple RichFaces 4 application. To generate a project from the archetype, run
+
+ mvn archetype:generate -DarchetypeGroupId=org.richfaces.archetypes -DarchetypeArtifactId=richfaces-archetype-simpleapp
+ -DarchetypeVersion=<version> -DgroupId=<yourGroupId> -DartifactId=<yourArtifactId> -Dversion=1.0-SNAPSHOT
+
+
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/META-INF/maven/archetype-metadata.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/META-INF/maven/archetype-metadata.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/META-INF/maven/archetype-metadata.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descript... http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="gae-sample"
+ xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descript..."
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <fileSets>
+ <fileSet filtered="true" packaged="true" encoding="UTF-8">
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**/*.java</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/webapp</directory>
+ <includes>
+ <include>**/*.jsp</include>
+ <include>**/*.xhtml</include>
+ <include>**/*.xml</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/java-gae-jsf-ri</directory>
+ <includes>
+ <include>**/*.java</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*.properties</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>src/main/webapp-gae</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </fileSet>
+ <fileSet encoding="UTF-8">
+ <directory>src/main/webapp</directory>
+ <includes>
+ <include>**/*.jsfdia</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory>.settings</directory>
+ <includes>
+ <include>**/*.xml</include>
+ </includes>
+ </fileSet>
+ <fileSet encoding="UTF-8">
+ <directory>.settings</directory>
+ <includes>
+ <include>**/*.prefs</include>
+ <include>**/*.component</include>
+ </includes>
+ </fileSet>
+ <fileSet filtered="true" encoding="UTF-8">
+ <directory></directory>
+ <includes>
+ <include>.classpath</include>
+ <include>.project</include>
+ <include>readme.txt</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+</archetype-descriptor>
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/pom.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/pom.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/pom.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>${groupId}</groupId>
+ <artifactId>${artifactId}</artifactId>
+ <name>RichFaces 4 Application</name>
+ <version>${version}</version>
+ <packaging>war</packaging>
+
+ <url>http://jboss.org/richfaces</url>
+
+ <repositories>
+ <repository>
+ <id>jboss-public-repository-group</id>
+ <name>Jboss Repository for Maven</name>
+ <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ </repository>
+ <repository>
+ <id>java-net</id>
+ <name>Java.net Maven Repository</name>
+ <url>http://download.java.net/maven/2</url>
+ </repository>
+ </repositories>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <org.richfaces.bom.version>4.0.0.20100826-M2</org.richfaces.bom.version>
+ </properties>
+
+ <build>
+ <finalName>rf-gae-sample</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <webResources>
+ <resource>
+ <directory>${basedir}/src/main/java</directory>
+ <targetPath>/WEB-INF/src</targetPath>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>jee6</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <webappDirectory>${project.build.directory}/${project.build.finalName}-jee6</webappDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>jta</artifactId>
+ <version>1.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>jee6</id>
+ <phase>package</phase>
+ <goals>
+ <goal>war</goal>
+ </goals>
+ <configuration>
+ <webappDirectory>${project.build.directory}/${project.build.finalName}-jee6</webappDirectory>
+ <classifier>jee6</classifier>
+ <packagingExcludes>WEB-INF/lib/jsf-api*,WEB-INF/lib/jsf-impl*,WEB-INF/lib/slf4j-*</packagingExcludes>
+ <warSourceExcludes>WEB-INF/lib/jsf-api*,WEB-INF/lib/jsf-impl*,WEB-INF/lib/slf4j-*</warSourceExcludes>
+ </configuration>
+ </execution>
+ </executions>
+ <configuration>
+ <webResources>
+ <resource>
+ <directory>${basedir}/src/main/java</directory>
+ <targetPath>/WEB-INF/src</targetPath>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>gae</id>
+ <dependencies>
+ <dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.web</groupId>
+ <artifactId>el-impl</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jta_1.1_spec</artifactId>
+ <version>1.1.1</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jpa_3.0_spec</artifactId>
+ <version>1.1.1</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>xalan</groupId>
+ <artifactId>xalan</artifactId>
+ <version>2.7.1</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ <version>2.9.1</version>
+ <scope>runtime</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>src/main/java-gae-jsf-ri</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <webResources>
+ <resource>
+ <directory>src/main/webapp-gae</directory>
+ </resource>
+ <resource>
+ <directory>src/main/webapp</directory>
+ </resource>
+ <resource>
+ <directory>${project.build.directory}/generated-resources</directory>
+ <targetPath>static-resources</targetPath>
+ </resource>
+ <resource>
+ <directory>${basedir}/src/main/java</directory>
+ <targetPath>/WEB-INF/src</targetPath>
+ </resource>
+ </webResources>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.richfaces.cdk</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>${org.richfaces.bom.version}</version>
+ <configuration></configuration>
+ <executions>
+ <execution>
+ <id>process</id>
+ <goals>
+ <goal>process</goal>
+ </goals>
+ <configuration>
+ <outputDir>generated-resources</outputDir>
+ <skins>
+ <skin>blueSky</skin>
+ <skin>classic</skin>
+ <skin>deepMarine</skin>
+ <skin>emeraldTown</skin>
+ <skin>japanCherry</skin>
+ <skin>ruby</skin>
+ <skin>wine</skin>
+ </skins>
+ <includedContentTypes>
+ <include>application/javascript</include>
+ <include>text/css</include>
+ <include>image/.+</include>
+ </includedContentTypes>
+ <fileNameMappings>
+ <property>
+ <name>^\Qorg.richfaces.renderkit.html\E</name>
+ <value>org.richfaces/images</value>
+ </property>
+ <property>
+ <name>^\Qorg.richfaces.renderkit.html.images\E</name>
+ <value>org.richfaces/images</value>
+ </property>
+ <property>
+ <name>^css/</name>
+ <value>org.richfaces/css/</value>
+ </property>
+ </fileNameMappings>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.richfaces</groupId>
+ <artifactId>richfaces-bom</artifactId>
+ <version>${org.richfaces.bom.version}</version>
+ <scope>import</scope>
+ <type>pom</type>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-components-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>jsp-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache</artifactId>
+ </dependency>
+
+ <!--
+ simple logger binding: only messages of level INFO and
+ higher are printed
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.5.8</version>
+ </dependency>
+
+ <!-- Log4J dependency used in examples -->
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ </dependency>
+
+ <!-- Tests -->
+ <dependency>
+ <groupId>org.testng</groupId>
+ <artifactId>testng</artifactId>
+ <version>5.10</version>
+ <classifier>jdk15</classifier>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/readme.txt
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/readme.txt (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/readme.txt 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,12 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+Project generated with richfaces-archetype-simpleapp
+
+To build this project for Tomcat 6 run
+
+ mvn clean package
+
+If you wan to create a binaries for both Tomcat 6 and JBoss 6 run
+
+ mvn clean package -P release
\ No newline at end of file
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java/RichBean.java
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java/RichBean.java (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java/RichBean.java 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,30 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package};
+
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+import java.io.Serializable;
+
+public class RichBean implements Serializable {
+
+ private static final long serialVersionUID = -2403138958014741653L;
+ private Logger logger;
+ private String name;
+
+ public RichBean() {
+ logger = LoggerFactory.getLogger(RichBean.class);
+ logger.info("post construct: initialize");
+ name = "John";
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/sun/faces/config/WebConfiguration.java
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/sun/faces/config/WebConfiguration.java (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/java-gae-jsf-ri/com/sun/faces/config/WebConfiguration.java 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,1112 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can obtain
+ * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
+ * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [year]
+ * [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.faces.config;
+
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
+import javax.faces.application.ResourceHandler;
+import javax.faces.application.StateManager;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIInput;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.BeanValidator;
+import javax.faces.view.facelets.ResourceResolver;
+import javax.servlet.ServletContext;
+
+import com.sun.faces.util.FacesLogger;
+import com.sun.faces.util.Util;
+
+/** Class Documentation */
+public class WebConfiguration
+{
+
+ // Log instance for this class
+ private static final Logger LOGGER = FacesLogger.CONFIG.getLogger();
+
+ // A Simple regular expression of allowable boolean values
+ private static final Pattern ALLOWABLE_BOOLEANS = Pattern
+ .compile("true|false");
+
+ // Key under which we store our WebConfiguration instance.
+ private static final String WEB_CONFIG_KEY = "com.sun.faces.config.WebConfiguration";
+
+ // Logging level. Defaults to FINE
+ private Level loggingLevel = Level.FINE;
+
+ private Map<BooleanWebContextInitParameter, Boolean> booleanContextParameters = new EnumMap<BooleanWebContextInitParameter, Boolean>(
+ BooleanWebContextInitParameter.class);
+
+ private Map<WebContextInitParameter, String> contextParameters = new EnumMap<WebContextInitParameter, String>(
+ WebContextInitParameter.class);
+
+ private Map<WebEnvironmentEntry, String> envEntries = new EnumMap<WebEnvironmentEntry, String>(
+ WebEnvironmentEntry.class);
+
+ private Map<WebContextInitParameter, String[]> cachedListParams;
+
+ private List<String> setParams = new ArrayList<String>();
+
+ private ServletContext servletContext;
+
+ // ------------------------------------------------------------ Constructors
+
+ private WebConfiguration(ServletContext servletContext)
+ {
+
+ this.servletContext = servletContext;
+
+ String contextName = getServletContextName();
+
+ initSetList(servletContext);
+ processBooleanParameters(servletContext, contextName);
+ processInitParameters(servletContext, contextName);
+ if (canProcessJndiEntries())
+ {
+ processJndiEntries(contextName);
+ }
+
+ // build the cache of list type params
+ cachedListParams = new HashMap<WebContextInitParameter, String[]>(3);
+ getOptionValue(WebContextInitParameter.ResourceExcludes, " ");
+ getOptionValue(WebContextInitParameter.DefaultSuffix, " ");
+ getOptionValue(WebContextInitParameter.FaceletsViewMappings, ";");
+
+ }
+
+ // ---------------------------------------------------------- Public Methods
+
+ /**
+ * Return the WebConfiguration instance for this application passing the
+ * result of FacesContext.getCurrentInstance().getExternalContext() to
+ * {@link ${symbol_pound}getInstance(javax.faces.context.ExternalContext)}.
+ *
+ * @return the WebConfiguration for this application or <code>null</code> if
+ * no FacesContext is available.
+ */
+ public static WebConfiguration getInstance()
+ {
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ return getInstance(facesContext.getExternalContext());
+
+ }
+
+ /**
+ * Return the WebConfiguration instance for this application.
+ *
+ * @param extContext
+ * the ExternalContext for this request
+ * @return the WebConfiguration for this application
+ */
+ public static WebConfiguration getInstance(ExternalContext extContext)
+ {
+
+ WebConfiguration config = (WebConfiguration) extContext
+ .getApplicationMap().get(WEB_CONFIG_KEY);
+ if (config == null)
+ {
+ return getInstance((ServletContext) extContext.getContext());
+ }
+ else
+ {
+ return config;
+ }
+
+ }
+
+ /**
+ * Return the WebConfiguration instance for this application.
+ *
+ * @param servletContext
+ * the ServletContext
+ * @return the WebConfiguration for this application or <code>null</code> if
+ * no WebConfiguration could be located
+ */
+ public static WebConfiguration getInstance(ServletContext servletContext)
+ {
+
+ WebConfiguration webConfig = (WebConfiguration) servletContext
+ .getAttribute(WEB_CONFIG_KEY);
+
+ if (webConfig == null)
+ {
+ webConfig = new WebConfiguration(servletContext);
+ servletContext.setAttribute(WEB_CONFIG_KEY, webConfig);
+ }
+ return webConfig;
+
+ }
+
+ /**
+ * @return The <code>ServletContext</code> originally used to construct this
+ * WebConfiguration instance
+ */
+ public ServletContext getServletContext()
+ {
+
+ return servletContext;
+
+ }
+
+ /**
+ * Obtain the value of the specified boolean parameter
+ *
+ * @param param
+ * the parameter of interest
+ * @return the value of the specified boolean parameter
+ */
+ public boolean isOptionEnabled(BooleanWebContextInitParameter param)
+ {
+
+ if (booleanContextParameters.get(param) != null)
+ {
+ return booleanContextParameters.get(param);
+ }
+ else
+ {
+ return param.getDefaultValue();
+ }
+
+ }
+
+ /**
+ * Obtain the value of the specified parameter
+ *
+ * @param param
+ * the parameter of interest
+ * @return the value of the specified parameter
+ */
+ public String getOptionValue(WebContextInitParameter param)
+ {
+ String result = contextParameters.get(param);
+
+ if (null == result)
+ {
+ WebContextInitParameter alternate = param.getAlternate();
+ if (null != alternate)
+ {
+ result = contextParameters.get(alternate);
+ }
+ }
+
+ return result;
+
+ }
+
+ public String[] getOptionValue(WebContextInitParameter param, String sep)
+ {
+ String[] result;
+
+ assert (null != cachedListParams);
+ if (null == (result = cachedListParams.get(param)))
+ {
+ String value = getOptionValue(param);
+ if (null == value)
+ {
+ result = new String[0];
+ }
+ else
+ {
+ result = Util.split(value, sep);
+ }
+ cachedListParams.put(param, result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Obtain the value of the specified env-entry
+ *
+ * @param entry
+ * the env-entry of interest
+ * @return the value of the specified env-entry
+ */
+ public String getEnvironmentEntry(WebEnvironmentEntry entry)
+ {
+
+ return envEntries.get(entry);
+
+ }
+
+ /**
+ * @param param
+ * the init parameter of interest
+ * @return <code>true</code> if the parameter was explicitly set, otherwise,
+ * <code>false</code>
+ */
+ public boolean isSet(WebContextInitParameter param)
+ {
+
+ return isSet(param.getQualifiedName());
+
+ }
+
+ /**
+ * @param param
+ * the init parameter of interest
+ * @return <code>true</code> if the parameter was explicitly set, otherwise,
+ * <code>false</code>
+ */
+ public boolean isSet(BooleanWebContextInitParameter param)
+ {
+
+ return isSet(param.getQualifiedName());
+
+ }
+
+ /**
+ * @return the name of this application
+ */
+ public String getServletContextName()
+ {
+
+ if (servletContext.getMajorVersion() == 2
+ && servletContext.getMinorVersion() <= 4)
+ {
+ return servletContext.getServletContextName();
+ }
+ else
+ {
+ return servletContext.getContextPath();
+ }
+
+ }
+
+ public void overrideContextInitParameter(
+ BooleanWebContextInitParameter param, boolean value)
+ {
+
+ if (param == null) { return; }
+ boolean oldVal = booleanContextParameters.put(param, value);
+ if (LOGGER.isLoggable(Level.FINE) && oldVal != value)
+ {
+ LOGGER
+ .log(
+ Level.FINE,
+ "Overriding init parameter {0}. Changing from {1} to {2}.",
+ new Object[]
+ {
+ param.getQualifiedName(), oldVal, value
+ });
+ }
+
+ }
+
+ public void overrideContextInitParameter(WebContextInitParameter param,
+ String value)
+ {
+
+ if (param == null || value == null || value.length() == 0) { return; }
+ value = value.trim();
+ String oldVal = contextParameters.put(param, value);
+ cachedListParams.remove(param);
+ if (oldVal != null)
+ {
+ if (LOGGER.isLoggable(Level.FINE) && !(oldVal.equals(value)))
+ {
+ LOGGER
+ .log(
+ Level.FINE,
+ "Overriding init parameter {0}. Changing from {1} to {2}.",
+ new Object[]
+ {
+ param.getQualifiedName(), oldVal, value
+ });
+ }
+ }
+
+ }
+
+ // ------------------------------------------------- Package Private Methods
+
+ static void clear(ServletContext servletContext)
+ {
+
+ servletContext.removeAttribute(WEB_CONFIG_KEY);
+
+ }
+
+ // --------------------------------------------------------- Private Methods
+
+ /**
+ * <p>
+ * Is the configured value valid against the default boolean pattern.
+ * </p>
+ *
+ * @param param
+ * the boolean parameter
+ * @param value
+ * the configured value
+ * @return <code>true</code> if the value is valid, otherwise
+ * <code>false</code>
+ */
+ private boolean isValueValid(BooleanWebContextInitParameter param,
+ String value)
+ {
+
+ if (!ALLOWABLE_BOOLEANS.matcher(value).matches())
+ {
+ if (LOGGER.isLoggable(Level.WARNING))
+ {
+ LOGGER.log(Level.WARNING,
+ "jsf.config.webconfig.boolconfig.invalidvalue",
+ new Object[]
+ {
+ value, param.getQualifiedName(), "true|false"
+ });
+ }
+ return false;
+ }
+
+ return true;
+
+ }
+
+ /**
+ * <p>
+ * Process all boolean context initialization parameters.
+ * </p>
+ *
+ * @param servletContext
+ * the ServletContext of interest
+ * @param contextName
+ * the context name
+ */
+ private void processBooleanParameters(ServletContext servletContext,
+ String contextName)
+ {
+
+ // process boolean contxt parameters
+ for (BooleanWebContextInitParameter param : BooleanWebContextInitParameter
+ .values())
+ {
+ String strValue = servletContext.getInitParameter(param
+ .getQualifiedName());
+ boolean value;
+
+ if (strValue != null && strValue.length() > 0
+ && param.isDeprecated())
+ {
+ BooleanWebContextInitParameter alternate = param.getAlternate();
+ if (LOGGER.isLoggable(Level.WARNING))
+ {
+ if (alternate != null)
+ {
+ LOGGER.log(Level.WARNING,
+ "jsf.config.webconfig.param.deprecated",
+ new Object[]
+ {
+ contextName, param.getQualifiedName(),
+ alternate.getQualifiedName()
+ });
+ }
+ else
+ {
+ LOGGER
+ .log(
+ Level.WARNING,
+ "jsf.config.webconfig.param.deprecated.no_replacement",
+ new Object[]
+ {
+ contextName,
+ param.getQualifiedName()
+ });
+ }
+ }
+
+ if (alternate != null)
+ {
+ if (isValueValid(param, strValue))
+ {
+ value = Boolean.valueOf(strValue);
+ }
+ else
+ {
+ value = param.getDefaultValue();
+ }
+
+ if (LOGGER.isLoggable(Level.INFO) && alternate != null)
+ {
+ LOGGER
+ .log(
+ Level.INFO,
+ ((value) ? "jsf.config.webconfig.configinfo.reset.enabled"
+ : "jsf.config.webconfig.configinfo.reset.disabled"),
+ new Object[]
+ {
+ contextName,
+ alternate.getQualifiedName()
+ });
+ }
+
+ booleanContextParameters.put(alternate, value);
+ }
+ continue;
+ }
+
+ if (!param.isDeprecated())
+ {
+ if (strValue == null)
+ {
+ value = param.getDefaultValue();
+ }
+ else
+ {
+ if (isValueValid(param, strValue))
+ {
+ value = Boolean.valueOf(strValue);
+ }
+ else
+ {
+ value = param.getDefaultValue();
+ }
+ }
+
+ // first param processed should be
+ // com.sun.faces.displayConfiguration
+ if (BooleanWebContextInitParameter.DisplayConfiguration
+ .equals(param)
+ && value)
+ {
+ loggingLevel = Level.INFO;
+ }
+
+ if (LOGGER.isLoggable(loggingLevel))
+ {
+ LOGGER
+ .log(
+ loggingLevel,
+ ((value) ? "jsf.config.webconfig.boolconfiginfo.enabled"
+ : "jsf.config.webconfig.boolconfiginfo.disabled"),
+ new Object[]
+ {
+ contextName,
+ param.getQualifiedName()
+ });
+ }
+
+ booleanContextParameters.put(param, value);
+ }
+
+ }
+
+ }
+
+ /**
+ * Adds all com.sun.faces init parameter names to a list. This allows
+ * callers to determine if a parameter was explicitly set.
+ *
+ * @param servletContext
+ * the ServletContext of interest
+ */
+ private void initSetList(ServletContext servletContext)
+ {
+
+ for (Enumeration e = servletContext.getInitParameterNames(); e
+ .hasMoreElements();)
+ {
+ String name = e.nextElement().toString();
+ if (name.startsWith("com.sun.faces"))
+ {
+ setParams.add(name);
+ }
+ }
+
+ }
+
+ /**
+ * @param name
+ * the param name
+ * @return <code>true</code> if the name was explicitly specified
+ */
+ private boolean isSet(String name)
+ {
+
+ return setParams.contains(name);
+
+ }
+
+ /**
+ * <p>
+ * Process all non-boolean context initialization parameters.
+ * </p>
+ *
+ * @param servletContext
+ * the ServletContext of interest
+ * @param contextName
+ * the context name
+ */
+ private void processInitParameters(ServletContext servletContext,
+ String contextName)
+ {
+
+ for (WebContextInitParameter param : WebContextInitParameter.values())
+ {
+ String value = servletContext.getInitParameter(param
+ .getQualifiedName());
+
+ if (value != null && value.length() > 0 && param.isDeprecated())
+ {
+ WebContextInitParameter alternate = param.getAlternate();
+ if (LOGGER.isLoggable(Level.WARNING))
+ {
+ if (alternate != null)
+ {
+ LOGGER.log(Level.WARNING,
+ "jsf.config.webconfig.param.deprecated",
+ new Object[]
+ {
+ contextName, param.getQualifiedName(),
+ alternate.getQualifiedName()
+ });
+ }
+ else
+ {
+ LOGGER
+ .log(
+ Level.WARNING,
+ "jsf.config.webconfig.param.deprecated.no_replacement",
+ new Object[]
+ {
+ contextName,
+ param.getQualifiedName()
+ });
+ }
+ }
+
+ if (alternate != null)
+ {
+ if (LOGGER.isLoggable(Level.INFO))
+ {
+ LOGGER.log(Level.INFO,
+ "jsf.config.webconfig.configinfo.reset",
+ new Object[]
+ {
+ contextName,
+ alternate.getQualifiedName(), value
+ });
+ }
+
+ contextParameters.put(alternate, value);
+ }
+ continue;
+ }
+
+ if ((value == null || value.length() == 0) && !param.isDeprecated())
+ {
+ value = param.getDefaultValue();
+ }
+ if (value == null || value.length() == 0)
+ {
+ continue;
+ }
+
+ if (value.length() > 0)
+ {
+ if (LOGGER.isLoggable(loggingLevel))
+ {
+ LOGGER.log(loggingLevel, "jsf.config.webconfig.configinfo",
+ new Object[]
+ {
+ contextName, param.getQualifiedName(),
+ value
+ });
+
+ }
+ contextParameters.put(param, value);
+ }
+ else
+ {
+ if (LOGGER.isLoggable(loggingLevel))
+ {
+ LOGGER.log(loggingLevel,
+ "jsf.config.webconfig.option.notconfigured",
+ new Object[]
+ {
+ contextName, param.getQualifiedName()
+ });
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * <p>
+ * Process all JNDI entries.
+ * </p>
+ *
+ * @param contextName
+ * the context name
+ */
+ private void processJndiEntries(String contextName)
+ {
+/*
+ * This section has been disabled due to incompatibilities with Google App Engine 1.2.6.
+ Context initialContext = null;
+ try
+ {
+ initialContext = new InitialContext();
+ }
+ catch (NamingException ne)
+ {
+ if (LOGGER.isLoggable(Level.WARNING))
+ {
+ LOGGER.log(Level.WARNING, ne.toString(), ne);
+ }
+ }
+
+ if (initialContext != null)
+ {
+ // process environment entries
+ for (WebEnvironmentEntry entry : WebEnvironmentEntry.values())
+ {
+ String entryName = entry.getQualifiedName();
+ String value = null;
+
+ try
+ {
+ value = (String) initialContext.lookup(entryName);
+ }
+ catch (NamingException root)
+ {
+ if (LOGGER.isLoggable(Level.FINE))
+ {
+ LOGGER.fine(root.toString());
+ }
+ }
+
+ if (value != null)
+ {
+ if (LOGGER.isLoggable(Level.INFO))
+ {
+ // special logic for ClientStateSavingPassword
+ if (!entry
+ .equals(WebEnvironmentEntry.ClientStateSavingPassword))
+ {
+ if (LOGGER.isLoggable(loggingLevel))
+ {
+ LOGGER.log(loggingLevel,
+ "jsf.config.webconfig.enventryinfo",
+ new Object[]
+ {
+ contextName, entryName, value
+ });
+ }
+ }
+ else
+ {
+ if (LOGGER.isLoggable(loggingLevel))
+ {
+ LOGGER
+ .log(
+ loggingLevel,
+ "jsf.config.webconfig.enventry.clientencrypt",
+ contextName);
+ }
+ }
+ }
+ envEntries.put(entry, value);
+ }
+ }
+ }
+*/
+ }
+
+ private boolean canProcessJndiEntries()
+ {
+
+ /*
+ * This section has been disabled due to incompatibilities with Google App Engine 1.2.6
+ try
+ {
+ Util.getCurrentLoader(this)
+ .loadClass("javax.naming.InitialContext");
+ }
+ catch (Exception e)
+ {
+ */
+ if (LOGGER.isLoggable(Level.FINE))
+ {
+ LOGGER
+ .fine("javax.naming is forced unavailable. JNDI entries related to Mojarra configuration will not be processed.");
+ }
+ return false;
+ /*
+ }
+ return true;
+ */
+
+ }
+
+ // ------------------------------------------------------------------- Enums
+
+ /**
+ * <p>
+ * An <code>enum</code> of all non-boolean context initalization parameters
+ * recognized by the implementation.
+ * </p>
+ */
+ public enum WebContextInitParameter
+ {
+
+ // implementation note:
+ // if a parameter is to be deprecated,
+ // then the <name>Deprecated enum element
+ // *must* appear after the one that is taking
+ // its place. The reporting logic depends on this
+
+ ManagedBeanFactoryDecorator(
+ "com.sun.faces.managedBeanFactoryDecoratorClass", ""), StateSavingMethod(
+ "javax.faces.STATE_SAVING_METHOD", "server"), FaceletsSuffix(
+ ViewHandler.FACELETS_SUFFIX_PARAM_NAME,
+ ViewHandler.DEFAULT_FACELETS_SUFFIX), DefaultSuffix(
+ ViewHandler.DEFAULT_SUFFIX_PARAM_NAME,
+ ViewHandler.DEFAULT_SUFFIX), JavaxFacesConfigFiles(
+ "javax.faces.CONFIG_FILES", ""), JavaxFacesProjectStage(
+ "javax.faces.PROJECT_STAGE", "Production"), AlternateLifecycleId(
+ "javax.faces.LIFECYCLE_ID", ""), ResourceExcludes(
+ ResourceHandler.RESOURCE_EXCLUDES_PARAM_NAME,
+ ResourceHandler.RESOURCE_EXCLUDES_DEFAULT_VALUE + " .groovy"), NumberOfViews(
+ "com.sun.faces.numberOfViewsInSession", "15"), NumberOfViewsDeprecated(
+ "com.sun.faces.NUMBER_OF_VIEWS_IN_SESSION", "15", true,
+ NumberOfViews), NumberOfLogicalViews(
+ "com.sun.faces.numberOfLogicalViews", "15"), NumberOfLogicalViewsDeprecated(
+ "com.sun.faces.NUMBER_OF_VIEWS_IN_LOGICAL_VIEW_IN_SESSION",
+ "15", true, NumberOfLogicalViews), NumberOfConcurrentFlashUsers(
+ "com.sun.faces.numberOfConcerrentFlashUsers", "5000"), NumberOfFlashesBetweenFlashReapings(
+ "com.sun.faces.numberOfFlashesBetweenFlashReapings", "5000"), InjectionProviderClass(
+ "com.sun.faces.injectionProvider", ""), SerializationProviderClass(
+ "com.sun.faces.serializationProvider", ""), ResponseBufferSize(
+ "com.sun.faces.responseBufferSize", "1024"), FaceletsBufferSize(
+ "javax.faces.FACELETS_BUFFER_SIZE", "1024", true,
+ ResponseBufferSize), FaceletsBufferSizeDeprecated(
+ "facelets.BUFFER_SIZE", "1024", true, FaceletsBufferSize), ClientStateWriteBufferSize(
+ "com.sun.faces.clientStateWriteBufferSize", "8192"), ResourceBufferSize(
+ "com.sun.faces.resourceBufferSize", "2048"), ExpressionFactory(
+ "com.sun.faces.expressionFactory",
+ "com.sun.el.ExpressionFactoryImpl"), ClientStateTimeout(
+ "com.sun.faces.clientStateTimeout", ""), DefaultResourceMaxAge(
+ "com.sun.faces.defaultResourceMaxAge", "604800"), ResourceUpdateCheckPeriod(
+ "com.sun.faces.resourceUpdateCheckPeriod", "5" // in minutes
+ ), CompressableMimeTypes("com.sun.faces.compressableMimeTypes", ""), DisableUnicodeEscaping(
+ "com.sun.faces.disableUnicodeEscaping", "auto"), FaceletsDefaultRefreshPeriod(
+ "javax.faces.FACELETS_REFRESH_PERIOD", "2"), FaceletsDefaultRefreshPeriodDeprecated(
+ "facelets.REFRESH_PERIOD", "2", true,
+ FaceletsDefaultRefreshPeriod), FaceletsResourceResolver(
+ ResourceResolver.FACELETS_RESOURCE_RESOLVER_PARAM_NAME, ""), FaceletsResourceResolverDeprecated(
+ "facelets.RESOURCE_RESOLVER", "", true,
+ FaceletsResourceResolver), FaceletsViewMappings(
+ ViewHandler.FACELETS_VIEW_MAPPINGS_PARAM_NAME, ""), FaceletsViewMappingsDeprecated(
+ "facelets.VIEW_MAPPINGS", "", true, FaceletsViewMappings), FaceletsLibraries(
+ "javax.faces.FACELETS_LIBRARIES", ""), FaceletsLibrariesDeprecated(
+ "facelets.LIBRARIES", "", true, FaceletsLibraries), FaceletsDecorators(
+ "javax.faces.FACELETS_DECORATORS", ""), FaceletsDecoratorsDeprecated(
+ "facelets.DECORATORS", "", true, FaceletsDecorators), DuplicateJARPattern(
+ "com.sun.faces.duplicateJARPattern", ""), ValidateEmptyFields(
+ UIInput.VALIDATE_EMPTY_FIELDS_PARAM_NAME, "auto"), FullStateSavingViewIds(
+ StateManager.FULL_STATE_SAVING_VIEW_IDS_PARAM_NAME, ""), AnnotationScanPackages(
+ "com.sun.faces.annotationScanPackages", ""), FaceletFactory(
+ "com.sun.faces.faceletFactory", "");
+
+ private String defaultValue;
+ private String qualifiedName;
+ private WebContextInitParameter alternate;
+ private boolean deprecated;
+
+ // ---------------------------------------------------------- Public
+ // Methods
+
+ public String getDefaultValue()
+ {
+
+ return defaultValue;
+
+ }
+
+ public String getQualifiedName()
+ {
+
+ return qualifiedName;
+
+ }
+
+ // ------------------------------------------------- Package Private
+ // Methods
+
+ WebContextInitParameter(String qualifiedName, String defaultValue)
+ {
+
+ this(qualifiedName, defaultValue, false, null);
+
+ }
+
+ WebContextInitParameter(String qualifiedName, String defaultValue,
+ boolean deprecated, WebContextInitParameter alternate)
+ {
+
+ this.qualifiedName = qualifiedName;
+ this.defaultValue = defaultValue;
+ this.deprecated = deprecated;
+ this.alternate = alternate;
+
+ }
+
+ // --------------------------------------------------------- Private
+ // Methods
+
+ private WebContextInitParameter getAlternate()
+ {
+
+ return alternate;
+
+ }
+
+ private boolean isDeprecated()
+ {
+
+ return deprecated;
+
+ }
+
+ }
+
+ /**
+ * <p>
+ * An <code>enum</code> of all boolean context initalization parameters
+ * recognized by the implementation.
+ * </p>
+ */
+ public enum BooleanWebContextInitParameter
+ {
+
+ // implementation note:
+ // if a parameter is to be deprecated,
+ // then the <name>Deprecated enum element
+ // *must* appear after the one that is taking
+ // its place. The reporting logic depends on this
+
+ DisplayConfiguration("com.sun.faces.displayConfiguration", false), ValidateFacesConfigFiles(
+ "com.sun.faces.validateXml", false), VerifyFacesConfigObjects(
+ "com.sun.faces.verifyObjects", false), ForceLoadFacesConfigFiles(
+ "com.sun.faces.forceLoadConfiguration", false), DisableArtifactVersioning(
+ "com.sun.faces.disableVersionTracking", false, true, null), EnableHtmlTagLibraryValidator(
+ "com.sun.faces.enableHtmlTagLibValidator", false), EnableCoreTagLibraryValidator(
+ "com.sun.faces.enableCoreTagLibValidator", false), PreferXHTMLContentType(
+ "com.sun.faces.preferXHTML", false), PreferXHTMLContextTypeDeprecated(
+ "com.sun.faces.PreferXHTML", false, true,
+ PreferXHTMLContentType), CompressViewState(
+ "com.sun.faces.compressViewState", true), CompressViewStateDeprecated(
+ "com.sun.faces.COMPRESS_STATE", true, true, CompressViewState), CompressJavaScript(
+ "com.sun.faces.compressJavaScript", true), ExternalizeJavaScriptDeprecated(
+ "com.sun.faces.externalizeJavaScript", true, true, null), SendPoweredByHeader(
+ "com.sun.faces.sendPoweredByHeader", true), EnableJSStyleHiding(
+ "com.sun.faces.enableJSStyleHiding", false), EnableScriptInAttributeValue(
+ "com.sun.faces.enableScriptsInAttributeValues", true), WriteStateAtFormEnd(
+ "com.sun.faces.writeStateAtFormEnd", true), EnableLazyBeanValidation(
+ "com.sun.faces.enableLazyBeanValidation", true), EnableLoadBundle11Compatibility(
+ "com.sun.faces.enabledLoadBundle11Compatibility", false), EnableRestoreView11Compatibility(
+ "com.sun.faces.enableRestoreView11Compatibility", false), SerializeServerState(
+ "com.sun.faces.serializeServerState", false), EnableViewStateIdRendering(
+ "com.sun.faces.enableViewStateIdRendering", true), RegisterConverterPropertyEditors(
+ "com.sun.faces.registerConverterPropertyEditors", false), EnableGroovyScripting(
+ "com.sun.faces.enableGroovyScripting", false), DisableFaceletJSFViewHandler(
+ "javax.faces.DISABLE_FACELET_JSF_VIEWHANDLER", false), DisableDefaultBeanValidator(
+ BeanValidator.DISABLE_DEFAULT_BEAN_VALIDATOR_PARAM_NAME, false), DateTimeConverterUsesSystemTimezone(
+ "javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE",
+ false), FaceletsSkipComments(
+ "javax.faces.FACELETS_SKIP_COMMENTS", false), FaceletsSkipCommentsDeprecated(
+ "facelets.SKIP_COMMENTS", false, true, FaceletsSkipComments), PartialStateSaving(
+ StateManager.PARTIAL_STATE_SAVING_PARAM_NAME, true), GenerateUniqueServerStateIds(
+ "com.sun.faces.generateUniqueServerStateIds", true), AutoCompleteOffOnViewState(
+ "com.sun.faces.autoCompleteOffOnViewState", true), EnableThreading(
+ "com.sun.faces.enableThreading", true), AllowTextChildren(
+ "com.sun.faces.allowTextChildren", false);
+
+ private BooleanWebContextInitParameter alternate;
+
+ private String qualifiedName;
+ private boolean defaultValue;
+ private boolean deprecated;
+
+ // ---------------------------------------------------------- Public
+ // Methods
+
+ public boolean getDefaultValue()
+ {
+
+ return defaultValue;
+
+ }
+
+ public String getQualifiedName()
+ {
+
+ return qualifiedName;
+
+ }
+
+ // ------------------------------------------------- Package Private
+ // Methods
+
+ BooleanWebContextInitParameter(String qualifiedName,
+ boolean defaultValue)
+ {
+
+ this(qualifiedName, defaultValue, false, null);
+
+ }
+
+ BooleanWebContextInitParameter(String qualifiedName,
+ boolean defaultValue, boolean deprecated,
+ BooleanWebContextInitParameter alternate)
+ {
+
+ this.qualifiedName = qualifiedName;
+ this.defaultValue = defaultValue;
+ this.deprecated = deprecated;
+ this.alternate = alternate;
+
+ }
+
+ // --------------------------------------------------------- Private
+ // Methods
+
+ private BooleanWebContextInitParameter getAlternate()
+ {
+
+ return alternate;
+
+ }
+
+ private boolean isDeprecated()
+ {
+
+ return deprecated;
+
+ }
+
+ }
+
+ /**
+ * <p>
+ * An <code>enum</code> of all environment entries (specified in the
+ * web.xml) recognized by the implemenetation.
+ * </p>
+ */
+ public enum WebEnvironmentEntry
+ {
+
+ ClientStateSavingPassword("ClientStateSavingPassword"), ProjectStage(
+ javax.faces.application.ProjectStage.PROJECT_STAGE_JNDI_NAME);
+
+ private static final String JNDI_PREFIX = "java:comp/env/";
+ private String qualifiedName;
+
+ // ---------------------------------------------------------- Public
+ // Methods
+
+ public String getQualifiedName()
+ {
+
+ return qualifiedName;
+
+ }
+
+ // ------------------------------------------------- Package Private
+ // Methods
+
+ WebEnvironmentEntry(String qualifiedName)
+ {
+
+ if (qualifiedName.startsWith(JNDI_PREFIX))
+ {
+ this.qualifiedName = qualifiedName;
+ }
+ else
+ {
+ this.qualifiedName = JNDI_PREFIX + qualifiedName;
+ }
+
+ }
+
+ }
+
+ /**
+ * <p>
+ * An <code>enum</code> of all possible values for the
+ * <code>disableUnicodeEscaping</code> configuration parameter.
+ * </p>
+ */
+ public enum DisableUnicodeEscaping
+ {
+ True("true"), False("false"), Auto("auto");
+
+ private final String value;
+
+ DisableUnicodeEscaping(String value)
+ {
+ this.value = value;
+ }
+
+ public static DisableUnicodeEscaping getByValue(String value)
+ {
+ for (DisableUnicodeEscaping disableUnicodeEscaping : DisableUnicodeEscaping
+ .values())
+ {
+ if (disableUnicodeEscaping.value.equals(value)) { return disableUnicodeEscaping; }
+ }
+
+ return null;
+ }
+ }
+
+} // END WebConfiguration
\ No newline at end of file
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/resources/logging.properties
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/resources/logging.properties (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/resources/logging.properties 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,31 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+${symbol_pound} A default java.util.logging configuration.
+${symbol_pound} (All App Engine logging is through java.util.logging by default).
+${symbol_pound}
+${symbol_pound} To use this configuration, copy it into your application's WEB-INF
+${symbol_pound} folder and add the following to your appengine-web.xml:
+${symbol_pound}
+${symbol_pound} <system-properties>
+${symbol_pound} <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
+${symbol_pound} </system-properties>
+${symbol_pound}
+
+${symbol_pound} Set the default logging level for all loggers to WARNING
+.level = WARNING
+
+${symbol_pound} Set the default logging level for ORM, specifically, to WARNING
+DataNucleus.JDO.level=WARNING
+DataNucleus.Persistence.level=WARNING
+DataNucleus.Cache.level=WARNING
+DataNucleus.MetaData.level=WARNING
+DataNucleus.General.level=WARNING
+DataNucleus.Utility.level=WARNING
+DataNucleus.Transaction.level=WARNING
+DataNucleus.Datastore.level=WARNING
+DataNucleus.ClassLoading.level=WARNING
+DataNucleus.Plugin.level=WARNING
+DataNucleus.ValueGeneration.level=WARNING
+DataNucleus.Enhancer.level=WARNING
+DataNucleus.SchemaTool.level=WARNING
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/.faces-config.xml.jsfdia 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PROCESS model-entity="JSFProcess"/>
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/faces-config.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/faces-config.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/faces-config.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,13 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<?xml version="1.0"?>
+<faces-config version="2.0" 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_2_0.xsd">
+
+ <managed-bean>
+ <managed-bean-name>richBean</managed-bean-name>
+ <managed-bean-class>${package}.RichBean</managed-bean-class>
+ <managed-bean-scope>view</managed-bean-scope>
+ </managed-bean>
+</faces-config>
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/jboss-scanning.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/jboss-scanning.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/jboss-scanning.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,14 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<scanning xmlns="urn:jboss:scanning:1.0">
+<!--
+ For JBoss AS 6 integration there is a conflict with guava, and
+ google-collections. JBAS-8361
+-->
+ <path name="WEB-INF/classes"></path>
+
+ <path name="WEB-INF/lib/guava-r05.jar">
+ <exclude name="com.google.common.collect" />
+ </path>
+</scanning>
\ No newline at end of file
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/WEB-INF/web.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,54 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
+ 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-app_2_5.xsd">
+ <display-name>Sample RichFaces 4 Application</display-name>
+ <context-param>
+ <param-name>javax.faces.PROJECT_STAGE</param-name>
+ <param-value>Development</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.SKIP_COMMENTS</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.enableControlSkinning</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.enableControlSkinningClasses</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.skin</param-name>
+ <param-value>blueSky</param-value>
+ </context-param>
+ <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>*.jsf</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>/faces/*</url-pattern>
+ </servlet-mapping>
+ <session-config>
+ <session-timeout>30</session-timeout>
+ </session-config>
+ <mime-mapping>
+ <extension>ecss</extension>
+ <mime-type>text/css</mime-type>
+ </mime-mapping>
+ <welcome-file-list>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ </login-config>
+</web-app>
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.jsp
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.jsp (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.jsp 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,10 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head></head>
+ <body>
+ <jsp:forward page="/index.jsf" />
+ </body>
+</html>
\ No newline at end of file
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.xhtml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.xhtml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/index.xhtml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,27 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<!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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j">
+
+<body>
+<ui:composition template="/templates/template.xhtml">
+
+ <ui:define name="title">RichFaces Sample</ui:define>
+
+ <ui:define name="body">
+ <h:form prependId="false">
+ <h:outputLabel value="Name:" for="nameInput" />
+ <h:inputText id="nameInput" value="${symbol_pound}{richBean.name}">
+ <a4j:ajax event="keyup" render="output" />
+ </h:inputText>
+ <h:panelGroup id="output">
+ <h:outputText value="Hello ${symbol_pound}{richBean.name}!"
+ rendered="${symbol_pound}{not empty richBean.name}" />
+ </h:panelGroup>
+ </h:form>
+ </ui:define>
+</ui:composition>
+</body>
+</html>
\ No newline at end of file
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/templates/template.xhtml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/templates/template.xhtml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp/templates/template.xhtml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,16 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<!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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:a4j="http://richfaces.org/a4j">
+
+<h:head>
+ <title><ui:define name="title">Application Title</ui:define></title>
+ <meta http-equiv="content-type" content="text/xhtml; charset=UTF-8" />
+</h:head>
+
+<h:body>
+ <ui:insert name="body">Default content</ui:insert>
+</h:body>
+</html>
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/appengine-web.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/appengine-web.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/appengine-web.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,12 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<?xml version="1.0" encoding="utf-8"?>
+<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
+ <application>rf-${artifactId}</application>
+ <version>1</version>
+ <sessions-enabled>true</sessions-enabled>
+ <system-properties>
+ <property name="java.util.logging.config.file" value="WEB-INF/classes/logging.properties" />
+ </system-properties>
+</appengine-web-app>
\ No newline at end of file
Added: sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/web.xml
===================================================================
--- sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/web.xml (rev 0)
+++ sandbox/trunk/archetypes/rf-gae-sample/src/main/resources/archetype-resources/src/main/webapp-gae/WEB-INF/web.xml 2010-09-09 09:17:57 UTC (rev 19138)
@@ -0,0 +1,92 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="richfaces-showcase" version="2.5">
+ <display-name>richfaces-showcase-gae</display-name>
+ <welcome-file-list>
+ <welcome-file>index.jsp</welcome-file>
+ </welcome-file-list>
+ <context-param>
+ <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
+ <param-value>/WEB-INF/app-tags.taglib.xml</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.enableControlSkinning</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.enableControlSkinningClasses</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.skin</param-name>
+ <param-value>blueSky</param-value>
+ </context-param>
+ <context-param>
+ <param-name>javax.faces.PROJECT_STAGE</param-name>
+ <param-value>Development</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.staticResourceLocation</param-name>
+ <param-value>${symbol_pound}{facesContext.externalContext.requestContextPath}/static-resources/${symbol_pound}{resourceLocation}</param-value>
+ </context-param>
+
+ <context-param>
+ <param-name>org.ajax4jsf.cache.CACHE_MANAGER_FACTORY_CLASS</param-name>
+ <param-value>org.ajax4jsf.cache.lru.LRUMapCacheFactory</param-value>
+ </context-param>
+
+ <context-param>
+ <description>
+ Set this flag to true if you want the JavaServer Faces
+ Reference Implementation to validate the XML in your
+ faces-config.xml resources against the DTD. Default
+ value is false.
+ </description>
+ <param-name>com.sun.faces.validateXml</param-name>
+ <param-value>true</param-value>
+ </context-param>
+ <!-- ***** Accommodate Single-Threaded Requirement of Google AppEngine -->
+ <context-param>
+ <description>
+ When enabled, the runtime initialization and default ResourceHandler
+ implementation will use threads to perform their functions. Set this
+ value to false if threads aren't desired (as in the case of running
+ within the Google Application Engine).
+
+ Note that when this option is disabled, the ResourceHandler will not
+ pick up new versions of resources when ProjectStage is development.
+ </description>
+ <param-name>com.sun.faces.enableThreading</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <context-param>
+ <param-name>com.sun.faces.expressionFactory</param-name>
+ <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
+ </context-param>
+ <context-param>
+ <param-name>org.richfaces.executeAWTInitializer</param-name>
+ <param-value>false</param-value>
+ </context-param>
+ <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>*.jsf</url-pattern>
+ </servlet-mapping>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>/faces/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
14 years, 3 months
JBoss Rich Faces SVN: r19137 - in trunk/core: api/src/test/java/org/ajax4jsf/javascript and 5 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-09-08 15:14:49 -0400 (Wed, 08 Sep 2010)
New Revision: 19137
Added:
trunk/core/api/src/test/java/org/richfaces/renderkit/
trunk/core/api/src/test/java/org/richfaces/renderkit/util/
trunk/core/api/src/test/java/org/richfaces/renderkit/util/IdSplitBuilderTest.java
Removed:
trunk/core/impl/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java
trunk/core/impl/src/main/java/org/richfaces/renderkit/util/IdSplitBuilder.java
trunk/core/impl/src/main/java/org/richfaces/renderkit/util/RendererUtils.java
trunk/core/impl/src/test/java/org/richfaces/renderkit/util/
Modified:
trunk/core/api/src/main/java/org/ajax4jsf/javascript/JSEncoder.java
trunk/core/api/src/test/java/org/ajax4jsf/javascript/ScriptUtilsTest.java
Log:
RF-7560 - synchronized unmerged files
Modified: trunk/core/api/src/main/java/org/ajax4jsf/javascript/JSEncoder.java
===================================================================
--- trunk/core/api/src/main/java/org/ajax4jsf/javascript/JSEncoder.java 2010-09-08 17:07:06 UTC (rev 19136)
+++ trunk/core/api/src/main/java/org/ajax4jsf/javascript/JSEncoder.java 2010-09-08 19:14:49 UTC (rev 19137)
@@ -31,13 +31,14 @@
// private char APOSTROPHE[] = { '\\', '\'' };
private static final char[] ENCODE_HEX = "0123456789ABCDEF".toCharArray();
- private static final char[] ENCODE_APOS = "\\'".toCharArray();
private static final char[] ENCODE_QUOT = "\\\"".toCharArray();
private static final char[] ENCODE_LF = "\\n".toCharArray();
+ private static final char[] ENCODE_BC = "\\b".toCharArray();
private static final char[] ENCODE_FF = "\\f".toCharArray();
private static final char[] ENCODE_CR = "\\r".toCharArray();
private static final char[] ENCODE_TAB = "\\t".toCharArray();
private static final char[] ENCODE_BS = "\\\\".toCharArray();
+ private static final char[] ENCODE_FS = "\\/".toCharArray();
// private static final char ENCODE_ESC[] = "\\e".toCharArray();
@@ -47,32 +48,34 @@
public JSEncoder() {}
/**
- * Return true or false wether this encoding can encode the specified
+ * Return true or false whether this encoding/format can encode the specified
* character or not.
* <p>
* This method will return true for the following character range: <br />
* <code>
- * <nobr>#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]</nobr>
+ * <nobr>\b | \f | \t | \r | \n | " | \ | / | [#x20-#xD7FF] | [#xE000-#xFFFD]</nobr>
* </code>
* </p>
*
* @see <a href="http://www.w3.org/TR/REC-xml#charsets">W3C XML 1.0 </a>
+ * @see <a href="http://json.org/">JSON.org</a>
*/
public boolean compile(char c) {
- if ((c == 0x09) || // [\t]
- (c == 0x0a) || // [\n]
- (c == 0x0d) || // [\r](c == 0x22) || // ["]
- (c == 0x22) || // ["]
- (c == 0x27) || // [']
- (c == 0x5c) || // [\]
- (c == 0x03) || // [esc]
- (c == ']') || // ] - to avoid conflicts in CDATA
- (c == '<') || // - escape HTML markup characters
- (c == '>') || // - HTML
- (c == '&') || // - HTML
- (c == '-') || // - HTML comments
- (c < 0x20) || // See <http://www.w3.org/TR/REC-xml#charsets>
- ((c > 0xd7ff) && (c < 0xe000)) || (c > 0xfffd) || (c > 0xff)) {
+ if ((c == '\b') ||
+ (c == '\f') |
+ (c == '\t') ||
+ (c == '\n') ||
+ (c == '\r') ||
+ (c == '"') ||
+ (c == '\\') ||
+ (c == '/') ||
+ (c == ']') || // ] - to avoid conflicts in CDATA
+ (c == '<') || // - escape HTML markup characters
+ (c == '>') || // - HTML
+ (c == '&') || // - HTML
+ (c == '-') || // - HTML comments
+ (c < 0x20) || // See <http://www.w3.org/TR/REC-xml#charsets>
+ ((c > 0xd7ff) && (c < 0xe000)) || (c > 0xfffd) || (c > 0xff)) {
return false;
}
@@ -85,39 +88,36 @@
*/
public char[] encode(char c) {
switch (c) {
- case 0x03 :
- return ENCODE_FF; // (>) [>]
+ case '\b' :
+ return ENCODE_BC;
+
+ case '\f' :
+ return ENCODE_FF;
- case 0x09 :
- return ENCODE_TAB; // (>) [>]
+ case '\t' :
+ return ENCODE_TAB;
- case 0x0a :
- return ENCODE_LF; // (>) [>]
+ case '\n' :
+ return ENCODE_LF;
- case 0x0d :
- return ENCODE_CR; // (>) [>]
+ case '\r' :
+ return ENCODE_CR;
- case 0x22 :
- return ENCODE_QUOT; // (") ["]
+ case '"' :
+ return ENCODE_QUOT;
- case 0x27 :
- return ENCODE_APOS; // (') [']
+ case '\\' :
+ return ENCODE_BS;
- case 0x5c :
- return ENCODE_BS; // (<) [<]
-
+ case '/' :
+ return ENCODE_FS;
+
default : {
- if (c > 0xff) {
- char[] ret = {
- '\\', 'u', ENCODE_HEX[c >> 0xc & 0xf], ENCODE_HEX[c >> 0x8 & 0xf], ENCODE_HEX[c >> 0x4 & 0xf],
- ENCODE_HEX[c & 0xf]
- };
+ char[] ret = {
+ '\\', 'u', ENCODE_HEX[c >> 0xc & 0xf], ENCODE_HEX[c >> 0x8 & 0xf], ENCODE_HEX[c >> 0x4 & 0xf],
+ ENCODE_HEX[c & 0xf]
+ };
- return ret;
- }
-
- char[] ret = {'\\', 'x', ENCODE_HEX[c >> 0x4 & 0xf], ENCODE_HEX[c & 0xf]};
-
return ret;
}
}
Modified: trunk/core/api/src/test/java/org/ajax4jsf/javascript/ScriptUtilsTest.java
===================================================================
--- trunk/core/api/src/test/java/org/ajax4jsf/javascript/ScriptUtilsTest.java 2010-09-08 17:07:06 UTC (rev 19136)
+++ trunk/core/api/src/test/java/org/ajax4jsf/javascript/ScriptUtilsTest.java 2010-09-08 19:14:49 UTC (rev 19137)
@@ -123,9 +123,9 @@
* Test method for {@link org.ajax4jsf.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testStringToScript() {
- Object obj = "foo";
+ Object obj = "f \b\r\t\f\n\"'\\/ oo";
- assertEquals("\"foo\"", ScriptUtils.toScript(obj));
+ assertEquals("\"f \\b\\r\\t\\f\\n\\\"'\\\\\\/ oo\"", ScriptUtils.toScript(obj));
}
/**
@@ -260,8 +260,8 @@
public void testAddEncoded() {
StringBuilder buff = new StringBuilder();
- ScriptUtils.addEncoded(buff, "foo\"\'");
- assertEquals("foo\\\"\\\'", buff.toString());
+ ScriptUtils.addEncoded(buff, "foo");
+ assertEquals("foo", buff.toString());
}
/**
Copied: trunk/core/api/src/test/java/org/richfaces/renderkit/util/IdSplitBuilderTest.java (from rev 19136, trunk/core/impl/src/test/java/org/richfaces/renderkit/util/IdSplitBuilderTest.java)
===================================================================
--- trunk/core/api/src/test/java/org/richfaces/renderkit/util/IdSplitBuilderTest.java (rev 0)
+++ trunk/core/api/src/test/java/org/richfaces/renderkit/util/IdSplitBuilderTest.java 2010-09-08 19:14:49 UTC (rev 19137)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.renderkit.util;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import org.junit.Test;
+import org.richfaces.renderkit.util.IdSplitBuilder;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class IdSplitBuilderTest {
+
+ private static String[] asArray(String... strings) {
+ return strings;
+ }
+
+ @Test
+ public void testEmptyString() throws Exception {
+ assertArrayEquals(asArray(), IdSplitBuilder.split(""));
+ assertArrayEquals(asArray(), IdSplitBuilder.split(" \r\t\n "));
+ }
+
+ @Test
+ public void testOneStrings() throws Exception {
+ assertArrayEquals(asArray("test"), IdSplitBuilder.split("test"));
+ assertArrayEquals(asArray("some:id"), IdSplitBuilder.split("some:id"));
+ assertArrayEquals(asArray("table:[1]"), IdSplitBuilder.split("table:[1]"));
+ assertArrayEquals(asArray("table:[1, 2]"), IdSplitBuilder.split("table:[1, 2]"));
+ assertArrayEquals(asArray("table:[1, 2]:nestedTable:[*]"), IdSplitBuilder.split("table:[1, 2]:nestedTable:[*]"));
+ assertArrayEquals(asArray("table:[1, 2]:[*]:group"), IdSplitBuilder.split("table:[1, 2]:[*]:group"));
+ assertArrayEquals(asArray("table:[1 2]:nestedTable:[*]"), IdSplitBuilder.split("table:[1 2]:nestedTable:[*]"));
+ assertArrayEquals(asArray("table:[1 2]:[*]:group"), IdSplitBuilder.split("table:[1 2]:[*]:group"));
+ }
+
+ @Test
+ public void testTwoStrings() throws Exception {
+ assertArrayEquals(asArray("test", "abc"), IdSplitBuilder.split("test abc"));
+ assertArrayEquals(asArray("some:id", "form:table"), IdSplitBuilder.split("some:id form:table"));
+ assertArrayEquals(asArray("test", "abc"), IdSplitBuilder.split("test, abc"));
+ assertArrayEquals(asArray("some:id", "form:table"), IdSplitBuilder.split("some:id, form:table"));
+
+ assertArrayEquals(asArray("test:[1 2 3]:abc", "form:[2]"), IdSplitBuilder.split("test:[1 2 3]:abc form:[2]"));
+ assertArrayEquals(asArray("[1 2]:some", "[3\t4]:id"), IdSplitBuilder.split(" [1 2]:some [3\t4]:id "));
+ }
+
+ @Test
+ public void testSeveralStrings() throws Exception {
+ assertArrayEquals(asArray("test", "abc", "def", "ghi"), IdSplitBuilder.split("test abc def ghi"));
+ assertArrayEquals(asArray("test:[1 2]abc", "def", "ghi"), IdSplitBuilder.split("test:[1 2]abc def ghi"));
+ assertArrayEquals(asArray("[1 2]abc", "[3, 4]def", "ghi[5 6 7]"),
+ IdSplitBuilder.split("[1 2]abc [3, 4]def ghi[5 6 7]"));
+
+ assertArrayEquals(
+ asArray("test:[1 2]:abc", "table", "form:table:[ * ]:child", "extTable:[ 0, 3 ]:child:[1 8]:@header"),
+ IdSplitBuilder.split(" test:[1 2]:abc, table," +
+ " form:table:[ * ]:child, extTable:[ 0, 3 ]:child:[1 8]:@header" ));
+ }
+}
Deleted: trunk/core/impl/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java 2010-09-08 17:07:06 UTC (rev 19136)
+++ trunk/core/impl/src/main/java/org/richfaces/renderkit/util/AjaxRendererUtils.java 2010-09-08 19:14:49 UTC (rev 19137)
@@ -1,1147 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.renderkit.util;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.faces.component.NamingContainer;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIForm;
-import javax.faces.context.FacesContext;
-import javax.faces.context.PartialResponseWriter;
-
-import org.ajax4jsf.Messages;
-import org.ajax4jsf.component.AjaxClientBehavior;
-import org.ajax4jsf.component.AjaxComponent;
-import org.ajax4jsf.context.AjaxContext;
-import org.ajax4jsf.javascript.JSFunction;
-import org.ajax4jsf.javascript.JSFunctionDefinition;
-import org.ajax4jsf.javascript.JSReference;
-import org.ajax4jsf.renderkit.AJAXDataSerializer;
-import org.ajax4jsf.renderkit.AjaxEventOptions;
-import org.richfaces.application.ServiceTracker;
-import org.richfaces.log.Logger;
-import org.richfaces.log.RichfacesLogger;
-import org.richfaces.renderkit.HandlersChain;
-import org.richfaces.renderkit.util.RendererUtils.HTML;
-
-/**
- * @author shura
- * <p/>
- * Some utilites for render AJAX components.
- */
-public final class AjaxRendererUtils {
-
- public static final String AJAX_ABORT_ATTR = "ignoreDupResponses";
- public static final String AJAX_AREAS_RENDERED = "org.ajax4jsf.areas.rendered";
- public static final String AJAX_DELAY_ATTR = "requestDelay";
-
- /**
- * Name Javasript function for submit AJAX request
- */
- public static final String AJAX_FUNCTION_NAME = "RichFaces.ajax";
-
- /**
- * @since 3.3.0
- */
- public static final String AJAX_PROCESS_ATTRIBUTE = "process";
- public static final String AJAX_QUEUE_ATTR = "eventsQueue";
- public static final String AJAX_REGIONS_ATTRIBUTE = "reRender";
- public static final String AJAX_SINGLE_ATTR = "ajaxSingle";
- public static final String AJAX_SINGLE_PARAMETER_NAME = "ajaxSingle";
- public static final String ALL = "@all";
- public static final String FORM = "@form";
- public static final String THIS = "@this";
- public static final String REGION = "@region";
- public static final String NONE = "@none";
-
- public static final Set<String> GLOBAL_META_COMPONENTS;
-
- static {
- GLOBAL_META_COMPONENTS = new HashSet<String>(2);
-
- GLOBAL_META_COMPONENTS.add(ALL);
- GLOBAL_META_COMPONENTS.add(NONE);
- }
-
- /**
- * Attribute to keep
- */
- public static final String LIMITRENDER_ATTR_NAME = "limitRender";
-
- /**
- * Attribute for keep JavaScript function name for call before updating
- * DOM tree.
- */
- public static final String ONBEFOREDOMUPDATE_ATTR_NAME = "onbeforedomupdate";
- public static final String ONBEGIN_ATTR_NAME = "onbegin";
-
- /**
- * Attribute for keep JavaScript function name for call after complete
- * request.
- */
- public static final String ONCOMPLETE_ATTR_NAME = "oncomplete";
-
- public static final String DATA_ATTR_NAME = "data";
-
- /**
- * Attribute for keep JavaScript function name for call after complete
- * request.
- */
- public static final String ONCOMPLETE_CONTENT_ID = "org.ajax4jsf.oncomplete";
- public static final String SIMILARITY_GROUPING_ID_ATTR = "similarityGroupingId";
-
- /**
- * Attribute for keep clientId of status component
- */
- public static final String STATUS_ATTR_NAME = "status";
- public static final String VALUE_ATTR = "value";
-
- public static final String EXTENSION_ID = "org.richfaces.extension";
- public static final String AJAX_COMPONENT_ID_PARAMETER = "org.richfaces.ajax.component";
- public static final String BEHAVIOR_EVENT_PARAMETER = "javax.faces.behavior.event";
-
- public static final String QUEUE_ID_ATTRIBUTE = "queueId";
-
- private static final String BEFOREDOMUPDATE_ELEMENT_NAME = "beforedomupdate";
- private static final String COMPLETE_ELEMENT_NAME = "complete";
- private static final String DATA_ELEMENT_NAME = "data";
- private static final String COMPONENT_DATA_ELEMENT_NAME = "componentData";
-
- private static final RendererUtils RENDERER_UTILS = RendererUtils.getInstance();
- private static final Class<?> OBJECT_ARRAY_CLASS = new Object[0].getClass();
- private static final Logger LOG = RichfacesLogger.RENDERKIT.getLogger();
-
- /**
- * Static class - protect constructor
- */
- private AjaxRendererUtils() {
- }
-
- private static enum BehaviorEventOptionsData {
- begin {
- @Override
- public String getAttributeValue(AjaxClientBehavior behavior) {
- return behavior.getOnbegin();
- }
- },
- error {
- @Override
- public String getAttributeValue(AjaxClientBehavior behavior) {
- return behavior.getOnerror();
- }
- },
- queueId {
- @Override
- public String getAttributeValue(AjaxClientBehavior behavior) {
- return behavior.getQueueId();
- }
- },
- event {
- @Override
- public String getAttributeValue(AjaxClientBehavior behavior) {
- return behavior.getOnevent();
- }
- };
-
- public abstract String getAttributeValue(AjaxClientBehavior behavior);
- }
-
- /**
- * Build JavaScript onclick event for given component
- *
- * @param uiComponent -
- * component for build event
- * @param facesContext
- * @return <code>StringBuffer</code> with Javascript code
- */
- public static StringBuffer buildOnClick(UIComponent uiComponent, FacesContext facesContext) {
- return buildOnClick(uiComponent, facesContext, false);
- }
-
- /**
- * Build JavaScript onclick event for given component
- *
- * @param uiComponent -
- * component for build event
- * @param facesContext
- * @param omitDefaultActionUrl - default action URL is not encoded if parameter is true
- * @return <code>StringBuffer</code> with Javascript code
- */
- public static StringBuffer buildOnClick(UIComponent uiComponent, FacesContext facesContext,
- boolean omitDefaultActionUrl) {
- return buildOnEvent(uiComponent, facesContext, HTML.ONCLICK_ATTRIBUTE, omitDefaultActionUrl);
- }
-
- /**
- * Build JavaScript event for component
- *
- * @param uiComponent -
- * component for build event
- * @param facesContext
- * @param eventName -
- * name of event
- * @return <code>StringBuffer</code> with Javascript code
- */
- public static StringBuffer buildOnEvent(UIComponent uiComponent, FacesContext facesContext, String eventName) {
- return buildOnEvent(uiComponent, facesContext, eventName, false);
- }
-
- /**
- * Build JavaScript event for component
- *
- * @param uiComponent -
- * component for build event
- * @param facesContext
- * @param eventName -
- * name of event
- * @param omitDefaultActionUrl - default action URL is not encoded if parameter is true
- * @return <code>StringBuffer</code> with Javascript code
- */
- public static StringBuffer buildOnEvent(UIComponent uiComponent, FacesContext facesContext, String eventName,
- boolean omitDefaultActionUrl) {
- StringBuffer onEvent = new StringBuffer();
-
-// if (null != eventName) {
-// String commandOnEvent = (String) uiComponent.getAttributes().get(
-// eventName);
-// if (commandOnEvent != null) {
-// onEvent.append(commandOnEvent);
-// onEvent.append(';');
-// }
-// }
-// JSFunction ajaxFunction = buildAjaxFunction(uiComponent, facesContext);
-// // Create formal parameter for non-input elements ???
-// // Link Control pseudo-object
-// // Options map. Possible options for function call :
-// // control - name of form control for submit.
-// // name - name for link control \
-// // value - value of control. - possible replace by parameters ?
-// // single true/false - submit all form or only one control.
-// // affected - array of element's ID for update on responce.
-// // oncomplete - function for call after complete request.
-// // status - id of request status component.
-// // parameters - map of parameters name/value for append on request.
-// // ..........
-// ajaxFunction.addParameter(buildEventOptions(facesContext, uiComponent, omitDefaultActionUrl));
-//
-// // appendAjaxSubmitParameters(facesContext, uiComponent, onEvent);
-// ajaxFunction.appendScript(onEvent);
-// if (uiComponent instanceof AjaxSupport) {
-// AjaxSupport support = (AjaxSupport) uiComponent;
-// if (support.isDisableDefault()) {
-// onEvent.append("; return false;");
-// }
-// }
-// LOG.debug(Messages.getMessage(Messages.BUILD_ONCLICK_INFO, uiComponent
-// .getId(), onEvent.toString()));
- return onEvent;
- }
-
- public static AjaxEventOptions buildEventOptions(FacesContext facesContext, UIComponent component) {
- return buildEventOptions(facesContext, component, null);
- }
-
- public static AjaxEventOptions buildEventOptions(FacesContext facesContext, UIComponent component,
- AjaxClientBehavior ajaxBehavior) {
- AjaxEventOptions ajaxEventOptions = new AjaxEventOptions();
- Map<String, Object> parametersMap = RENDERER_UTILS.createParametersMap(facesContext, component);
- String ajaxStatusName = getAjaxStatus(component);
-
- if (ajaxBehavior != null) {
- ajaxStatusName = (ajaxBehavior.getStatus() != null) ? ajaxBehavior.getStatus() : ajaxStatusName;
- appenAjaxBehaviorOptions(ajaxBehavior, ajaxEventOptions);
- } else {
- appendComponentOptions(facesContext, component, ajaxEventOptions);
- }
-
- if ((ajaxStatusName != null) && (ajaxStatusName.length() != 0)) {
- ajaxEventOptions.set(STATUS_ATTR_NAME, ajaxStatusName);
- }
-
- if (!parametersMap.isEmpty()) {
- ajaxEventOptions.getParameters().putAll(parametersMap);
- }
-
- return ajaxEventOptions;
- }
-
- private static boolean isNotEmpty(String value) {
- return (value != null) && (value.length() != 0);
- }
-
- private static void appenAjaxBehaviorOptions(AjaxClientBehavior behavior, AjaxEventOptions ajaxEventOptions) {
- for (BehaviorEventOptionsData optionsData : BehaviorEventOptionsData.values()) {
- String eventHandlerValue = optionsData.getAttributeValue(behavior);
-
- if (isNotEmpty(eventHandlerValue)) {
- ajaxEventOptions.set(optionsData.toString(), eventHandlerValue);
- }
- }
- }
-
- private static void appendComponentOptions(FacesContext facesContext, UIComponent component,
- AjaxEventOptions ajaxEventOptions) {
- String behaviorName = "begin";
- HandlersChain handlersChain = new HandlersChain(facesContext, component);
- String inlineHandler = getAjaxOnBegin(component);
-
- handlersChain.addInlineHandlerAsValue(inlineHandler);
- handlersChain.addBehaviors(behaviorName);
-
- String handlerScript = handlersChain.toScript();
-
- if (isNotEmpty(handlerScript)) {
- ajaxEventOptions.set(behaviorName, handlerScript);
- }
-
- String queueId = getQueueId(component);
- if (isNotEmpty(queueId)) {
- ajaxEventOptions.set(QUEUE_ID_ATTRIBUTE, queueId);
- }
-
- ajaxEventOptions.set("incId", "1");
- }
-
-// public static AjaxEventOptions buildEventOptions(FacesContext facesContext,
-// UIComponent uiComponent, Map<String, Object> params) {
-//
-// return buildEventOptions(facesContext, uiComponent, params, false);
-// }
-
- /**
- * @param facesContext
- * @param uiComponent
- * @return
- */
-// public static Map<String, Object> buildEventOptions(FacesContext facesContext,
-// UIComponent uiComponent, Map<String, Object> params, boolean omitDefaultActionUrl) {
-// String clientId = uiComponent.getClientId(facesContext);
-// Map<String, Object> componentAttributes = uiComponent.getAttributes();
-// Map<String, Object> options = new HashMap<String, Object>();
-//
-// UIComponent nestingContainer = (UIComponent) findAjaxContainer(
-// facesContext, uiComponent);
-// String containerClientId = nestingContainer.getClientId(facesContext);
-// if (containerClientId != null && !AjaxViewRoot.ROOT_ID.equals(containerClientId)) {
-// options.put("containerId", containerClientId);
-// }
-//
-// Map<String, Object> parameters = new HashMap<String, Object>();
-// UIComponent targetComponent = (uiComponent instanceof AjaxSupport)?uiComponent.getParent():uiComponent;
-// // UIForm form = getNestingForm(uiComponent);
-// // "input" - if assigned to html input element.
-// boolean input = targetComponent instanceof EditableValueHolder;
-// // Action component - button etc.
-//// boolean action = targetComponent instanceof ActionSource;
-//
-// boolean ajaxSingle = Boolean.TRUE.equals(componentAttributes
-// .get(AJAX_SINGLE_ATTR));
-// // For input components in single mode or without form submit input
-// // control )
-// if (ajaxSingle ) {
-// parameters.put(AJAX_SINGLE_PARAMETER_NAME, targetComponent.getClientId(facesContext));
-// // options.put("single", JSReference.TRUE);
-// if (input) {
-// options.put("control", JSReference.THIS);
-// }
-// }
-// // Control value for submit
-// String controlName;
-// Object controlValue;
-// // TODO - make compatible with JSF RI/MyFaces ? use submittedValue ( if
-// // any ) for UIInput, converted value for ValueHolder.
-// controlName = clientId;
-// controlValue = clientId;
-// parameters.put(controlName, controlValue);
-// AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
-//
-// String ajaxActionURL = ajaxContext.getAjaxActionURL(facesContext);
-// if (omitDefaultActionUrl) {
-// UIComponent form = getNestingForm(uiComponent);
-// if (form != null && !RENDERER_UTILS.isBooleanAttribute(form, "ajaxSubmit")) {
-// if (RENDERER_UTILS.getActionUrl(facesContext).equals(ajaxActionURL)) {
-// ajaxActionURL = null;
-// }
-// }
-// }
-//
-// if (ajaxActionURL != null) {
-// // Setup action URL. For portlet environment, it will be different from
-// // page.
-// options.put("actionUrl", ajaxActionURL);
-// }
-//
-// // Add application-wide Ajax parameters
-// parameters.putAll(ajaxContext.getCommonAjaxParameters());
-// // add child parameters
-// appendParameters(facesContext, uiComponent, parameters);
-//
-// if (params != null) {
-// parameters.putAll(params);
-// }
-//
-// if (!parameters.isEmpty()) {
-// options.put("parameters", parameters);
-// }
-// // parameter to render only current list of areas.
-//// if (isAjaxLimitToList(uiComponent)) {
-//// Set<? extends Object> ajaxAreas = getAjaxAreas(uiComponent);
-//// Set<String> areasIds = new HashSet<String>();
-//// if (null != ajaxAreas) {
-//// for (Iterator<? extends Object> iter = ajaxAreas.iterator(); iter.hasNext();) {
-//// String id = (String) iter.next();
-//// UIComponent comp = RendererUtils.getInstance().
-//// findComponentFor(uiComponent, id);
-//// if (null != comp) {
-//// areasIds.add(comp.getClientId(facesContext));
-//// } else {
-//// areasIds.add(id);
-//// }
-//// }
-//// }
-//// options.put("affected", areasIds);
-//// }
-// String oncomplete = getAjaxOncomplete(uiComponent);
-// if (null != oncomplete) {
-// options.put(ONCOMPLETE_ATTR_NAME, buildAjaxOncomplete(oncomplete));
-// }
-//
-// String beforeupdate = getAjaxOnBeforeDomUpdate(uiComponent);
-// if (null != beforeupdate) {
-// options.put(ONBEFOREDOMUPDATE_ATTR_NAME, buildAjaxOnBeforeDomUpdate(beforeupdate));
-// }
-//
-//
-// String status = getAjaxStatus(uiComponent);
-// if (null != status) {
-// options.put("status", status);
-// }
-// String queue = (String) componentAttributes.get(AJAX_QUEUE_ATTR);
-// String implicitQueue = null;
-//
-// Integer requestDelay = (Integer) componentAttributes
-// .get(AJAX_DELAY_ATTR);
-// if (null != requestDelay && requestDelay.intValue() > 0) {
-// options.put(AJAX_DELAY_ATTR, requestDelay);
-// if (null == queue) {
-// implicitQueue = clientId;
-// }
-// }
-// Boolean ignoreDupResponses = (Boolean) componentAttributes
-// .get(AJAX_ABORT_ATTR);
-// if (null != ignoreDupResponses && ignoreDupResponses.booleanValue()) {
-// options.put(AJAX_ABORT_ATTR, JSReference.TRUE);
-// if (null == queue) {
-// implicitQueue = clientId;
-// }
-// }
-//
-// if (null != queue) {
-// options.put(AJAX_QUEUE_ATTR, queue);
-// } else if (implicitQueue != null) {
-// options.put("implicitEventsQueue", clientId);
-// }
-//
-// ExternalContext externalContext = facesContext.getExternalContext();
-// String namespace = externalContext.encodeNamespace("");
-// if (namespace != null && namespace.length() != 0) {
-// options.put("namespace", namespace);
-// }
-//
-// String similarityGroupingId = (String) componentAttributes.get(SIMILARITY_GROUPING_ID_ATTR);
-// if (similarityGroupingId == null || similarityGroupingId.length() == 0) {
-// similarityGroupingId = clientId;
-// } else {
-// similarityGroupingId = externalContext.encodeNamespace(similarityGroupingId);
-// }
-//
-// options.put(SIMILARITY_GROUPING_ID_ATTR, similarityGroupingId);
-//
-// // request timeout.
-// Integer timeout = (Integer) componentAttributes.get("timeout");
-// if (null != timeout && timeout.intValue() > 0) {
-// options.put("timeout", timeout);
-// }
-// // Encoding for requests
-// String encoding = (String) componentAttributes.get("encoding");
-// if (null != encoding) {
-// options.put("encoding", encoding);
-// }
-// return options;
-// }
-// /**
-// * Create call to Ajax Submit function with first two parameters
-// *
-// * @param uiComponent
-// * @param facesContext
-// * @param functionName
-// * @return
-// */
-// public static JSFunction buildAjaxFunction(UIComponent uiComponent,
-// FacesContext facesContext) {
-// JSFunction ajaxFunction = buildAjaxFunction(uiComponent, facesContext,
-// AJAX_FUNCTION_NAME);
-// // client-side script must have reference to event-enabled object.
-// ajaxFunction.addParameter(new JSReference("event"));
-// return ajaxFunction;
-// }
-
- /**
- * Create call to Ajax Submit function with first two parameters
- *
- * @param facesContext
- * @param uiComponent
- * @param functionName
- * @return
- */
- public static JSFunction buildAjaxFunction(FacesContext facesContext, UIComponent uiComponent,
- String functionName) {
- JSFunction ajaxFunction = new JSFunction(functionName);
-
- ajaxFunction.addParameter(uiComponent.getClientId(facesContext));
- ajaxFunction.addParameter(JSReference.EVENT);
-
- return ajaxFunction;
- }
-
- /**
- * Append common parameters ( array of affected areas, status area id, on
- * complete function ) to JavaScript event string.
- *
- * @param uiComponent
- * @param onClick -
- * buffer with JavaScript code eg... AJAX.Submit(form,this
- */
-
- // public static void appendAjaxSubmitParameters(FacesContext facesContext,
- // UIComponent uiComponent, StringBuffer onClick)
- // {
- // Set ajaxAreas = getAjaxAreas(uiComponent);
- // onClick.append(',');
- // // parameter to render only current list of areas.
- // if (isAjaxLimitToList(uiComponent) && ajaxAreas != null &&
- // ajaxAreas.size() > 0)
- // {
- // onClick.append('[');
- // Iterator areas = ajaxAreas.iterator();
- // boolean first = true;
- // while (areas.hasNext())
- // {
- // String element = (String) areas.next();
- // UIComponent component = uiComponent.findComponent(element);
- // if (null != component)
- // {
- // if (!first)
- // {
- // onClick.append(',');
- // }
- // else
- // {
- // first = false;
- // }
- // onClick.append('\'');
- // onClick.append(component.getClientId(facesContext));
- // onClick.append('\'');
- // }
- // }
- // onClick.append("]");
- // }
- // else
- // {
- // onClick.append("null");
- // }
- // // insert id of request status element.
- // onClick.append(',');
- // String status = getAjaxStatus(uiComponent);
- // if (null != status)
- // {
- // onClick.append('\'').append(status).append('\'');
- // }
- // else
- // {
- // onClick.append("null");
- // }
- // // insert function name for call after completed request
- // onClick.append(',');
- // String oncomplete = getAjaxOncomplete(uiComponent);
- // if (null != oncomplete)
- // {
- // onClick.append(oncomplete);
- // }
- // else
- // {
- // onClick.append("null");
- // }
- //
- // }
-
- /**
- * Get list of clientId's for given component
- *
- * @param uiComponent
- * @return List of areas Id's , updated by this component.
- */
- public static Set<String> getAjaxAreas(UIComponent uiComponent) {
- Object areas;
-
- if (uiComponent instanceof AjaxComponent) {
- areas = ((AjaxComponent) uiComponent).getReRender();
- } else {
- areas = uiComponent.getAttributes().get(AjaxRendererUtils.AJAX_REGIONS_ATTRIBUTE);
- }
-
- return asSet(areas);
- }
-
- /**
- * Returns set of areas to be processed as a result of this component action invocation
- *
- * @param component
- * @return set of IDs that should be processed as a
- * @since 3.3.0
- */
- public static Set<String> getAjaxAreasToProcess(UIComponent component) {
- Object areas;
-
- if (component instanceof AjaxComponent) {
- areas = ((AjaxComponent) component).getProcess();
- } else {
- areas = component.getAttributes().get(AjaxRendererUtils.AJAX_PROCESS_ATTRIBUTE);
- }
-
- return asSet(areas);
- }
-
- /**
- * Split parameter string into array of strings.
- * @param valuesSet
- * @return
- */
- public static String[] asArray(String valuesSet) {
- return IdSplitBuilder.split(valuesSet);
- }
-
- /**
- * Convert parameter ( Collection, List, array, String, comma-separated
- * String, whitespace-separate String) to set of strings.
- *
- * @param valueToSet -
- * object for conversion to Set.
- * @return - set of strings.
- */
- @SuppressWarnings("unchecked")
- public static Set<String> asSet(Object valueToSet) {
- if (null != valueToSet) {
-
- // Simplest case - set.
- if (valueToSet instanceof Set) {
- return new LinkedHashSet<String>((Set<String>) valueToSet);
- } else if (valueToSet instanceof Collection) { // Other collections.
- return new LinkedHashSet<String>((Collection<String>) valueToSet);
- } else if (OBJECT_ARRAY_CLASS.isAssignableFrom(valueToSet.getClass())) { // Array
- return new LinkedHashSet<String>(Arrays.asList((String[]) valueToSet));
- } else if (valueToSet instanceof String) { // Tokenize string.
- String areasString = ((String) valueToSet).trim();
-
- if (areasString.contains(",") || areasString.contains(" ")) {
- String[] values = asArray(areasString);
- Set<String> result = new LinkedHashSet<String>(values.length);
- for (String value : values) {
- result.add(value);
- }
-
- return result;
- } else {
- Set<String> areasSet = new LinkedHashSet<String>(5);
-
- areasSet.add(areasString);
-
- return areasSet;
- }
- }
- }
-
- return null;
- }
-
- /**
- * Get status area Id for given component.
- *
- * @param component
- * @return clientId of status area, or <code>null</code>
- */
- public static String getAjaxStatus(UIComponent component) {
- String statusId;
-
- if (component instanceof AjaxComponent) {
- statusId = ((AjaxComponent) component).getStatus();
- } else {
- statusId = (String) component.getAttributes().get(STATUS_ATTR_NAME);
- }
-
- return statusId;
-
-// if (null != statusId) {
-// UIComponent status = RendererUtils.getInstance().
-// findComponentFor(component, statusId);
-//
-// if (null != status) {
-// statusId = status
-// .getClientId(FacesContext.getCurrentInstance());
-// } else {
-// LOG.warn(Messages.getMessage(
-// Messages.AJAX_STATUS_COMPONENT_NOT_FOWND_WARNING,
-// component.getId()));
-// }
-// }
-// return statusId;
- }
-
- public static String getQueueId(UIComponent component) {
- return (String) component.getAttributes().get(QUEUE_ID_ATTRIBUTE);
- }
-
- public static JSFunctionDefinition buildAjaxOncomplete(String body) {
- JSFunctionDefinition function = new JSFunctionDefinition("request", "event", "data");
-
- function.addToBody(body);
-
- return function;
- }
-
- public static JSFunctionDefinition buildAjaxOnBeforeDomUpdate(String body) {
- JSFunctionDefinition function = new JSFunctionDefinition("request", "event", "data");
-
- function.addToBody(body);
-
- return function;
- }
-
- /**
- * Get function name for call on completed ajax request.
- *
- * @param component for wich calculate function name
- * @return name of JavaScript function or <code>null</code>
- */
- //TODO nick - refactor - remove this method?
- public static String getAjaxOncomplete(UIComponent component) {
- if (component instanceof AjaxComponent) {
- return ((AjaxComponent) component).getOncomplete();
- }
-
- return (String) component.getAttributes().get(ONCOMPLETE_ATTR_NAME);
- }
-
- /**
- * Get function name for call before update DOM.
- *
- * @param component for wich calculate function name
- * @return name of JavaScript function or <code>null</code>
- */
- //TODO nick - refactor - remove this method?
- public static String getAjaxOnBeforeDomUpdate(UIComponent component) {
- if (component instanceof AjaxComponent) {
- return ((AjaxComponent) component).getOnbeforedomupdate();
- }
-
- return (String) component.getAttributes().get(ONBEFOREDOMUPDATE_ATTR_NAME);
- }
-
- //TODO nick - refactor - remove this method?
- public static String getAjaxOnBegin(UIComponent component) {
- if (component instanceof AjaxComponent) {
- return ((AjaxComponent) component).getOnbegin();
- }
-
- return (String) component.getAttributes().get(ONBEGIN_ATTR_NAME);
- }
-
- /**
- * @param component
- * @return
- * @since 4.0
- */
- public static Object getAjaxData(UIComponent component) {
- if (component instanceof AjaxComponent) {
- return ((AjaxComponent) component).getData();
- }
-
- return component.getAttributes().get(DATA_ATTR_NAME);
- }
-
- /**
- * Calculate, must be component render only given areas, or all sended from
- * server.
- *
- * @param component
- * @return <code>true</code> if client must render ONLY given areas.
- */
- public static boolean isAjaxLimitRender(UIComponent component) {
- boolean result = false;
-
- if (component instanceof AjaxComponent) {
- result = ((AjaxComponent) component).isLimitRender();
- } else {
- try {
- result = ((Boolean) component.getAttributes().get(LIMITRENDER_ATTR_NAME)).booleanValue();
- } catch (NullPointerException e) {
-
- // NullPointer - ignore ...
- } catch (ClassCastException e1) {
-
- // not Boolean - false ...
- }
- }
-
- return result;
- }
-
- /**
- * Replacement for buggy in MyFaces <code>RendererUtils</code>
- *
- * @param component
- * @return
- */
- public static String getAbsoluteId(UIComponent component) {
- if (component == null) {
- throw new NullPointerException(Messages.getMessage(Messages.COMPONENT_NULL_ERROR_2));
- }
-
- StringBuffer idBuf = new StringBuffer();
-
- idBuf.append(component.getId());
-
- UIComponent parent = component;
-
- while ((parent = parent.getParent()) != null) {
- if (parent instanceof NamingContainer) {
- idBuf.insert(0, NamingContainer.SEPARATOR_CHAR);
- idBuf.insert(0, parent.getId());
- }
- }
-
- idBuf.insert(0, NamingContainer.SEPARATOR_CHAR);
- LOG.debug(Messages.getMessage(Messages.CALCULATE_COMPONENT_ID_INFO, component.getId(), idBuf.toString()));
-
- return idBuf.toString();
- }
-
- /**
- * Find nested form for given component
- *
- * @param component
- * @return nested <code>UIForm</code> component, or <code>null</code>
- */
- public static UIComponent getNestingForm(UIComponent component) {
- UIComponent parent = component;
-
- // Search enclosed UIForm or ADF UIXForm component
- while ((parent != null) && !(parent instanceof UIForm)
- && !("org.apache.myfaces.trinidad.Form".equals(parent.getFamily()))
- && !("oracle.adf.Form".equals(parent.getFamily()))) {
- parent = parent.getParent();
- }
-
- return parent;
- }
-
- protected static String getAjaxActionUrl(FacesContext facesContext) {
- return AjaxContext.getCurrentInstance(facesContext).getAjaxActionURL(facesContext);
- }
-
-// /**
-// * Encode rendered areas as special HTML tag ( span in current release )
-// *
-// * @param context
-// * @param component
-// * @throws IOException
-// */
-// public static void encodeAreas(FacesContext context, UIComponent component) throws IOException {
-// AjaxContext ajaxContext = AjaxContext.getCurrentInstance(context);
-// ExternalContext externalContext = context.getExternalContext();
-// Map<String, Object> requestMap = externalContext.getRequestMap();
-// Set<String> rendered = ajaxContext.getAjaxRenderedAreas();
-//
-// // write special area for list of rendered elements. Client-side
-// // Java
-// // Script
-// // read this structure for update areas of DOM tree.
-// ResponseWriter out = context.getResponseWriter();
-//
-// // Create <span> element to keep list rendered aread ( in title
-// // attribute )
-// // More right will create special namespace for such
-// // information,
-// // but I want to keep simple html ( xhtml ) document - on case
-// // I have troubles with microsoft XMLHTTP validations.
-// out.startElement(AjaxContainerRenderer.AJAX_RESULT_GROUP_TAG, component);
-// out.writeAttribute(HTML.NAME_ATTRIBUTE, AjaxContainerRenderer.AJAX_UPDATE_HEADER, null);
-//
-// StringBuffer senderString = new StringBuffer();
-//
-// for (Iterator<String> it = rendered.iterator(); it.hasNext();) {
-// String id = it.next();
-//
-// senderString.append(id);
-//
-// if (it.hasNext()) {
-// senderString.append(',');
-// }
-// }
-//
-// out.writeAttribute(AjaxContainerRenderer.AJAX_RESULT_GROUP_ATTR, senderString, null);
-// out.endElement(AjaxContainerRenderer.AJAX_RESULT_GROUP_TAG);
-//
-// // For sequences and client-saved states.
-// out.startElement(AjaxContainerRenderer.AJAX_VIEW_STATE_TAG, component);
-// out.writeAttribute(HTML.ID_ATTRIBUTE, AjaxContainerRenderer.AJAX_VIEW_STATE_ID, null);
-// writeState(context);
-// out.endElement(AjaxContainerRenderer.AJAX_VIEW_STATE_TAG);
-//
-// // Write rendered flag to html <meta>
-// out.startElement(AjaxContainerRenderer.AJAX_RESULT_GROUP_TAG, component);
-// out.writeAttribute(HTML.ID_ATTRIBUTE, AjaxContainerRenderer.AJAX_FLAG_HEADER, null);
-// out.writeAttribute(HTML.NAME_ATTRIBUTE, AjaxContainerRenderer.AJAX_FLAG_HEADER, null);
-// out.writeAttribute(AjaxContainerRenderer.AJAX_RESULT_GROUP_ATTR, "true", null);
-// out.endElement(AjaxContainerRenderer.AJAX_RESULT_GROUP_TAG);
-//
-// // set response header with list of rendered ID's
-// Object response = externalContext.getResponse();
-//
-// // Use reflection for send responce headers - we can get
-// // different responces classes
-// // for different environment ( portal, cocoon etc )
-// if (response instanceof HttpServletResponse) {
-// HttpServletResponse httpResponse = (HttpServletResponse) response;
-//
-// httpResponse.setHeader(AjaxContainerRenderer.AJAX_FLAG_HEADER, "true");
-// } else {
-// try {
-// Method setHeadergMethod = response.getClass().getMethod("setHeader",
-// new Class[]{String.class, String.class});
-//
-// setHeadergMethod.invoke(response, AjaxContainerRenderer.AJAX_FLAG_HEADER, "true");
-// } catch (Exception e) {
-// LOG.error(Messages.getMessage(Messages.DETECTING_ENCODING_DISABLED_ERROR));
-// LOG.error(Messages.getMessage(Messages.OBTAIN_RESPONSE_SET_HEADER_ERROR, e));
-// }
-// }
-//
-// Map<String, Object> responseDataMap = ajaxContext.getResponseComponentDataMap();
-//
-// // Get data serializer instance
-// AJAXDataSerializer serializer = ServiceTracker.getService(context, AJAXDataSerializer.class);
-//
-// // Put data to JavaScript handlers, inside <span> elements.
-// for (Map.Entry<String, Object> entry : responseDataMap.entrySet()) {
-// out.startElement(HTML.SPAN_ELEM, component);
-// out.writeAttribute(HTML.ID_ATTRIBUTE, entry.getKey(), null);
-//
-// String dataString = serializer.asString(entry.getValue());
-//
-// out.write(dataString);
-// out.endElement(HTML.SPAN_ELEM);
-// }
-//
-// // Include active 'oncomplete' function content :
-// Object oncomplete = ajaxContext.getOncomplete();
-//
-// if (null != oncomplete) {
-// out.startElement(HTML.SPAN_ELEM, component);
-// out.writeAttribute(HTML.ID_ATTRIBUTE, ONCOMPLETE_CONTENT_ID, null);
-// out.writeText(oncomplete, null);
-// out.endElement(HTML.SPAN_ELEM);
-// }
-//
-// // For self-rendered case, we use own methods for replace stateKey by
-// // real value in XML filter.
-// // if(ajaxContext.isSelfRender()){
-// // saveViewState(context, out);
-// // }
-// requestMap.put(AJAX_AREAS_RENDERED, "true");
-// }
-
- /**
- * Write state saving markers to context, include MyFaces view sequence.
- *
- * @param context
- * @throws IOException
- */
- public static void writeState(FacesContext context) throws IOException {
- context.getApplication().getViewHandler().writeState(context);
- }
-
-// /**
-// * Encode declaration for AJAX response. Render <html><body>
-// *
-// * @param context
-// * @param component
-// * @throws IOException
-// */
-// public static void encodeAjaxBegin(FacesContext context, UIComponent component) throws IOException {
-//
-// // AjaxContainer ajax = (AjaxContainer) component;
-// ResponseWriter out = context.getResponseWriter();
-//
-// // DebugUtils.traceView("ViewRoot in AJAX Page encode begin");
-// out.startElement("html", component);
-//
-// Locale locale = context.getViewRoot().getLocale();
-//
-// out.writeAttribute(HTML.LANG_ATTRIBUTE, locale.toString(), "lang");
-// out.startElement("body", component);
-// }
-//
-// /**
-// * End encoding of AJAX response. Render tag with included areas and close
-// * </body></html>
-// *
-// * @param context
-// * @param component
-// * @throws IOException
-// */
-// public static void encodeAjaxEnd(FacesContext context, UIComponent component) throws IOException {
-//
-// // AjaxContainer ajax = (AjaxContainer) component;
-// ResponseWriter out = context.getResponseWriter();
-//
-// // DebugUtils.traceView("ViewRoot in AJAX Page encode begin");
-// encodeAreas(context, component);
-// out.endElement("body");
-// out.endElement("html");
-// }
-
- /**
- * @param facesContext
- * @return
- */
- public static boolean isAjaxRequest(FacesContext facesContext) {
- return AjaxContext.getCurrentInstance(facesContext).isAjaxRequest();
- }
-
- /**
- * TODO: add deprecation
- *
- * @param facesContext
- * @param component
- * @param id
- */
- public static void addRegionByName(FacesContext facesContext, UIComponent component, String id) {
- AjaxContext.getCurrentInstance(facesContext).addComponentToAjaxRender(component, id);
- }
-
- /**
- * @param facesContext
- * @param component
- */
- public static void addRegionsFromComponent(UIComponent component, FacesContext facesContext) {
- AjaxContext.getCurrentInstance(facesContext).addRegionsFromComponent(component);
- }
-
- private static void startExtensionElementIfNecessary(
- PartialResponseWriter partialResponseWriter,
- Map<String, String> attributes,
- boolean[] writingState) throws IOException {
-
- if (!writingState[0]) {
- writingState[0] = true;
-
- partialResponseWriter.startExtension(attributes);
- }
- }
-
- private static void endExtensionElementIfNecessary(
- PartialResponseWriter partialResponseWriter,
- boolean[] writingState) throws IOException {
-
- if (writingState[0]) {
- writingState[0] = false;
-
- partialResponseWriter.endExtension();
- }
- }
-
- public static void renderAjaxExtensions(FacesContext facesContext, UIComponent component) throws IOException {
- AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
-
- Map<String, String> attributes = Collections.singletonMap(HTML.ID_ATTRIBUTE,
- facesContext.getExternalContext().encodeNamespace(EXTENSION_ID));
- PartialResponseWriter writer = facesContext.getPartialViewContext().getPartialResponseWriter();
- boolean[] writingState = new boolean[]{false};
-
- Object onbeforedomupdate = ajaxContext.getOnbeforedomupdate();
- if (onbeforedomupdate != null) {
- String string = onbeforedomupdate.toString();
- if (string.length() != 0) {
- startExtensionElementIfNecessary(writer, attributes, writingState);
- writer.startElement(BEFOREDOMUPDATE_ELEMENT_NAME, component);
- writer.writeText(onbeforedomupdate, null);
- writer.endElement(BEFOREDOMUPDATE_ELEMENT_NAME);
- }
- }
-
- Object oncomplete = ajaxContext.getOncomplete();
- if (oncomplete != null) {
- String string = oncomplete.toString();
- if (string.length() != 0) {
- startExtensionElementIfNecessary(writer, attributes, writingState);
- writer.startElement(COMPLETE_ELEMENT_NAME, component);
- writer.writeText(oncomplete, null);
- writer.endElement(COMPLETE_ELEMENT_NAME);
- }
- }
-
- Object responseData = ajaxContext.getResponseData();
- if (responseData != null) {
- startExtensionElementIfNecessary(writer, attributes, writingState);
- writer.startElement(DATA_ELEMENT_NAME, component);
-
- AJAXDataSerializer serializer = ServiceTracker.getService(facesContext, AJAXDataSerializer.class);
- writer.writeText(serializer.asString(responseData), null);
-
- writer.endElement(DATA_ELEMENT_NAME);
- }
-
- Map<String, Object> responseComponentDataMap = ajaxContext.getResponseComponentDataMap();
- if (responseComponentDataMap != null && !responseComponentDataMap.isEmpty()) {
- startExtensionElementIfNecessary(writer, attributes, writingState);
- writer.startElement(COMPONENT_DATA_ELEMENT_NAME, component);
-
- AJAXDataSerializer serializer = ServiceTracker.getService(facesContext, AJAXDataSerializer.class);
- writer.writeText(serializer.asString(responseComponentDataMap), null);
-
- writer.endElement(COMPONENT_DATA_ELEMENT_NAME);
- }
-
- endExtensionElementIfNecessary(writer, writingState);
-
- }
-
-}
Deleted: trunk/core/impl/src/main/java/org/richfaces/renderkit/util/IdSplitBuilder.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/renderkit/util/IdSplitBuilder.java 2010-09-08 17:07:06 UTC (rev 19136)
+++ trunk/core/impl/src/main/java/org/richfaces/renderkit/util/IdSplitBuilder.java 2010-09-08 19:14:49 UTC (rev 19137)
@@ -1,150 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.richfaces.renderkit.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author Nick Belaevski
- */
-final class IdSplitBuilder {
-
- private static final int INITIAL_SPLIT_LIST_SIZE = 3;
-
- private enum State {
- IN_ID (true) {
-
- @Override
- public State getNextState(char c) {
- if (c == '[') {
- return State.IN_ID_INSIDE_BRACKETS;
- } else if (isSeparator(c)) {
- return State.OUTSIDE_ID;
- } else {
- return this;
- }
- }
- },
- IN_ID_INSIDE_BRACKETS (true) {
-
- @Override
- public State getNextState(char c) {
- if (c == ']') {
- return State.IN_ID;
- } else {
- return this;
- }
- }
- },
- OUTSIDE_ID (false) {
-
- @Override
- public State getNextState(char c) {
- if (!isSeparator(c)) {
- if (c == '[') {
- return State.IN_ID_INSIDE_BRACKETS;
- } else {
- return State.IN_ID;
- }
- }
-
- return this;
- }
- };
-
- private final boolean idSegment;
-
- private State(boolean idSegment) {
- this.idSegment = idSegment;
- }
-
- private static boolean isSeparator(char c) {
- return c == ',' || Character.isWhitespace(c);
- }
-
- public abstract State getNextState(char c);
-
- public boolean isIdSegment() {
- return idSegment;
- }
-
- public void processChar(IdSplitBuilder builder, char c, int charIdx) {
- State nextState = getNextState(c);
-
- if (nextState.isIdSegment() ^ isIdSegment()) {
- if (nextState.isIdSegment()) {
- builder.setStartIndex(charIdx);
- } else {
- builder.flushBuilder(charIdx);
- builder.setStartIndex(-1);
- }
- }
-
- builder.state = nextState;
- }
- }
-
- private int startIdx = -1;
-
- private String sourceString;
-
- private List<String> result = new ArrayList<String>(INITIAL_SPLIT_LIST_SIZE);
-
- private State state = State.OUTSIDE_ID;
-
- private IdSplitBuilder(String sourceString) {
- super();
- this.sourceString = sourceString;
- }
-
- private void setStartIndex(int idx) {
- startIdx = idx;
- }
-
- private void flushBuilder(int endIdx) {
- if (startIdx >= 0 && endIdx > startIdx) {
- String id = sourceString.substring(startIdx, endIdx);
- result.add(id);
- }
- }
-
- private void build() {
- int length = sourceString.length();
- for (int i = 0; i < length; i++) {
- char c = sourceString.charAt(i);
- state.processChar(this, c, i);
- }
- flushBuilder(length);
- }
-
- private String[] getSplit() {
- return result.toArray(new String[result.size()]);
- }
-
- public static String[] split(String s) {
- IdSplitBuilder splitBuilder = new IdSplitBuilder(s);
- splitBuilder.build();
- return splitBuilder.getSplit();
- }
-
-}
\ No newline at end of file
Deleted: trunk/core/impl/src/main/java/org/richfaces/renderkit/util/RendererUtils.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/renderkit/util/RendererUtils.java 2010-09-08 17:07:06 UTC (rev 19136)
+++ trunk/core/impl/src/main/java/org/richfaces/renderkit/util/RendererUtils.java 2010-09-08 19:14:49 UTC (rev 19137)
@@ -1,1314 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-package org.richfaces.renderkit.util;
-
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.faces.FacesException;
-import javax.faces.application.ViewHandler;
-import javax.faces.component.EditableValueHolder;
-import javax.faces.component.NamingContainer;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIForm;
-import javax.faces.component.UIParameter;
-import javax.faces.component.UIViewRoot;
-import javax.faces.component.ValueHolder;
-import javax.faces.component.behavior.ClientBehaviorContext.Parameter;
-import javax.faces.component.behavior.ClientBehaviorHolder;
-import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
-import javax.faces.convert.Converter;
-
-import org.ajax4jsf.Messages;
-import org.ajax4jsf.component.JavaScriptParameter;
-import org.ajax4jsf.javascript.JSEncoder;
-import org.ajax4jsf.javascript.JSFunctionDefinition;
-import org.ajax4jsf.javascript.JSReference;
-import org.ajax4jsf.util.HtmlDimensions;
-import org.richfaces.context.ComponentIdResolver;
-import org.richfaces.renderkit.HandlersChain;
-
-/**
- * Util class for common render operations - render passthru html attributes,
- * iterate over child components etc.
- *
- * @author asmirnov(a)exadel.com (latest modification by $Author: alexsmirnov $)
- * @version $Revision: 1.1.2.6 $ $Date: 2007/02/08 19:07:16 $
- *
- */
-public class RendererUtils {
-
- public static final String DUMMY_FORM_ID = ":_form";
-
- // we'd better use this instance multithreadly quickly
- private static final RendererUtils INSTANCE = new RendererUtils();
-
- /**
- * Substitutions for components properies names and HTML attributes names.
- */
- private static final Map<String, String> SUBSTITUTIONS = new HashMap<String, String>();
-
- private static final Set<String> REQUIRED_ATTRIBUTES = new HashSet<String>();
-
- static {
- SUBSTITUTIONS.put(HTML.CLASS_ATTRIBUTE, "styleClass");
-
- REQUIRED_ATTRIBUTES.add(HTML.ALT_ATTRIBUTE);
-
- Arrays.sort(HTML.PASS_THRU);
- Arrays.sort(HTML.PASS_THRU_EVENTS);
- Arrays.sort(HTML.PASS_THRU_BOOLEAN);
- Arrays.sort(HTML.PASS_THRU_URI);
- }
-
- // can be created by subclasses;
- // administratively restricted to be created by package members ;)
- protected RendererUtils() {
- super();
- }
-
- /**
- * Wrapper class around object value used to transform values into particular JS objects
- *
- * @author Nick Belaevski
- * @since 3.3.2
- */
- public static enum ScriptHashVariableWrapper {
-
- /**
- * No-op default wrapper
- */
- DEFAULT {
- @Override
- Object wrap(Object o) {
- return o;
- }
- },
-
- /**
- * Event handler functions wrapper. Wraps <pre>functionCode</pre> object into:
- * <pre>function(event) {
- * functionCode
- * }</pre>
- */
- EVENT_HANDLER {
- @Override
- Object wrap(Object o) {
- return new JSFunctionDefinition("event").addToBody(o);
- }
- };
-
- /**
- * Method that does the wrapping
- *
- * @param o object to wrap
- * @return wrapped object
- */
- abstract Object wrap(Object o);
- }
-
- /**
- * Use this method to get singleton instance of RendererUtils
- * @return singleton instance
- */
- public static RendererUtils getInstance() {
- return INSTANCE;
- }
-
- /**
- * Encode id attribute with clientId component property
- *
- * @param context
- * @param component
- * @throws IOException
- */
- public void encodeId(FacesContext context, UIComponent component) throws IOException {
- encodeId(context, component, HTML.ID_ATTRIBUTE);
- }
-
- /**
- * Encode clientId to custom attribute ( for example, to control name )
- *
- * @param context
- * @param component
- * @param attribute
- * @throws IOException
- */
- public void encodeId(FacesContext context, UIComponent component, String attribute) throws IOException {
- String clientId = null;
-
- try {
- clientId = component.getClientId(context);
- } catch (Exception e) {
-
- // just ignore if clientId wasn't inited yet
- }
-
- if (null != clientId) {
- context.getResponseWriter().writeAttribute(attribute, clientId,
- (String) getComponentAttributeName(attribute));
- }
- }
-
- /**
- * Encode id attribute with clientId component property. Encoded only if id
- * not auto generated.
- *
- * @param context
- * @param component
- * @throws IOException
- */
- public void encodeCustomId(FacesContext context, UIComponent component) throws IOException {
- if (hasExplicitId(component)) {
- context.getResponseWriter().writeAttribute(HTML.ID_ATTRIBUTE, component.getClientId(context),
- HTML.ID_ATTRIBUTE);
- }
- }
-
- public Map<String, Object> createParametersMap(FacesContext context, UIComponent component) {
- Map<String, Object> parameters = new LinkedHashMap<String, Object>();
-
- if (component.getChildCount() > 0) {
- for (UIComponent child : component.getChildren()) {
- if (child instanceof UIParameter) {
- UIParameter parameter = (UIParameter) child;
- String name = parameter.getName();
- Object value = parameter.getValue();
-
- if (null == name) {
- throw new IllegalArgumentException(Messages.getMessage(Messages.UNNAMED_PARAMETER_ERROR,
- component.getClientId(context)));
- }
-
- boolean escape = true;
-
- if (child instanceof JavaScriptParameter) {
- JavaScriptParameter actionParam = (JavaScriptParameter) child;
-
- escape = !actionParam.isNoEscape();
- }
-
- if (escape) {
- if (value == null) {
- value = "";
- }
- } else {
- value = new JSReference(value.toString());
-
- // if(it.hasNext()){onEvent.append(',');};
- // renderAjaxLinkParameter( name,
- // value, onClick, jsForm, nestingForm);
- }
-
- parameters.put(name, value);
- }
- }
- }
-
- return parameters;
- }
-
- private void encodeBehaviors(FacesContext context, ClientBehaviorHolder behaviorHolder,
- String defaultHtmlEventName, String[] attributesExclusions)
- throws IOException {
-
-// if (attributesExclusions != null && attributesExclusions.length != 0) {
-// assert false : "Not supported yet";
-// }
- // TODO: disabled component check
- String defaultEventName = behaviorHolder.getDefaultEventName();
- Collection<String> eventNames = behaviorHolder.getEventNames();
-
- if (eventNames != null) {
- UIComponent component = (UIComponent) behaviorHolder;
- ResponseWriter writer = context.getResponseWriter();
- Collection<Parameter> parametersList = HandlersChain.createParametersList(createParametersMap(context,
- component));
-
- for (String behaviorEventName : eventNames) {
- if (behaviorEventName.equals(defaultEventName)) {
- continue;
- }
-
- String htmlEventName = "on" + behaviorEventName;
-
- if ((attributesExclusions == null) || (Arrays.binarySearch(attributesExclusions, htmlEventName) < 0)) {
- HandlersChain handlersChain = new HandlersChain(context, component, parametersList);
-
- handlersChain.addInlineHandlerFromAttribute(htmlEventName);
- handlersChain.addBehaviors(behaviorEventName);
-
- String handlerScript = handlersChain.toScript();
-
- if (!isEmpty(handlerScript)) {
- writer.writeAttribute(htmlEventName, handlerScript, htmlEventName);
- }
- }
- }
- }
- }
-
- /**
- * Encode common pass-thru html attributes.
- *
- * @param context
- * @param component
- * @throws IOException
- */
- public void encodePassThru(FacesContext context, UIComponent component, String defaultHtmlEvent)
- throws IOException {
-
- encodeAttributesFromArray(context, component, HTML.PASS_THRU);
-
- if (component instanceof ClientBehaviorHolder) {
- ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
-
- encodeBehaviors(context, clientBehaviorHolder, defaultHtmlEvent, null);
- } else {
- encodeAttributesFromArray(context, component, HTML.PASS_THRU_EVENTS);
- }
- }
-
- /**
- * Encode pass-through attributes except specified ones
- *
- * @param context
- * @param component
- * @param exclusions
- * @throws IOException
- */
- public void encodePassThruWithExclusions(FacesContext context, UIComponent component, String exclusions,
- String defaultHtmlEvent) throws IOException {
-
- if (null != exclusions) {
- String[] exclusionsArray = exclusions.split(",");
-
- encodePassThruWithExclusionsArray(context, component, exclusionsArray, defaultHtmlEvent);
- }
- }
-
- public void encodePassThruWithExclusionsArray(FacesContext context, UIComponent component, String[] exclusions,
- String defaultHtmlEvent) throws IOException {
-
- ResponseWriter writer = context.getResponseWriter();
- Map<String, Object> attributes = component.getAttributes();
-
- Arrays.sort(exclusions);
-
- for (int i = 0; i < HTML.PASS_THRU.length; i++) {
- String attribute = HTML.PASS_THRU[i];
-
- if (Arrays.binarySearch(exclusions, attribute) < 0) {
- encodePassThruAttribute(context, attributes, writer, attribute);
- }
- }
-
- if (component instanceof ClientBehaviorHolder) {
- ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
-
- encodeBehaviors(context, clientBehaviorHolder, defaultHtmlEvent, exclusions);
- } else {
- for (int i = 0; i < HTML.PASS_THRU_EVENTS.length; i++) {
- String attribute = HTML.PASS_THRU_EVENTS[i];
-
- if (Arrays.binarySearch(exclusions, attribute) < 0) {
- encodePassThruAttribute(context, attributes, writer, attribute);
- }
- }
- }
- }
-
- /**
- * Encode one pass-thru attribute, with plain/boolean/url value, got from
- * properly component attribute.
- *
- * @param context
- * @param writer
- * @param attribute
- * @throws IOException
- */
- public void encodePassThruAttribute(FacesContext context, Map<String, Object> attributes, ResponseWriter writer,
- String attribute) throws IOException {
-
- Object value = attributeValue(attribute, attributes.get(getComponentAttributeName(attribute)));
-
- if ((null != value) && shouldRenderAttribute(attribute, value)) {
- if (Arrays.binarySearch(HTML.PASS_THRU_URI, attribute) >= 0) {
- String url = context.getApplication().getViewHandler().getResourceURL(context, value.toString());
-
- url = context.getExternalContext().encodeResourceURL(url);
- writer.writeURIAttribute(attribute, url, attribute);
- } else {
- writer.writeAttribute(attribute, value, attribute);
- }
- }
- }
-
- public void encodeAttributesFromArray(FacesContext context, UIComponent component, String[] attrs)
- throws IOException {
-
- ResponseWriter writer = context.getResponseWriter();
- Map<String, Object> attributes = component.getAttributes();
-
- for (int i = 0; i < attrs.length; i++) {
- String attribute = attrs[i];
-
- encodePassThruAttribute(context, attributes, writer, attribute);
- }
- }
-
- /**
- * Encode attributes given by comma-separated string list.
- *
- * @param context
- * current JSF context
- * @param component
- * for with render attributes values
- * @param attrs
- * comma separated list of attributes
- * @throws IOException
- */
- public void encodeAttributes(FacesContext context, UIComponent component, String attrs) throws IOException {
- if (null != attrs) {
- String[] attrsArray = attrs.split(",");
-
- encodeAttributesFromArray(context, component, attrsArray);
- }
- }
-
- /**
- * @param context
- * @param component
- * @param property
- * @param attributeName
- *
- * @throws IOException
- */
- public void encodeAttribute(FacesContext context, UIComponent component, Object property, String attributeName)
- throws IOException {
-
- ResponseWriter writer = context.getResponseWriter();
- Object value = component.getAttributes().get(property);
-
- if (shouldRenderAttribute(attributeName, value)) {
- writer.writeAttribute(attributeName, value, property.toString());
- }
- }
-
- public void encodeAttribute(FacesContext context, UIComponent component, String attribute) throws IOException {
- encodeAttribute(context, component, getComponentAttributeName(attribute), attribute);
- }
-
- /**
- * Write html-attribute
- *
- * @param writer
- * @param attribute
- * @param value
- * @throws IOException
- */
- public void writeAttribute(ResponseWriter writer, String attribute, Object value) throws IOException {
- if (shouldRenderAttribute(attribute, value)) {
- writer.writeAttribute(attribute, value.toString(), attribute);
- }
- }
-
- /**
- * @return true if and only if the argument <code>attributeVal</code> is
- * an instance of a wrapper for a primitive type and its value is
- * equal to the default value for that type as given in the spec.
- */
- public boolean shouldRenderAttribute(Object attributeVal) {
- if (null == attributeVal) {
- return false;
- } else if ((attributeVal instanceof Boolean)
- && ((Boolean) attributeVal).booleanValue() == Boolean.FALSE.booleanValue()) {
- return false;
- } else if (attributeVal.toString().length() == 0) {
- return false;
- } else {
- return isValidProperty(attributeVal);
- }
- }
-
- public boolean shouldRenderAttribute(String attributeName, Object attributeVal) {
- if (REQUIRED_ATTRIBUTES.contains(attributeName)) {
- if (attributeVal == null) {
- return false;
- }
- } else {
- return shouldRenderAttribute(attributeVal);
- }
-
- return true;
- }
-
- /**
- * Test for valid value of property. by default, for non-setted properties
- * with Java primitive types of JSF component return appropriate MIN_VALUE .
- *
- * @param property -
- * value of property returned from
- * {@link UIComponent#getAttributes()}
- * @return true for setted property, false otherthise.
- */
- public boolean isValidProperty(Object property) {
- if (null == property) {
- return false;
- } else if ((property instanceof Integer) && ((Integer) property).intValue() == Integer.MIN_VALUE) {
- return false;
- } else if ((property instanceof Double) && ((Double) property).doubleValue() == Double.MIN_VALUE) {
- return false;
- } else if ((property instanceof Character) && ((Character) property).charValue() == Character.MIN_VALUE) {
- return false;
- } else if ((property instanceof Float) && ((Float) property).floatValue() == Float.MIN_VALUE) {
- return false;
- } else if ((property instanceof Short) && ((Short) property).shortValue() == Short.MIN_VALUE) {
- return false;
- } else if ((property instanceof Byte) && ((Byte) property).byteValue() == Byte.MIN_VALUE) {
- return false;
- } else if ((property instanceof Long) && ((Long) property).longValue() == Long.MIN_VALUE) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Checks if the argument passed in is empty or not.
- * Object is empty if it is: <br />
- * - <code>null</code><br />
- * - zero-length string<br />
- * - empty collection<br />
- * - empty map<br />
- * - zero-length array<br />
- *
- * @param o object to check for emptiness
- * @since 3.3.2
- * @return <code>true</code> if the argument is empty, <code>false</code> otherwise
- */
- public boolean isEmpty(Object o) {
- if (null == o) {
- return true;
- }
-
- if (o instanceof String) {
- return 0 == ((String) o).length();
- }
-
- if (o instanceof Collection<?>) {
- return ((Collection<?>) o).isEmpty();
- }
-
- if (o instanceof Map<?, ?>) {
- return ((Map<?, ?>) o).isEmpty();
- }
-
- if (o.getClass().isArray()) {
- return Array.getLength(o) == 0;
- }
-
- return false;
- }
-
- /**
- * Puts value into map under specified key if the value is not empty and not default.
- * Performs optional value wrapping.
- *
- * @param hash
- * @param name
- * @param value
- * @param defaultValue
- * @param wrapper
- *
- * @since 3.3.2
- */
- public void addToScriptHash(Map<String, Object> hash, String name, Object value, String defaultValue,
- ScriptHashVariableWrapper wrapper) {
- ScriptHashVariableWrapper wrapperOrDefault = (wrapper != null) ? wrapper : ScriptHashVariableWrapper.DEFAULT;
-
- if (isValidProperty(value) && !isEmpty(value)) {
- if (!isEmpty(defaultValue)) {
- if (!defaultValue.equals(value.toString())) {
- hash.put(name, wrapperOrDefault.wrap(value));
- }
- } else {
- if (!(value instanceof Boolean) || ((Boolean) value).booleanValue()) {
- hash.put(name, wrapperOrDefault.wrap(value));
- }
- }
- }
- }
-
- /**
- * Puts value into map under specified key if the value is not empty and not default.
- * Performs optional value wrapping.
- *
- * @param hash
- * @param name
- * @param value
- * @param defaultValue
- *
- * @since 3.3.2
- */
- public void addToScriptHash(Map<String, Object> hash, String name, Object value, String defaultValue) {
- addToScriptHash(hash, name, value, defaultValue, null);
- }
-
- /**
- * Puts value into map under specified key if the value is not empty and not default.
- * Performs optional value wrapping.
- *
- * @param hash
- * @param name
- * @param value
- *
- * @since 3.3.2
- */
- public void addToScriptHash(Map<String, Object> hash, String name, Object value) {
- addToScriptHash(hash, name, value, null, null);
- }
-
- /**
- * Convert HTML attribute name to component property name.
- *
- * @param key
- * @return
- */
- protected Object getComponentAttributeName(Object key) {
- Object converted = SUBSTITUTIONS.get(key);
-
- if (null == converted) {
- return key;
- } else {
- return converted;
- }
- }
-
- /**
- * Convert attribute value to proper object. For known html boolean
- * attributes return name for true value, otherthise - null. For non-boolean
- * attributes return same value.
- *
- * @param name
- * attribute name.
- * @param value
- * @return
- */
- protected Object attributeValue(String name, Object value) {
- if (null == value || Arrays.binarySearch(HTML.PASS_THRU_BOOLEAN, name) < 0) {
- return value;
- }
-
- boolean checked;
-
- if (value instanceof Boolean) {
- checked = ((Boolean) value).booleanValue();
- } else {
- checked = Boolean.parseBoolean(value.toString());
- }
-
- return checked ? name : null;
- }
-
- /**
- * Get boolean value of logical attribute
- *
- * @param component
- * @param name
- * attribute name
- * @return true if attribute is equals Boolean.TRUE or String "true" , false
- * otherwise.
- */
- public boolean isBooleanAttribute(UIComponent component, String name) {
- Object attrValue = component.getAttributes().get(name);
- boolean result = false;
-
- if (null != attrValue) {
- if (attrValue instanceof String) {
- result = "true".equalsIgnoreCase((String) attrValue);
- } else {
- result = Boolean.TRUE.equals(attrValue);
- }
- }
-
- return result;
- }
-
- /**
- * Return converted value for {@link javax.faces.component.ValueHolder} as
- * String, perform nessesary convertions.
- *
- * @param context
- * @param component
- * @return
- */
- public String getValueAsString(FacesContext context, UIComponent component) {
-
- // First - get submitted value for input components
- if (component instanceof EditableValueHolder) {
- EditableValueHolder input = (EditableValueHolder) component;
- String submittedValue = (String) input.getSubmittedValue();
-
- if (null != submittedValue) {
- return submittedValue;
- }
- }
-
- // If no submitted value presented - convert same for UIInput/UIOutput
- if (component instanceof ValueHolder) {
- return formatValue(context, component, ((ValueHolder) component).getValue());
- } else {
- throw new IllegalArgumentException(
- Messages.getMessage(Messages.CONVERTING_NON_VALUE_HOLDER_COMPONENT_ERROR, component.getId()));
- }
- }
-
- /**
- * Convert any object value to string. If component instance of
- * {@link ValueHolder } got {@link Converter} for formatting. If not,
- * attempt to use converter based on value type.
- *
- * @param context
- * @param component
- * @return
- */
- public String formatValue(FacesContext context, UIComponent component, Object value) {
- if (value instanceof String) {
- return (String) value;
- }
-
- Converter converter = null;
-
- if (component instanceof ValueHolder) {
- ValueHolder holder = (ValueHolder) component;
-
- converter = holder.getConverter();
- }
-
- if ((null == converter) && (null != value)) {
- try {
- converter = context.getApplication().createConverter(value.getClass());
- } catch (FacesException e) {
-
- // TODO - log converter exception.
- }
- }
-
- if (null == converter) {
- if (null != value) {
- return value.toString();
- }
- } else {
- return converter.getAsString(context, component, value);
- }
-
- return "";
- }
-
- public String encodePx(String value) {
- return HtmlDimensions.formatPx(HtmlDimensions.decode(value));
- }
-
- /**
- * formats given value to
- *
- * @param value
- *
- * @return
- */
- public String encodePctOrPx(String value) {
- if (value.indexOf('%') > 0) {
- return value;
- } else {
- return encodePx(value);
- }
- }
-
- /**
- * Find nested form for given component
- *
- * @param component
- * @return nested <code>UIForm</code> component, or <code>null</code>
- */
- public UIForm getNestingForm(FacesContext context, UIComponent component) {
- UIComponent parent = component.getParent();
-
- while ((parent != null) && !(parent instanceof UIForm)) {
- parent = parent.getParent();
- }
-
- UIForm nestingForm = null;
-
- if (parent != null) {
-
- // link is nested inside a form
- nestingForm = (UIForm) parent;
- }
-
- return nestingForm;
- }
-
- /**
- * @param context
- * @param component
- * @return
- * @throws IOException
- */
- public void encodeBeginFormIfNessesary(FacesContext context, UIComponent component) throws IOException {
- UIForm form = getNestingForm(context, component);
-
- if (null == form) {
- ResponseWriter writer = context.getResponseWriter();
- String clientId = component.getClientId(context) + DUMMY_FORM_ID;
-
- encodeBeginForm(context, component, writer, clientId);
-
- // writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "margin:0;
- // padding:0;", null);
- }
- }
-
- /**
- * @param context
- * @param component
- * @param writer
- * @param clientId
- * @throws IOException
- */
- public void encodeBeginForm(FacesContext context, UIComponent component, ResponseWriter writer, String clientId)
- throws IOException {
-
- String actionURL = getActionUrl(context);
- String encodeActionURL = context.getExternalContext().encodeActionURL(actionURL);
-
- writer.startElement(HTML.FORM_ELEMENT, component);
- writer.writeAttribute(HTML.ID_ATTRIBUTE, clientId, null);
- writer.writeAttribute(HTML.NAME_ATTRIBUTE, clientId, null);
- writer.writeAttribute(HTML.METHOD_ATTRIBUTE, "post", null);
- writer.writeAttribute(HTML.STYLE_ATTRIBUTE, "margin:0; padding:0; display: inline;", null);
- writer.writeURIAttribute(HTML.ACTION_ATTRIBUTE, encodeActionURL, "action");
- }
-
- /**
- * @param context
- * @param component
- * @throws IOException
- */
- public void encodeEndFormIfNessesary(FacesContext context, UIComponent component) throws IOException {
- UIForm form = getNestingForm(context, component);
-
- if (null == form) {
- ResponseWriter writer = context.getResponseWriter();
-
- // TODO - hidden form parameters ?
- encodeEndForm(context, writer);
- }
- }
-
- /**
- * @param context
- * @param writer
- * @throws IOException
- */
- public void encodeEndForm(FacesContext context, ResponseWriter writer) throws IOException {
- AjaxRendererUtils.writeState(context);
- writer.endElement(HTML.FORM_ELEMENT);
- }
-
- /**
- * @param facesContext
- * @return String A String representing the action URL
- */
- public String getActionUrl(FacesContext facesContext) {
- ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
- String viewId = facesContext.getViewRoot().getViewId();
-
- return viewHandler.getActionURL(facesContext, viewId);
- }
-
- /**
- * Simplified version of {@link encodeId}
- *
- * @param context
- * @param component
- * @return client id of current component
- */
- public String clientId(FacesContext context, UIComponent component) {
- String clientId = "";
-
- try {
- clientId = component.getClientId(context);
- } catch (Exception e) {
-
- // just ignore
- }
-
- return clientId;
- }
-
- /**
- * Wtrie JavaScript with start/end elements and type.
- *
- * @param context
- * @param component
- * @param script
- */
- public void writeScript(FacesContext context, UIComponent component, Object script) throws IOException {
- ResponseWriter writer = context.getResponseWriter();
-
- writer.startElement(HTML.SCRIPT_ELEM, component);
- writer.writeAttribute(HTML.TYPE_ATTR, "text/javascript", "type");
- writer.writeText(script, null);
- writer.endElement(HTML.SCRIPT_ELEM);
- }
-
- /**
- * @param ids
- * @param keyword
- * @return
- * @since 4.0
- */
- private static boolean checkKeyword(Collection<String> ids, String keyword) {
- if (ids.contains(keyword)) {
- if (ids.size() != 1) {
- //TODO log
- }
-
- return true;
- }
-
- return false;
- }
-
- public String getPredefinedMetaComponentId(FacesContext facesContext, UIComponent component, String id) {
-
- if (AjaxRendererUtils.ALL.equals(id)) {
- return AjaxRendererUtils.ALL;
- } else if (AjaxRendererUtils.NONE.equals(id)) {
- return AjaxRendererUtils.NONE;
- } else if (AjaxRendererUtils.THIS.equals(id)) {
- return component.getClientId(facesContext);
- } else if (AjaxRendererUtils.FORM.equals(id)) {
- UIForm nestingForm = getNestingForm(facesContext, component);
- if (nestingForm != null) {
- return nestingForm.getClientId(facesContext);
- } else {
- //TODO nick - log warning for missing form
- }
- }
-
- return null;
- }
-
- /**
- * @param context
- * @param component
- * @param shortIds
- * @since 4.0
- * @return
- */
- public Collection<String> findComponentsFor(FacesContext context, UIComponent component,
- Collection<String> shortIds) {
-
- // TODO - implement
- // TODO add support for @*
- Set<String> result = new LinkedHashSet<String>(shortIds.size());
-
- if (checkKeyword(shortIds, AjaxRendererUtils.ALL)) {
- result.add(AjaxRendererUtils.ALL);
- } else if (checkKeyword(shortIds, AjaxRendererUtils.NONE)) {
- //do nothing, use empty set
- } else {
- ComponentIdResolver locator = new ComponentIdResolver(context);
-
- for (String id : shortIds) {
- String predefinedMetaComponentId = getPredefinedMetaComponentId(context, component, id);
- if (predefinedMetaComponentId != null) {
- if (AjaxRendererUtils.GLOBAL_META_COMPONENTS.contains(predefinedMetaComponentId)) {
- result.clear();
- result.add(predefinedMetaComponentId);
- break;
- } else {
- result.add(predefinedMetaComponentId);
- continue;
- }
- }
-
- locator.addId(id);
- }
-
- locator.resolve(component);
-
- result.addAll(locator.getResolvedIds());
- }
-
- return result;
- }
-
- public UIComponent findComponentFor(FacesContext context, UIComponent component, String id) {
- return findComponentFor(component, id);
- }
-
- /**
- * @param component
- * @param id
- * @return
- */
- public UIComponent findComponentFor(UIComponent component, String id) {
- if (id == null) {
- throw new NullPointerException("id is null!");
- }
-
- if (id.length() == 0) {
- return null;
- }
-
- UIComponent target = null;
- UIComponent parent = component;
- UIComponent root = component;
-
- while ((null == target) && (null != parent)) {
- target = parent.findComponent(id);
- root = parent;
- parent = parent.getParent();
- }
-
- if (null == target) {
- target = findUIComponentBelow(root, id);
- }
-
- return target;
- }
-
- /**
- * If target component contains generated id and for doesn't, correct for id
- * @param forAttr
- * @param component
- *
- */
- public String correctForIdReference(String forAttr, UIComponent component) {
- int contains = forAttr.indexOf(UIViewRoot.UNIQUE_ID_PREFIX);
-
- if (contains <= 0) {
- String id = component.getId();
- int pos = id.indexOf(UIViewRoot.UNIQUE_ID_PREFIX);
-
- if (pos > 0) {
- return forAttr.concat(id.substring(pos));
- }
- }
-
- return forAttr;
- }
-
- private UIComponent findUIComponentBelow(UIComponent root, String id) {
- UIComponent target = null;
-
- for (Iterator<UIComponent> iter = root.getFacetsAndChildren(); iter.hasNext();) {
- UIComponent child = (UIComponent) iter.next();
-
- if (child instanceof NamingContainer) {
- try {
- target = child.findComponent(id);
- } catch (IllegalArgumentException iae) {
- continue;
- }
- }
-
- if (target == null) {
- if ((child.getChildCount() > 0) || (child.getFacetCount() > 0)) {
- target = findUIComponentBelow(child, id);
- }
- }
-
- if (target != null) {
- break;
- }
- }
-
- return target;
- }
-
- public static void writeEventHandlerFunction(FacesContext context, UIComponent component, String eventName)
- throws IOException {
-
- ResponseWriter writer = context.getResponseWriter();
- Object script = component.getAttributes().get(eventName);
-
- if ((script != null) && !script.equals("")) {
- JSFunctionDefinition onEventDefinition = new JSFunctionDefinition();
-
- onEventDefinition.addParameter("event");
- onEventDefinition.addToBody(script);
- writer.writeText(eventName + ": " + onEventDefinition.toScript(), null);
- } else {
- writer.writeText(eventName + ": ''", null);
- }
- }
-
- public JSFunctionDefinition getAsEventHandler(FacesContext context, UIComponent component, String attributeName,
- String append) {
- String event = (String) component.getAttributes().get(attributeName);
-
- if (event != null) {
- event = event.trim();
-
- if (event.length() != 0) {
- JSFunctionDefinition function = new JSFunctionDefinition();
-
- function.addParameter("event");
-
- if ((null != append) && (append.length() > 0)) {
- function.addToBody(event + append);
- } else {
- function.addToBody(event);
- }
-
- return function;
- }
- }
-
- return null;
- }
-
- public String escapeJavaScript(Object o) {
- if (o != null) {
- StringBuilder result = new StringBuilder();
- JSEncoder encoder = new JSEncoder();
- char[] chars = o.toString().toCharArray();
- int start = 0;
- int end = chars.length;
-
- for (int x = start; x < end; x++) {
- char c = chars[x];
-
- if (encoder.compile(c)) {
- continue;
- }
-
- if (start != x) {
- result.append(chars, start, x - start);
- }
-
- result.append(encoder.encode(c));
- start = x + 1;
-
- continue;
- }
-
- if (start != end) {
- result.append(chars, start, end - start);
- }
-
- return result.toString();
- } else {
- return null;
- }
- }
-
- public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
- if (component.getChildCount() > 0) {
- for (UIComponent child : component.getChildren()) {
- child.encodeAll(context);
- }
- }
- }
-
- public boolean hasExplicitId(UIComponent component) {
- return component.getId() != null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX);
- }
-
- /**
- * Common HTML elements and attributes names.
- *
- * @author asmirnov(a)exadel.com (latest modification by $Author: alexsmirnov $)
- * @version $Revision: 1.1.2.6 $ $Date: 2007/02/08 19:07:16 $
- *
- */
- public interface HTML {
- // elements
- public static final String A_ELEMENT = "a";
- public static final String BODY_ELEMENT = "body";
- public static final String IMG_ELEMENT = "img";
- public static final String INPUT_ELEM = "input";
- public static final String INPUT_TYPE_HIDDEN = "hidden";
- public static final String BUTTON = "button";
- public static final String CAPTION_ELEMENT = "caption";
- public static final String CHARSET_ATTR = "charset";
- public static final String COORDS_ATTR = "coords";
- public static final String COLGROUP_ELEMENT = "colgroup";
- public static final String COL_ELEMENT = "col";
- public static final String DISABLED_ATTR = "disabled";
- public static final String DIV_ELEM = "div";
- public static final String DD_ELEMENT = "dd";
- public static final String DL_ELEMENT = "dl";
- public static final String DT_ELEMENT = "dt";
- public static final String FORM_ELEMENT = "form";
- public static final String HEAD_ELEMENT = "head";
- public static final String HEIGHT_ATTRIBUTE = "height";
- public static final String HREFLANG_ATTR = "hreflang";
- public static final String HREF_ATTR = "href";
- public static final String HTML_ELEMENT = "html";
- public static final String LINK_ELEMENT = "link";
- public static final String SCRIPT_ELEM = "script";
- public static final String SPAN_ELEM = "span";
- public static final String TFOOT_ELEMENT = "tfoot";
- public static final String THEAD_ELEMENT = "thead";
- public static final String TABLE_ELEMENT = "table";
- public static final String TBODY_ELEMENT = "tbody";
- public static final String TD_ELEM = "td";
- public static final String TR_ELEMENT = "tr";
- public static final String TH_ELEM = "th";
- public static final String TITLE_ELEM = "title";
- public static final String UL_ELEMENT = "ul";
- public static final String OL_ELEMENT = "ol";
- public static final String LI_ELEMENT = "li";
-
- // attributes
- public static final String FRAME_ATTRIBUTE = "frame";
- public static final String BORDER_ATTRIBUTE = "border";
- public static final String BGCOLOR_ATTRIBUTE = "bgcolor";
- public static final String ACCEPT_ATTRIBUTE = "accept";
- public static final String ACCEPT_CHARSET_ATTRIBUTE = "accept-charset";
- public static final String ACCESSKEY_ATTRIBUTE = "accesskey";
- public static final String ACTION_ATTRIBUTE = "action";
- public static final String ALIGN_ATTRIBUTE = "align";
- public static final String ALT_ATTRIBUTE = "alt";
- public static final String AUTOCOMPLETE_ATTRIBUTE = "autocomplete";
- public static final String CLASS_ATTRIBUTE = "class";
- public static final String COLS_ATTRIBUTE = "cols";
- public static final String COLSPAN_ATTRIBUTE = "colspan";
- public static final String CELLPADDING_ATTRIBUTE = "cellpadding";
- public static final String CELLSPACING_ATTRIBUTE = "cellspacing";
- public static final String DIR_ATTRIBUTE = "dir";
- public static final String ENCTYPE_ATTRIBUTE = "enctype";
-
- public static final String ID_ATTRIBUTE = "id";
- public static final String LANG_ATTRIBUTE = "lang";
- public static final String LONGDESC_ATTRIBUTE = "longdesc";
- public static final String MAXLENGTH_ATTRIBUTE = "maxlength";
- public static final String MEDIA_ATTRIBUTE = "media";
- public static final String METHOD_ATTRIBUTE = "method";
- public static final String NAME_ATTRIBUTE = "name";
- public static final String NOWRAP_ATTRIBUTE = "nowrap";
- public static final String ROWS_ATTRIBUTE = "rows";
- public static final String RULES_ATTRIBUTE = "rules";
- public static final String ROWSPAN_ATTRIBUTE = "rowspan";
- public static final String READONLY_ATTRIBUTE = "readonly";
- public static final String SIZE_ATTRIBUTE = "size";
- public static final String SRC_ATTRIBUTE = "src";
- public static final String STYLE_ATTRIBUTE = "style";
- public static final String SUMMARY_ATTRIBUTE = "summary";
- public static final String SCOPE_ATTRIBUTE = "scope";
- public static final String TABINDEX_ATTRIBUTE = "tabindex";
- public static final String TITLE_ATTRIBUTE = "title";
- public static final String TARGET_ATTRIBUTE = "target";
- public static final String TYPE_ATTR = "type";
-
- public static final String USEMAP_ATTRIBUTE = "usemap";
-
- public static final String VALIGN_ATTRIBUTE = "valign";
- public static final String VALUE_ATTRIBUTE = "value";
- public static final String WIDTH_ATTRIBUTE = "width";
-
-
- public static final String ONBLUR_ATTRIBUTE = "onblur";
- public static final String ONCHANGE_ATTRIBUTE = "onchange";
- public static final String ONCLICK_ATTRIBUTE = "onclick";
- public static final String ONDBLCLICK_ATTRIBUTE = "ondblclick";
- public static final String ONFOCUS_ATTRIBUTE = "onfocus";
- public static final String ONKEYDOWN_ATTRIBUTE = "onkeydown";
- public static final String ONKEYPRESS_ATTRIBUTE = "onkeypress";
- public static final String ONKEYUP_ATTRIBUTE = "onkeyup";
- public static final String ONLOAD_ATTRIBUTE = "onload";
- public static final String ONMOUSEDOWN_ATTRIBUTE = "onmousedown";
- public static final String ONMOUSEMOVE_ATTRIBUTE = "onmousemove";
- public static final String ONMOUSEOUT_ATTRIBUTE = "onmouseout";
- public static final String ONMOUSEOVER_ATTRIBUTE = "onmouseover";
- public static final String ONMOUSEUP_ATTRIBUTE = "onmouseup";
- public static final String ONRESET_ATTRIBUTE = "onreset";
- public static final String ONSELECT_ATTRIBUTE = "onselect";
- public static final String ONSUBMIT_ATTRIBUTE = "onsubmit";
- public static final String ONUNLOAD_ATTRIBUTE = "onunload";
-
- public static final String REL_ATTR = "rel";
- public static final String REV_ATTR = "rev";
- public static final String SHAPE_ATTR = "shape";
- public static final String STYLE_CLASS_ATTR = "styleClass";
-
-
-
- // public static final String ONRESET_ATTRIBUTE = "onreset";
- // attributes sets.
- public static final String[] PASS_THRU = {
-
- // DIR_ATTRIBUTE,
- // LANG_ATTRIBUTE,
- // STYLE_ATTRIBUTE,
- // TITLE_ATTRIBUTE
- "accesskey", "alt", "cols", "height", "lang", "longdesc", "maxlength", "rows", "size", "tabindex", "title",
- "width", "dir", "rules", "frame", "border", "cellspacing", "cellpadding", "summary", "bgcolor", "usemap",
- "enctype", "accept-charset", "accept", "target", "charset", "coords", "hreflang", "rel", "rev", "shape",
- "disabled", "readonly", "ismap", "align"
- };
-
- /**
- * HTML attributes allowed boolean-values only
- */
- public static final String[] PASS_THRU_BOOLEAN = {
- "disabled", "declare", "readonly", "compact", "ismap", "selected", "checked", "nowrap", "noresize",
- "nohref", "noshade", "multiple"
- };
- public static final String[] PASS_THRU_EVENTS = {
- "onblur", "onchange", "onclick", "ondblclick", "onfocus", "onkeydown", "onkeypress", "onkeyup", "onload",
- "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onreset", "onselect", "onsubmit",
- "onunload"
- };
- public static final String[] PASS_THRU_STYLES = {"style", "class", };
-
- /**
- * all HTML attributes with URI value.
- */
- public static final String[] PASS_THRU_URI = {
- "usemap", "background", "codebase", "cite", "data", "classid", "href", "longdesc", "profile", "src"
- };
-
-
- public static final String TEXT_JAVASCRIPT_TYPE = "text/javascript";
- public static final String REL_STYLESHEET = "stylesheet";
- public static final String CSS_TYPE = "text/css";
- public static final String JAVASCRIPT_TYPE = "text/javascript";
- }
-}
14 years, 3 months
JBoss Rich Faces SVN: r19136 - trunk/core/api/src/main/java/org/richfaces/renderkit.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-09-08 13:07:06 -0400 (Wed, 08 Sep 2010)
New Revision: 19136
Modified:
trunk/core/api/src/main/java/org/richfaces/renderkit/HtmlConstants.java
Log:
https://jira.jboss.org/browse/RF-9308
Modified: trunk/core/api/src/main/java/org/richfaces/renderkit/HtmlConstants.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/renderkit/HtmlConstants.java 2010-09-08 13:40:08 UTC (rev 19135)
+++ trunk/core/api/src/main/java/org/richfaces/renderkit/HtmlConstants.java 2010-09-08 17:07:06 UTC (rev 19136)
@@ -153,7 +153,7 @@
"accesskey", "alt", "cols", "height", "lang", "longdesc", "maxlength", "rows", "size", "tabindex", "title",
"width", "dir", "rules", "frame", "border", "cellspacing", "cellpadding", "summary", "bgcolor", "usemap",
"enctype", "accept-charset", "accept", "target", "charset", "coords", "hreflang", "rel", "rev", "shape",
- "disabled", "readonly", "ismap", "align"
+ "disabled", "readonly", "ismap", "align", "type"
};
/**
14 years, 3 months