WW-1607 Separate dojo-related tags into their own plugin. For prior history see <http://svn.apache.org/viewvc?view=rev&revision=514082>

git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@514083 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Musachy Barroso
2007-03-03 05:48:54 +00:00
parent f111ea4bbb
commit e2f349dca9
836 changed files with 127652 additions and 0 deletions
+198
View File
@@ -0,0 +1,198 @@
<?xml version="1.0"?>
<project>
<parent>
<artifactId>struts2-plugins</artifactId>
<groupId>org.apache.struts</groupId>
<version>2.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-dojo-plugin</artifactId>
<name>Struts2 Dojo Plugin</name>
<scm>
<connection>
scm:svn:http://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/dojo/
</connection>
<developerConnection>
scm:svn:https://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/dojo/
</developerConnection>
<url>
http://svn.apache.org/viewcvs.cgi/struts/struts2/trunk/plugins/dojo/
</url>
</scm>
<build>
<plugins>
<plugin>
<groupId>org.apache.myfaces.tobago</groupId>
<artifactId>maven-apt-plugin</artifactId>
<configuration>
<A>
uri=/struts-dojo-tags,tlibVersion=2.2.3,jspVersion=1.2,shortName=sx,displayName="Struts
Dojo Tags",
outFile=${basedir}/target/classes/META-INF/struts-dojo-tags.tld,
description="Struts AJAX tags based on Dojo.",
outTemplatesDir=${basedir}/../../core/src/site/resources/tags/ajax
</A>
<resourceTargetPath>target</resourceTargetPath>
<fork>false</fork>
<force>true</force>
<nocompile>true</nocompile>
<showWarnings>true</showWarnings>
<factory>
org.apache.struts.annotations.taglib.apt.TLDAnnotationProcessorFactory
</factory>
<target>1.5</target>
<includes>
<include>**/*.java</include>
</includes>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Core -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${pom.version}</version>
</dependency>
<!-- JSP API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- Velocity -->
<dependency>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.4</version>
<optional>true</optional>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>compile</scope>
<version>3.8.1</version>
<!-- has to be compile for StrutsTestCase, which is part of the base package so others can write unit tests -->
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.1</version>
<optional>true</optional>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>jmock</groupId>
<artifactId>jmock</artifactId>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.0</version>
<scope>test</scope>
</dependency>
<!--dependency>
<groupId>org.easymock</groupId>
<artifactId>easymockclassextension</artifactId>
<version>1.1</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
</exclusion>
</exclusions>
</dependency-->
<dependency>
<groupId>jmock</groupId>
<artifactId>jmock-cglib</artifactId>
<version>1.0.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mockobjects</groupId>
<artifactId>mockobjects-core</artifactId>
<version>0.09</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mockobjects</groupId>
<artifactId>mockobjects-jdk1.3</artifactId>
<version>0.09</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mockobjects</groupId>
<artifactId>mockobjects-alt-jdk1.3</artifactId>
<version>0.09</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mockobjects</groupId>
<artifactId>mockobjects-alt-jdk1.3-j2ee1.3</artifactId>
<version>0.09</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mockobjects</groupId>
<artifactId>mockobjects-jdk1.3-j2ee1.3</artifactId>
<version>0.09</version>
<scope>test</scope>
</dependency>
<!-- Mocks for unit testing (by Spring) -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
<version>1.2.8</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>1.2.8</version>
<scope>test</scope>
</dependency>
<!-- struts-annotations must be in compile scope for maven-apt-plugin to
function correctly. Marking it optional to exclude it from transitive
dependency resolution -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-annotations</artifactId>
<version>1.0.2-SNAPSHOT</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,171 @@
/*
* $Id: AbstractRemoteCallUIBean.java 508285 2007-02-16 02:42:24Z musachy $
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts2.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
import com.opensymphony.xwork2.util.ValueStack;
/**
* AbstractRemoteCallUIBean is superclass for all components dealing with remote
* calls.
*/
@StrutsTagSkipInheritance
public abstract class AbstractRemoteCallUIBean extends ClosingUIBean implements RemoteUICallBean {
protected String href;
protected String errorText;
protected String afterLoading;
protected String beforeLoading;
protected String executeScripts;
protected String loadingText;
protected String listenTopics;
protected String handler;
protected String formId;
protected String formFilter;
protected String notifyTopics;
protected String showErrorTransportText;
protected String indicator;
protected String showLoadingText;
public AbstractRemoteCallUIBean(ValueStack stack, HttpServletRequest request,
HttpServletResponse response) {
super(stack, request, response);
}
public void evaluateExtraParams() {
super.evaluateExtraParams();
if (href != null)
addParameter("href", findString(href));
if (errorText != null)
addParameter("errorText", findString(errorText));
if (loadingText != null)
addParameter("loadingText", findString(loadingText));
if (afterLoading != null)
addParameter("afterLoading", findString(afterLoading));
if (beforeLoading != null)
addParameter("beforeLoading", findString(beforeLoading));
if (executeScripts != null)
addParameter("executeScripts", findValue(executeScripts, Boolean.class));
if (listenTopics != null)
addParameter("listenTopics", findValue(listenTopics, String.class));
if (notifyTopics != null)
addParameter("notifyTopics", findValue(notifyTopics, String.class));
if (handler != null)
addParameter("handler", findString(handler));
if (formId != null)
addParameter("formId", findString(formId));
if (formFilter != null)
addParameter("formFilter", findString(formFilter));
if (indicator != null)
addParameter("indicator", findString(indicator));
if (showErrorTransportText != null)
addParameter("showErrorTransportText", findValue(showErrorTransportText, Boolean.class));
else
addParameter("showErrorTransportText", true);
if (showLoadingText != null)
addParameter("showLoadingText", findString(showLoadingText));
}
@StrutsTagAttribute(description="Topic that will trigger the remote call")
public void setListenTopics(String listenTopics) {
this.listenTopics = listenTopics;
}
@StrutsTagAttribute(description="The URL to call to obtain the content. Note: If used with ajax context, the value must be set as an url tag value.")
public void setHref(String href) {
this.href = href;
}
@StrutsTagAttribute(description="The text to display to the user if the is an error fetching the content")
public void setErrorText(String errorText) {
this.errorText = errorText;
}
/* (non-Javadoc)
* @see org.apache.struts2.components.RemoteUICallBean#setAfterLoading(java.lang.String)
*/
public void setAfterLoading(String afterLoading) {
this.afterLoading = afterLoading;
}
/* (non-Javadoc)
* @see org.apache.struts2.components.RemoteUICallBean#setBeforeLoading(java.lang.String)
*/
public void setBeforeLoading(String beforeLoading) {
this.beforeLoading = beforeLoading;
}
@StrutsTagAttribute(description="Javascript code in the fetched content will be executed", type="Boolean", defaultValue="false")
public void setExecuteScripts(String executeScripts) {
this.executeScripts = executeScripts;
}
@StrutsTagAttribute(description="Text to be shown while content is being fetched", defaultValue="Loading...")
public void setLoadingText(String loadingText) {
this.loadingText = loadingText;
}
@StrutsTagAttribute(description="Javascript function name that will make the request")
public void setHandler(String handler) {
this.handler = handler;
}
@StrutsTagAttribute(description="Function name used to filter the fields of the form.")
public void setFormFilter(String formFilter) {
this.formFilter = formFilter;
}
@StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
public void setFormId(String formId) {
this.formId = formId;
}
@StrutsTagAttribute(description="Topics that will published when the remote call completes")
public void setNotifyTopics(String notifyTopics) {
this.notifyTopics = notifyTopics;
}
@StrutsTagAttribute(description="Set whether errors will be shown or not", type="Boolean", defaultValue="true")
public void setShowErrorTransportText(String showError) {
this.showErrorTransportText = showError;
}
@StrutsTagAttribute(description="Id of element that will be shown while making request")
public void setIndicator(String indicator) {
this.indicator = indicator;
}
@StrutsTagAttribute(description="Show loading text on targets", type="Boolean", defaultValue="true")
public void setShowLoadingText(String showLoadingText) {
this.showLoadingText = showLoadingText;
}
}
@@ -0,0 +1,171 @@
/*
* $Id: Anchor.java 508285 2007-02-16 02:42:24Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
*
* A tag that creates a HTML &lt;a href='' /&gt; that when clicked calls a URL remote XMLHttpRequest call via the dojo
* framework.<p/>
*
* <!-- START SNIPPET: ajaxJavadoc -->
* <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
* <ul>
* <li>href</li>
* <li>errorText</li>
* <li>listenTopics</li>
* <li>notifyTopics</li>
* <li>executeScripts</li>
* <li>loadingText</li>
* <li>listenTopics</li>
* <li>handler</li>
* <li>formId</li>
* <li>formFilter</li>
* <li>targets</li>
* <li>showErrorTransportText</li>
* <li>targets</li>
* <li>indicator</li>
* </ul>
* 'resultDivId' Deprecated. Use targets.<p/>
* 'targets' is a list of element ids whose content will be updated with the
* text returned from request.<p/>
* 'errorText' is the text that will be displayed when there is an error making the request.<p/>
* 'onLoadJS' Deprecated. Use 'notifyTopics'.<p/>
* 'preInvokeJS' Deprecated. Use 'notifyTopics'.<p/>
* 'executeScripts' if set to true will execute javascript sections in the returned text.<p/>
* 'loadingText' is the text that will be displayed on the 'targets' elements while making the
* request.<p/>
* 'handler' is the name of the function that will take care of making the AJAX request. Dojo's widget
* and dom node are passed as parameters).<p/>
* 'formId' is the id of the html form whose fields will be seralized and passed as parameters
* in the request.<p/>
* 'formFilter' is the name of a function which will be used to filter the fields that will be
* seralized. This function takes as a parameter the element and returns true if the element
* should be included.<p/>
* 'listenTopics' comma separated list of topics names, that will trigger a request
* 'indicator' element to be shown while the request executing
* 'showErrorTransportText': whether errors should be displayed (on 'targets')</p>
* 'showLoadingText' show loading text on targets</p>
* 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
* <ul>
* <li>data: html or json object when type='load' or type='error'</li>
* <li>type: 'before' before the request is made, 'load' when the request succeeds, or 'error' when it fails</li>
* <li>request: request javascript object, when type='load' or type='error'</li>
* </ul>
* <!-- END SNIPPET: javadoc -->
*
* <p/> <b>Examples</b>
*
* <pre>
* <!-- START SNIPPET: example1 -->
* &lt;s:a id="link1" theme="ajax" href="/DoIt.action" errorText="An error ocurred" loadingText="Loading..."&gt;
* &lt;img border="none" src="&lt;%=request.getContextPath()%&gt;/images/delete.gif"/&gt;
* &lt;s:param name="id" value="1"/&gt;
* &lt;/s:a&gt;
* <!-- END SNIPPET: example1 -->
* </pre>
*
* </p>
*
* <!-- START SNIPPET: exampledescription1 -->
*
* Results in
*
* <!-- END SNIPPET: exampledescription1 -->
*
* </p>
*
* <pre>
* <!-- START SNIPPET: example2 -->
* &lt;a dojoType="BindAnchor" executeScripts="true" id="link1" href="/DoIt.action?id=1" errorText="An error ocurred"&gt;&lt;/a&gt;
* <!-- END SNIPPET: example2 -->
* </pre>
*
* </p>
*
* <!-- START SNIPPET: exampledescription2 -->
*
* Here is an example that uses the beforeLoading. This example is in altSyntax=true:
*
* <!-- END SNIPPET: exampledescription2 -->
*
* </p>
*
* <pre>
* <!-- START SNIPPET: example3 -->
* &lt;s:a id="test" theme="ajax" href="/simpeResult.action" beforeLoading="confirm('Are you sure?')"&gt;
* A
* &lt;/s:a&gt;
* <!-- END SNIPPET: example3 -->
* </pre>
*
*/
@StrutsTag(name="a", tldTagClass="org.apache.struts2.views.jsp.ui.AnchorTag", description="Render a HTML href element that when clicked can optionally call a URL via remote XMLHttpRequest and updates its targets")
public class Anchor extends AbstractRemoteCallUIBean {
public static final String OPEN_TEMPLATE = "a";
public static final String TEMPLATE = "a-close";
public static final String COMPONENT_NAME = Anchor.class.getName();
protected String targets;
public Anchor(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
public String getDefaultOpenTemplate() {
return OPEN_TEMPLATE;
}
protected String getDefaultTemplate() {
return TEMPLATE;
}
public void evaluateExtraParams() {
super.evaluateExtraParams();
if(targets != null)
addParameter("targets", findString(targets));
}
@StrutsTagAttribute(description="Comma delimited list of ids of the elements whose content will be updated")
public void setTargets(String targets) {
this.targets = targets;
}
@StrutsTagAttribute(name="onLoadJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute after reload")
public void setAfterLoading(String afterLoading) {
this.afterLoading = afterLoading;
}
@StrutsTagAttribute(name="preInvokeJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute before reload")
public void setBeforeLoading(String beforeLoading) {
this.beforeLoading = beforeLoading;
}
}
@@ -0,0 +1,302 @@
/*
* $Id: Autocompleter.java 510785 2007-02-23 03:05:33Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
* <p>The autocomplete tag is a combobox that can autocomplete text entered on the input box.
* When used on the "simple" theme, the autocompleter can be used like the ComboBox.
* When used on the "ajax" theme, the list can be retieved from an action. </p>
* <!-- END SNIPPET: javadoc -->
* <!-- START SNIPPET: ajaxJavadoc -->
* <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
* <ul>
* <li>href</li>
* <li>errorText</li>
* <li>listenTopics</li>
* <li>notifyTopics</li>
* <li>listenTopics</li>
* <li>formId</li>
* <li>formFilter</li>
* <li>indicator</li>
* <li>loadOnTextChange</li>
* <li>loadMinimumCount</li>
* <li>showDownArrow</li>
* <li>searchType</li>
* </ul>
* 'dropdownWidth' width in pixels of the drodpdown, same as autocompleter's width by default<p/>
* 'dropdownHeight' height in pixels of the drodown, 120 px by default<p/>
* 'forceValidOption' if invalid option is selected, clear autocompleter's text when focus is lost<p/>
* 'autoComplete', if true, make suggestions on the textbox<p/>
* 'formId' is the id of the html form whose fields will be seralized and passed as parameters
* in the request.<p/>
* 'formFilter' is the name of a function which will be used to filter the fields that will be
* seralized. This function takes as a parameter the element and returns true if the element
* should be included.<p/>
* 'listenTopics' comma separated list of topics names, that will trigger a request
* 'indicator' element to be shown while the request executing
* 'showErrorTransportText': whether errors should be displayed (on 'targets')<p/>
* 'loadOnTextChange' options will be reloaded everytime a character is typed on the textbox<p/>
* 'loadMinimumCount' minimum number of characters that will force the content to be loaded<p/>
* 'showDownError' show or hide the down arrow button<p/>
* 'searchType' how the search must be performed, options are: "startstring", "startword" and "substring"<p/>
* 'keyName' name of the field to which the selected key will be assigned<p/>
* 'iconPath' path of icon used for the dropdown<p/>
* 'templateCssPath' path to css file used to customize Dojo's widget<p/>
* 'dataFieldName' name of the field to be used as the list in the returned JSON string<p/>
* 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
* <ul>
* <li>data: selected value when type='valuechanged'</li>
* <li>type: 'before' before the request is made, 'valuechanged' when selection changes, 'load' when the request succeeds, or 'error' when it fails</li>
* <li>request: request javascript object, when type='load' or type='error'</li>
* <ul>
*<!-- END SNIPPET: ajaxJavadoc -->
*
*<!-- START SNIPPET: example -->
*<p>Autocompleter that gets its list from an action:</p>
*&lt;s:autocompleter name="test" href="%{jsonList}" autoComplete="false"/&gt;
*<br/>
**<p>Autocompleter that uses a list:</p>
*&lt;s:autocompleter name="test" list="{'apple','banana','grape','pear'}" autoComplete="false"/&gt;
*<br/>
*<!-- END SNIPPET: example -->
*/
@StrutsTag(name="autocompleter", tldTagClass="org.apache.struts2.views.jsp.ui.AutocompleterTag", description="Renders a combobox with autocomplete and AJAX capabilities")
@StrutsTagSkipInheritance
public class Autocompleter extends ComboBox {
public static final String TEMPLATE = "autocompleter";
final private static String COMPONENT_NAME = Autocompleter.class.getName();
protected String forceValidOption;
protected String searchType;
protected String autoComplete;
protected String delay;
protected String disabled;
protected String href;
protected String dropdownWidth;
protected String dropdownHeight;
protected String formId;
protected String formFilter;
protected String listenTopics;
protected String notifyTopics;
protected String indicator;
protected String loadOnTextChange;
protected String loadMinimumCount;
protected String showDownArrow;
protected String templateCssPath;
protected String iconPath;
protected String keyName;
protected String dataFieldName;
public Autocompleter(ValueStack stack, HttpServletRequest request,
HttpServletResponse response) {
super(stack, request, response);
}
protected String getDefaultTemplate() {
return TEMPLATE;
}
public String getComponentName() {
return COMPONENT_NAME;
}
public void evaluateExtraParams() {
super.evaluateExtraParams();
if (forceValidOption != null)
addParameter("forceValidOption", findValue(forceValidOption,
Boolean.class));
if (searchType != null) {
String type = findString(searchType);
if(type != null)
addParameter("searchType", type.toUpperCase());
}
if (autoComplete != null)
addParameter("autoComplete", findValue(autoComplete, Boolean.class));
if (delay != null)
addParameter("delay", findValue(delay, Integer.class));
if (disabled != null)
addParameter("disabled", findValue(disabled, Boolean.class));
if (href != null) {
addParameter("href", findString(href));
addParameter("mode", "remote");
}
if (dropdownHeight != null)
addParameter("dropdownHeight", findValue(dropdownHeight, Integer.class));
if (dropdownWidth != null)
addParameter("dropdownWidth", findValue(dropdownWidth, Integer.class));
if (formFilter != null)
addParameter("formFilter", findString(formFilter));
if (formId != null)
addParameter("formId", findString(formId));
if (listenTopics != null)
addParameter("listenTopics", findString(listenTopics));
if (notifyTopics != null)
addParameter("notifyTopics", findString(notifyTopics));
if (indicator != null)
addParameter("indicator", findString(indicator));
if (loadOnTextChange != null)
addParameter("loadOnTextChange", findValue(loadOnTextChange, Boolean.class));
if (loadMinimumCount != null)
addParameter("loadMinimumCount", findValue(loadMinimumCount, Integer.class));
if (showDownArrow != null)
addParameter("showDownArrow", findValue(showDownArrow, Boolean.class));
else
addParameter("showDownArrow", Boolean.TRUE);
if(templateCssPath != null)
addParameter("templateCssPath", findString(templateCssPath));
if(iconPath != null)
addParameter("iconPath", findString(iconPath));
if(dataFieldName != null)
addParameter("dataFieldName", findString(dataFieldName));
if(keyName != null)
addParameter("keyName", findString(keyName));
else {
keyName = name + "Key";
addParameter("keyName", findString(keyName));
}
String keyNameExpr = "%{" + keyName + "}";
addParameter("key", findString(keyNameExpr));
}
protected Object findListValue() {
return (list != null) ? findValue(list, Object.class) : null;
}
@StrutsTagAttribute(description="Whether autocompleter should make suggestion on the textbox", type="Boolean", defaultValue="false")
public void setAutoComplete(String autoComplete) {
this.autoComplete = autoComplete;
}
@StrutsTagAttribute(description="Enable or disable autocompleter", type="Boolean", defaultValue="false")
public void setDisabled(String disabled) {
this.disabled = disabled;
}
@StrutsTagAttribute(description="Force selection to be one of the options", type="Boolean", defaultValue="false")
public void setForceValidOption(String forceValidOption) {
this.forceValidOption = forceValidOption;
}
@StrutsTagAttribute(description="The URL used to load the options")
public void setHref(String href) {
this.href = href;
}
@StrutsTagAttribute(description="Delay before making the search", type="Integer", defaultValue="100")
public void setDelay(String searchDelay) {
this.delay = searchDelay;
}
@StrutsTagAttribute(description="how the search must be performed, options are: 'startstring', 'startword' " +
"and 'substring'", defaultValue="stringstart")
public void setSearchType(String searchType) {
this.searchType = searchType;
}
@StrutsTagAttribute(description="Dropdown's height in pixels", type="Integer", defaultValue="120")
public void setDropdownHeight(String height) {
this.dropdownHeight = height;
}
@StrutsTagAttribute(description="Dropdown's width", type="Integer", defaultValue="same as textbox")
public void setDropdownWidth(String width) {
this.dropdownWidth = width;
}
@StrutsTagAttribute(description="Function name used to filter the fields of the form")
public void setFormFilter(String formFilter) {
this.formFilter = formFilter;
}
@StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
public void setFormId(String formId) {
this.formId = formId;
}
@StrutsTagAttribute(description="Topic that will trigger a reload")
public void setListenTopics(String listenTopics) {
this.listenTopics = listenTopics;
}
@StrutsTagAttribute(description="Topics that will be published when content is reloaded")
public void setNotifyTopics(String onValueChangedPublishTopic) {
this.notifyTopics = onValueChangedPublishTopic;
}
@StrutsTagAttribute(description="Id of element that will be shown while request is made")
public void setIndicator(String indicator) {
this.indicator = indicator;
}
@StrutsTagAttribute(description="Minimum number of characters that will force the content to be loaded", type="Integer", defaultValue="3")
public void setLoadMinimumCount(String loadMinimumCount) {
this.loadMinimumCount = loadMinimumCount;
}
@StrutsTagAttribute(description="Options will be reloaded everytime a character is typed on the textbox", type="Boolean", defaultValue="true")
public void setLoadOnTextChange(String loadOnType) {
this.loadOnTextChange = loadOnType;
}
@StrutsTagAttribute(description="Show or hide the down arrow button", type="Boolean", defaultValue="true")
public void setShowDownArrow(String showDownArrow) {
this.showDownArrow = showDownArrow;
}
// Override as not required
@StrutsTagAttribute(description="Iteratable source to populate from.")
public void setList(String list) {
super.setList(list);
}
@StrutsTagAttribute(description="Template css path")
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
@StrutsTagAttribute(description="Path to icon used for the dropdown")
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
@StrutsTagAttribute(description="Name of the field to which the selected key will be assigned")
public void setKeyName(String keyName) {
this.keyName = keyName;
}
@StrutsTagAttribute(description="Name of the field in the returned JSON object that contains the data array", defaultValue="Value specified in 'name'")
public void setDataFieldName(String dataFieldName) {
this.dataFieldName = dataFieldName;
}
}
@@ -0,0 +1,324 @@
/*
* $Id: DateTimePicker.java 512580 2007-02-28 02:48:06Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
* <p>
* Renders a date/time picker in a dropdown container.
* </p>
* <p>
* A stand-alone DateTimePicker widget that makes it easy to select a date/time, or increment by week, month,
* and/or year.
* </p>
*
* <p>
* It is possible to customize the user-visible formatting with either the
* 'formatLength' (long, short, medium or full) or 'displayFormat' attributes. By defaulty current
* locale will be used.</p>
* </p>
*
* Syntax supported by 'displayFormat' is (http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns):-
* <table border="1">
* <tr>
* <td>Format</td>
* <td>Description</td>
* </tr>
* <tr>
* <td>d</td>
* <td>Day of the month</td>
* </tr>
* <tr>
* <td>D</td>
* <td>Day of year</td>
* </tr>
* <tr>
* <td>M</td>
* <td>Month - Use one or two for the numerical month, three for the abbreviation, or four for the full name, or 5 for the narrow name.</td>
* </tr>
* <tr>
* <td>h</td>
* <td>Hour [1-12].</td>
* </tr>
* <tr>
* <td>H</td>
* <td>Hour [0-23].</td>
* </tr>
* <tr>
* <td>m</td>
* <td>Minute. Use one or two for zero padding.</td>
* </tr>
* <tr>
* <td>s</td>
* <td>Second. Use one or two for zero padding.</td>
* </tr>
* </table>
*
* <p>
* The value sent to the server is
* typically a locale-independent value in a hidden field as defined by the name
* attribute. RFC3339 representation is the format used.
* </p>
*
* <p/>
*
* <!-- END SNIPPET: javadoc -->
*
* <b>Examples</b>
*
* <pre>
* <!-- START SNIPPET: expl1 -->
*
* Example 1:
* &lt;s:datetimepicker name="order.date" label="Order Date" /&gt;
* Example 2:
* &lt;s:datetimepicker name="delivery.date" label="Delivery Date" format="yyyy-MM-dd" /&gt;
*
* <!-- END SNIPPET: expl1 -->
* </pre>
* <p/>
*
* <!-- START SNIPPET: expldesc2 -->
*
* The css could be changed by using the following :-
*
* <!-- END SNIPPET: expldesc2 -->
*
* <pre>
* <!-- START SNIPPET: expl2 -->
*
* &lt;s:datetimepicker name="birthday" label="Birthday" templateCss="...." /&gt;
*
* <!-- END SNIPPET: expl2 -->
* </pre>
*
*/
@StrutsTag(name="datetimepicker", tldTagClass="org.apache.struts2.views.jsp.ui.DateTimePickerTag", description="Render datetimepicker")
@StrutsTagSkipInheritance
public class DateTimePicker extends UIBean {
final public static String TEMPLATE = "datetimepicker";
final private static SimpleDateFormat RFC3339_FORMAT = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss");
final protected static Log LOG = LogFactory.getLog(DateTimePicker.class);
protected String iconPath;
protected String formatLength;
protected String displayFormat;
protected String toggleType;
protected String toggleDuration;
protected String type;
protected String displayWeeks;
protected String adjustWeeks;
protected String startDate;
protected String endDate;
protected String weekStartsOn;
protected String staticDisplay;
protected String dayWidth;
protected String language;
protected String templateCssPath;
public DateTimePicker(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
protected String getDefaultTemplate() {
return TEMPLATE;
}
public void evaluateParams() {
super.evaluateParams();
if(displayWeeks != null)
addParameter("displayWeeks", findString(displayWeeks));
if(adjustWeeks != null)
addParameter("adjustWeeks", findValue(adjustWeeks, Boolean.class));
if(startDate != null)
addParameter("startDate", findString(startDate));
if(endDate != null)
addParameter("endDate", findString(endDate));
if(weekStartsOn != null)
addParameter("weekStartsOn", findString(weekStartsOn));
if(staticDisplay != null)
addParameter("staticDisplay", findValue(staticDisplay, Boolean.class));
if(dayWidth != null)
addParameter("dayWidth", findValue(dayWidth, Integer.class));
if(language != null)
addParameter("language", findString(language));
if(value != null)
addParameter("value", findString(value));
if(iconPath != null)
addParameter("iconPath", findString(iconPath));
if(formatLength != null)
addParameter("formatLength", findString(formatLength));
if(displayFormat != null)
addParameter("displayFormat", findString(displayFormat));
if(toggleType != null)
addParameter("toggleType", findString(toggleType));
if(toggleDuration != null)
addParameter("toggleDuration", findValue(toggleDuration,
Integer.class));
if(type != null)
addParameter("type", findString(type));
else
addParameter("type", "date");
if(templateCssPath != null)
addParameter("templateCssPath", findString(templateCssPath));
// format the value to RFC 3399
if(parameters.containsKey("value")) {
parameters.put("nameValue", format(parameters.get("value")));
} else {
if(name != null) {
String expr = name;
if(altSyntax()) {
expr = "%{" + expr + "}";
}
addParameter("nameValue", format(findValue(expr)));
}
}
}
@StrutsTagAttribute(description="If true, weekly size of calendar changes to acomodate the month if false," +
" 42 day format is used", type="Boolean", defaultValue="false")
public void setAdjustWeeks(String adjustWeeks) {
this.adjustWeeks = adjustWeeks;
}
@StrutsTagAttribute(description="How to render the names of the days in the header(narrow, abbr or wide)", defaultValue="narrow")
public void setDayWidth(String dayWidth) {
this.dayWidth = dayWidth;
}
@StrutsTagAttribute(description="Total weeks to display", type="Integer", defaultValue="6")
public void setDisplayWeeks(String displayWeeks) {
this.displayWeeks = displayWeeks;
}
@StrutsTagAttribute(description="Last available date in the calendar set", type="Date", defaultValue="2941-10-12")
public void setEndDate(String endDate) {
this.endDate = endDate;
}
@StrutsTagAttribute(description="First available date in the calendar set", type="Date", defaultValue="1492-10-12")
public void setStartDate(String startDate) {
this.startDate = startDate;
}
@StrutsTagAttribute(description="Disable all incremental controls, must pick a date in the current display", type="Boolean", defaultValue="false")
public void setStaticDisplay(String staticDisplay) {
this.staticDisplay = staticDisplay;
}
@StrutsTagAttribute(description="Adjusts the first day of the week 0==Sunday..6==Saturday", type="Integer", defaultValue="0")
public void setWeekStartsOn(String weekStartsOn) {
this.weekStartsOn = weekStartsOn;
}
@StrutsTagAttribute(description="Language to display this widget in", defaultValue="brower's specified preferred language")
public void setLanguage(String language) {
this.language = language;
}
@StrutsTagAttribute(description="A pattern used for the visual display of the formatted date, e.g. dd/MM/yyyy")
public void setDisplayFormat(String displayFormat) {
this.displayFormat = displayFormat;
}
@StrutsTagAttribute(description="Type of formatting used for visual display. Possible values are " +
"long, short, medium or full", defaultValue="short")
public void setFormatLength(String formatLength) {
this.formatLength = formatLength;
}
@StrutsTagAttribute(description="Path to icon used for the dropdown")
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
@StrutsTagAttribute(description="Duration of toggle in milliseconds", type="Integer", defaultValue="100")
public void setToggleDuration(String toggleDuration) {
this.toggleDuration = toggleDuration;
}
@StrutsTagAttribute(description="Defines the type of the picker on the dropdown. Possible values are 'date'" +
" for a DateTimePicker, and 'time' for a timePicker", defaultValue="date")
public void setType(String type) {
this.type = type;
}
@StrutsTagAttribute(description="oggle type of the dropdown. Possible values are plain,wipe,explode,fade", defaultValue="plain")
public void setToggleType(String toggleType) {
this.toggleType = toggleType;
}
@StrutsTagAttribute(description="Template css path")
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
private String format(Object obj) {
if(obj == null)
return null;
if(obj instanceof Date) {
return RFC3339_FORMAT.format((Date) obj);
} else {
// try to parse a date
String dateStr = obj.toString();
if(dateStr.equalsIgnoreCase("today"))
return RFC3339_FORMAT.format(new Date());
try {
Date date = null;
if(this.displayFormat != null) {
SimpleDateFormat format = new SimpleDateFormat(
(String) getParameters().get("displayFormat"));
date = format.parse(dateStr);
return RFC3339_FORMAT.format(date);
} else {
// last resource to assume already in correct/default format
return dateStr;
}
} catch (ParseException e) {
LOG.error("Could not parse date", e);
return dateStr;
}
}
}
}
@@ -0,0 +1,193 @@
/*
* $Id: Div.java 511300 2007-02-24 16:41:38Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
* The div tag when used on the ajax theme, provides a remote call
* from the current page to update a section of content without having to refresh the entire page.
* <p>
* It creates a HTML &lt;DIV /&gt; that obtains it's content via a remote XMLHttpRequest call via
* the dojo framework.
* </p>
* <div>
* <!-- START SNIPPET: ajaxJavadoc -->
* <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
* <ul>
* <li>href</li>
* <li>errorText</li>
* <li>afterLoading</li>
* <li>executeScripts</li>
* <li>loadingText</li>
* <li>listenTopics</li>
* <li>handler</li>
* <li>formId</li>
* <li>formFilter</li>
* <li>targets</li>
* <li>notifyTopics</li>
* <li>showErrorTransportText</li>
* <li>indicator</li>
* </ul>
* 'targets' is a list of element ids whose content will be updated with the
* text returned from request.<p/>
* 'href' needs to be set as an url tag reference value.<p/>
* 'errorText' is the text that will be displayed when there is an error making the request.<p/>
* 'afterLoading' Deprecated. Use 'notifyTopics'.<p/>
* 'executeScripts' if set to true will execute javascript sections in the returned text.<p/>
* 'loadingText' is the text that will be displayed on the 'targets' elements while making the
* request.<p/>
* 'handler' is the name of the function that will take care of making the AJAX request. Dojo's widget
* and dom node are passed as parameters).<p/>
* 'formId' is the id of the html form whose fields will be seralized and passed as parameters
* in the request.<p/>
* 'formFilter' is the name of a function which will be used to filter the fields that will be
* seralized. This function takes as a parameter the element and returns true if the element
* should be included.<p/>
* 'updateFreq' sets(in milliseconds) the update interval.<p/>
* 'autoStart' if set to true(true by default) starts the timer automatically<p/>
* 'startTimerListenTopics' is a comma-separated list of topics used to start the timer<p/>
* 'stopTimerListenTopics' is a comma-separated list of topics used to stop the timer<p/>
* 'listenTopics' comma separated list of topics names, that will trigger a request<p/>
* 'indicator' element to be shown while the request executing<p/>
* 'showErrorTransportText': whether errors should be displayed (on 'targets')</p>
* 'showLoadingText' show loading text on targets</p>
* 'separateScript' Run scripts in a separate scope, unique for each Div<p/>
* 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
* <ul>
* <li>data: html or json object when type='load' or type='error'</li>
* <li>type: 'before' before the request is made, 'load' when the request succeeds, or 'error' when it fails</li>
* <li>request: request javascript object, when type='load' or type='error'</li>
* </ul>
* <!-- END SNIPPET: javadoc -->
* </div><p> <b>Examples</b>
*
* <pre>
* <!-- START SNIPPET: example -->
* &lt;s:url id="url" action="AjaxTest" />
* &lt;s:div
* id=&quot;once&quot;
* theme=&quot;ajax&quot;
* href=&quot;%{url}&quot;
* loadingText=&quot;Loading...&quot;
* listenTopics=&quot;/refresh&quot;
* updateFreq=&quot;3000&quot;
* autoStart=&quot;true&quot;
* formId=&quot;form&quot;
*&gt;&lt;/s:div&gt;
* <!-- END SNIPPET: example -->
* </pre>
* </p>
*
*/
@StrutsTag(name="div", tldTagClass="org.apache.struts2.views.jsp.ui.DivTag", description="Render HTML div providing content from remote call via AJAX")
public class Div extends AbstractRemoteCallUIBean {
public static final String TEMPLATE = "div";
public static final String TEMPLATE_CLOSE = "div-close";
public static final String COMPONENT_NAME = Div.class.getName();
protected String updateFreq;
protected String autoStart;
protected String delay;
protected String startTimerListenTopics;
protected String stopTimerListenTopics;
protected String refreshOnShow;
protected String separateScripts;
public Div(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
public String getDefaultOpenTemplate() {
return TEMPLATE;
}
protected String getDefaultTemplate() {
return TEMPLATE_CLOSE;
}
public void evaluateExtraParams() {
super.evaluateExtraParams();
if (updateFreq != null)
addParameter("updateFreq", findValue(updateFreq, Integer.class));
if (autoStart != null)
addParameter("autoStart", findValue(autoStart, Boolean.class));
if (refreshOnShow != null)
addParameter("refreshOnShow", findValue(refreshOnShow, Boolean.class));
if (delay != null)
addParameter("delay", findValue(delay, Integer.class));
if (startTimerListenTopics != null)
addParameter("startTimerListenTopics", findString(startTimerListenTopics));
if (stopTimerListenTopics != null)
addParameter("stopTimerListenTopics", findString(stopTimerListenTopics));
if (separateScripts != null)
addParameter("separateScripts", findValue(separateScripts, Boolean.class));
}
@StrutsTagAttribute(description="Start timer automatically", type="Boolean", defaultValue="true")
public void setAutoStart(String autoStart) {
this.autoStart = autoStart;
}
@StrutsTagAttribute(description="How long to wait before fetching the content (in milliseconds)", type="Integer")
public void setDelay(String delay) {
this.delay = delay;
}
@StrutsTagAttribute(description="How often to reload the content (in milliseconds)", type="Integer")
public void setUpdateFreq(String updateInterval) {
this.updateFreq = updateInterval;
}
@StrutsTagAttribute(description="Topics that will start the timer (for autoupdate)")
public void setStartTimerListenTopics(String startTimerListenTopic) {
this.startTimerListenTopics = startTimerListenTopic;
}
@StrutsTagAttribute(description="Topics that will stop the timer (for autoupdate)")
public void setStopTimerListenTopics(String stopTimerListenTopic) {
this.stopTimerListenTopics = stopTimerListenTopic;
}
@StrutsTagAttribute(description="Content will be loaded when div becomes visible, used only inside tabbedPanel", type="Boolean", defaultValue="false")
public void setRefreshOnShow(String refreshOnShow) {
this.refreshOnShow = refreshOnShow;
}
@StrutsTagAttribute(description="Deprecated. Use 'notifyTopics'. Javascript code execute after reload")
public void setAfterLoading(String afterLoading) {
this.afterLoading = afterLoading;
}
@StrutsTagAttribute(description="Run scripts in a separate scope, unique for each Div", defaultValue="true")
public void setSeparateScripts(String separateScripts) {
this.separateScripts = separateScripts;
}
}
@@ -0,0 +1,54 @@
/*
* $Id: RemoteUICallBean.java 508285 2007-02-16 02:42:24Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
public interface RemoteUICallBean {
void setListenTopics(String topics);
void setNotifyTopics(String topics);
void setHref(String href);
void setErrorText(String errorText);
void setAfterLoading(String afterLoading);
void setBeforeLoading(String beforeLoading);
void setExecuteScripts(String executeScripts);
void setLoadingText(String loadingText);
void setHandler(String handler);
void setFormFilter(String formFilter);
void setFormId(String formId);
void setShowErrorTransportText(String showError);
void setShowLoadingText(String showLoadingText);
void setIndicator(String indicator);
}
@@ -0,0 +1,340 @@
/*
* $Id: Submit.java 508285 2007-02-16 02:42:24Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
* Render a submit button. The submit tag is used together with the form tag to provide asynchronous form submissions.
* The submit can have three different types of rendering:
* <ul>
* <li>input: renders as html &lt;input type="submit"...&gt;</li>
* <li>image: renders as html &lt;input type="image"...&gt;</li>
* <li>button: renders as html &lt;button type="submit"...&gt;</li>
* </ul>
* Please note that the button type has advantages by adding the possibility to seperate the submitted value from the
* text shown on the button face, but has issues with Microsoft Internet Explorer at least up to 6.0
* <!-- END SNIPPET: javadoc -->
*
* <p/> <b>Examples</b>
* <pre>
* <!-- START SNIPPET: example -->
* &lt;s:submit value="%{'Submit'}" /&gt;
* <!-- END SNIPPET: example -->
* </pre>
* <pre>
* <!-- START SNIPPET: example2 -->
* Render an image submit:
* &lt;s:submit type="image" value="%{'Submit'}" label="Submit the form" src="submit.gif"/&gt;
* <!-- END SNIPPET: example2 -->
* </pre>
* <pre>
* <!-- START SNIPPET: example3 -->
* Render an button submit:
* &lt;s:submit type="button" value="%{'Submit'}" label="Submit the form"/&gt;
* <!-- END SNIPPET: example3 -->
* </pre>
*
* <!-- START SNIPPET: ajaxJavadoc -->
* <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
* <ul>
* <li>href</li>
* <li>errorText</li>
* <li>listenTopics</li>
* <li>notifyTopics</li>
* <li>executeScripts</li>
* <li>loadingText</li>
* <li>listenTopics</li>
* <li>handler</li>
* <li>formId</li>
* <li>formFilter</li>
* <li>targets</li>
* <li>showErrorTransportText</li>
* <li>targets</li>
* <li>indicator</li>
* </ul>
* 'resultDivId' Deprecated. Use targets.</p>
* 'targets' is a list of element ids whose content will be updated with the
* text returned from request.<p/>
* 'errorText' is the text that will be displayed when there is an error making the request.<p/>
* 'onLoadJS' Deprecated. Use 'notifyTopics'.<p/>
* 'preInvokeJS' Deprecated. Use 'notifyTopics'.<p/>
* 'executeScripts' if set to true will execute javascript sections in the returned text.<p/>
* 'loadingText' is the text that will be displayed on the 'targets' elements while making the
* request.<p/>
* 'handler' is the name of the function that will take care of making the AJAX request. Dojo's widget
* and dom node are passed as parameters).<p/>
* 'formId' is the id of the html form whose fields will be seralized and passed as parameters
* in the request.<p/>
* 'formFilter' is the name of a function which will be used to filter the fields that will be
* seralized. This function takes as a parameter the element and returns true if the element
* should be included.<p/>
* 'listenTopics' comma separated list of topics names, that will trigger a request
* 'indicator' element to be shown while the request executing
* 'showErrorTransportText': whether errors should be displayed (on 'targets')</p>
* 'showLoadingText' show loading text on targets</p>
* 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
* <ul>
* <li>data: html or json object when type='load' or type='error'</li>
* <li>type: 'before' before the request is made, 'load' when the request succeeds, or 'error' when it fails</li>
* <li>request: request javascript object, when type='load' or type='error'</li>
* </ul>
* <!-- END SNIPPET: ajaxJavadoc -->
*
* <!-- START SNIPPET: ajxExDescription1 -->
* Show the results in another div. If you want your results to be shown in
* a div, use the resultDivId where the id is the id of the div you want them
* shown in. This is an inner HTML approah. Your results get jammed into
* the div for you. Here is a sample of this approach:
* <!-- END SNIPPET: ajxExDescription1 -->
*
* <pre>
* <!-- START SNIPPET: ajxExample1 -->
* Remote form replacing another div:
* &lt;div id='two' style="border: 1px solid yellow;"&gt;Initial content&lt;/div&gt;
* &lt;s:form
* id='theForm2'
* cssStyle="border: 1px solid green;"
* action='/AjaxRemoteForm.action'
* method='post'
* theme="ajax"&gt;
*
* &lt;input type='text' name='data' value='Struts User' /&gt;
* &lt;s:submit value="GO2" theme="ajax" resultDivId="two" /&gt;
*
* &lt;/s:form &gt;
* <!-- END SNIPPET: ajxExample1 -->
* </pre>
*
*/
@StrutsTag(name="submit", tldTagClass="org.apache.struts2.views.jsp.ui.SubmitTag", description="Render a submit button")
@StrutsTagSkipInheritance
public class Submit extends FormButton implements RemoteUICallBean {
private static final Log LOG = LogFactory.getLog(Submit.class);
final public static String TEMPLATE = "submit";
protected String href;
protected String errorText;
protected String executeScripts;
protected String loadingText;
protected String listenTopics;
protected String handler;
protected String formId;
protected String formFilter;
protected String src;
protected String notifyTopics;
protected String showErrorTransportText;
protected String indicator;
protected String showLoadingText;
//these two are called "preInvokeJS" and "onLoadJS" on the tld
//Names changed here to keep some consistency
protected String beforeLoading;
protected String afterLoading;
//this one is called "resultDivId" on the tld
protected String targets;
public Submit(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
protected String getDefaultTemplate() {
return TEMPLATE;
}
public void evaluateParams() {
if ((key == null) && (value == null)) {
value = "Submit";
}
if (((key != null)) && (value == null)) {
this.value = "%{getText('"+key +"')}";
}
super.evaluateParams();
}
public void evaluateExtraParams() {
super.evaluateExtraParams();
if (href != null)
addParameter("href", findString(href));
if (errorText != null)
addParameter("errorText", findString(errorText));
if (loadingText != null)
addParameter("loadingText", findString(loadingText));
if (afterLoading != null)
addParameter("afterLoading", findString(afterLoading));
if (beforeLoading != null)
addParameter("beforeLoading", findString(beforeLoading));
if (executeScripts != null)
addParameter("executeScripts", findValue(executeScripts, Boolean.class));
if (listenTopics != null)
addParameter("listenTopics", findString(listenTopics));
if (notifyTopics != null)
addParameter("notifyTopics", findString(notifyTopics));
if (handler != null)
addParameter("handler", findString(handler));
if (formId != null)
addParameter("formId", findString(formId));
if (formFilter != null)
addParameter("formFilter", findString(formFilter));
if (src != null)
addParameter("src", findString(src));
if (indicator != null)
addParameter("indicator", findString(indicator));
if (targets != null)
addParameter("targets", findString(targets));
if (showLoadingText != null)
addParameter("showLoadingText", findString(showLoadingText));
}
/**
* Indicate whether the concrete button supports the type "image".
*
* @return <tt>true</tt> to indicate type image is supported.
*/
protected boolean supportsImageType() {
return true;
}
/**
* Overrides to be able to render body in a template rather than always before the template
*/
public boolean end(Writer writer, String body) {
evaluateParams();
try {
addParameter("body", body);
mergeTemplate(writer, buildTemplateName(template, getDefaultTemplate()));
} catch (Exception e) {
LOG.error("error when rendering", e);
}
finally {
popComponentStack();
}
return false;
}
@StrutsTagAttribute(description="Topic that will trigger the remote call")
public void setListenTopics(String listenTopics) {
this.listenTopics = listenTopics;
}
@StrutsTagAttribute(description="The theme to use for the element. <b>This tag will usually use the ajax theme.</b>")
public void setTheme(String theme) {
super.setTheme(theme);
}
@StrutsTagAttribute(description="The URL to call to obtain the content. Note: If used with ajax context, the value must be set as an url tag value.")
public void setHref(String href) {
this.href = href;
}
@StrutsTagAttribute(description="The text to display to the user if the is an error fetching the content")
public void setErrorText(String errorText) {
this.errorText = errorText;
}
@StrutsTagAttribute(name="onLoadJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute after reload")
public void setAfterLoading(String afterLoading) {
this.afterLoading = afterLoading;
}
@StrutsTagAttribute(name="preInvokeJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute before reload")
public void setBeforeLoading(String beforeLoading) {
this.beforeLoading = beforeLoading;
}
@StrutsTagAttribute(description="Javascript code in the fetched content will be executed", type="Boolean", defaultValue="false")
public void setExecuteScripts(String executeScripts) {
this.executeScripts = executeScripts;
}
@StrutsTagAttribute(description="Text to be shown while content is being fetched", defaultValue="Loading...")
public void setLoadingText(String loadingText) {
this.loadingText = loadingText;
}
@StrutsTagAttribute(description="Javascript function name that will make the request")
public void setHandler(String handler) {
this.handler = handler;
}
@StrutsTagAttribute(description="Function name used to filter the fields of the form.")
public void setFormFilter(String formFilter) {
this.formFilter = formFilter;
}
@StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
public void setFormId(String formId) {
this.formId = formId;
}
@StrutsTagAttribute(description="Supply an image src for <i>image</i> type submit button. Will have no effect for types <i>input</i> and <i>button</i>.")
public void setSrc(String src) {
this.src = src;
}
@StrutsTagAttribute(description="Comma delimited list of ids of the elements whose content will be updated")
public void setTargets(String targets) {
this.targets = targets;
}
@StrutsTagAttribute(description="Topics that will published when the remote call completes")
public void setNotifyTopics(String notifyTopics) {
this.notifyTopics = notifyTopics;
}
@StrutsTagAttribute(description="Set whether errors will be shown or not", type="Boolean", defaultValue="true")
public void setShowErrorTransportText(String showErrorTransportText) {
this.showErrorTransportText = showErrorTransportText;
}
@StrutsTagAttribute(description="Set indicator")
public void setIndicator(String indicator) {
this.indicator = indicator;
}
@StrutsTagAttribute(description="Show loading text on targets", type="Boolean", defaultValue="true")
public void setShowLoadingText(String showLoadingText) {
this.showLoadingText = showLoadingText;
}
}
@@ -0,0 +1,137 @@
/*
* $Id: TabbedPanel.java 508575 2007-02-16 20:46:49Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
* The tabbedpanel widget is primarily an AJAX component, where each tab can either be local content or remote
* content (refreshed each time the user selects that tab).</p>
* <!-- END SNIPPET: javadoc -->
*
* <p/> <b>Examples</b>
* <p/>
* <!-- START SNIPPET: exdesc -->
* The following is an example of a tabbedpanel and panel tag utilizing local and remote content.<p/>
* <!-- END SNIPPET: exdesc -->
* <pre>
* <!-- START SNIPPET: example -->
* &lt;s:tabbedPanel id=&quot;test&quot; &gt;
* &lt;s:div id=&quot;one&quot; label=&quot;one&quot; theme=&quot;ajax&quot; labelposition=&quot;top&quot; &gt;
* This is the first pane&lt;br/&gt;
* &lt;s:form&gt;
* &lt;s:textfield name=&quot;tt&quot; label=&quot;Test Text&quot;/&gt; &lt;br/&gt;
* &lt;s:textfield name=&quot;tt2&quot; label=&quot;Test Text2&quot;/&gt;
* &lt;/s:form&gt;
* &lt;/s:div&gt;
* &lt;s:div id=&quot;three&quot; label=&quot;remote&quot; theme=&quot;ajax&quot; href=&quot;/AjaxTest.action&quot; &gt;
* This is the remote tab
* &lt;/s:div&gt;
* &lt;/s:tabbedPanel&gt;
* <!-- END SNIPPET: example -->
* </pre>
*
*/
@StrutsTag(name="tabbedPanel", tldTagClass="org.apache.struts2.views.jsp.ui.TabbedPanelTag", description="Render a tabbedPanel widget.")
@StrutsTagSkipInheritance
public class TabbedPanel extends ClosingUIBean {
public static final String TEMPLATE = "tabbedpanel";
public static final String TEMPLATE_CLOSE = "tabbedpanel-close";
final private static String COMPONENT_NAME = TabbedPanel.class.getName();
protected String selectedTab;
protected String closeButton;
protected String doLayout ;
protected String templateCssPath;
public TabbedPanel(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
protected void evaluateExtraParams() {
super.evaluateExtraParams();
if(selectedTab != null)
addParameter("selectedTab", findString(selectedTab));
if(closeButton != null)
addParameter("closeButton", findString(closeButton));
addParameter("doLayout", doLayout != null ? findValue(doLayout, Boolean.class) : Boolean.FALSE);
if(labelPosition != null) {
//dojo has some weird name for label positions
if(labelPosition.equalsIgnoreCase("left"))
labelPosition = "left-h";
if(labelPosition.equalsIgnoreCase("right"))
labelPosition = "right-h";
addParameter("labelPosition", null);
addParameter("labelPosition", labelPosition);
}
if(templateCssPath != null)
addParameter("templateCssPath", findString(templateCssPath));
}
public String getDefaultOpenTemplate() {
return TEMPLATE;
}
protected String getDefaultTemplate() {
return TEMPLATE_CLOSE;
}
public String getComponentName() {
return COMPONENT_NAME;
}
@StrutsTagAttribute(description="The id to assign to the component.", required=true)
public void setId(String id) {
// This is required to override tld generation attributes to required=true
super.setId(id);
}
@StrutsTagAttribute(description=" The id of the tab that will be selected by default")
public void setSelectedTab(String selectedTab) {
this.selectedTab = selectedTab;
}
@StrutsTagAttribute(description="Where the close button will be placed, possible values are 'tab' and 'pane'")
public void setCloseButton(String closeButton) {
this.closeButton = closeButton;
}
@StrutsTagAttribute(description="If doLayout is false, the tab container's height equals the height of the currently selected tab", type="Boolean", defaultValue="false")
public void setDoLayout(String doLayout) {
this.doLayout = doLayout;
}
@StrutsTagAttribute(description="Template css path")
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
}
@@ -0,0 +1,435 @@
/*
* $Id: Tree.java 497654 2007-01-19 00:21:57Z rgielen $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
*
* Renders a tree widget with AJAX support.<p/>
*
* The id attribute is normally specified, such that it could be looked up using
* javascript if necessary.<p/>
*
* <!-- END SNIPPET: javadoc -->
*
* <p/> <b>Examples</b>
*
* <pre>
* <!-- START SNIPPET: example -->
*
* &lt-- statically --&gt;
* &lt;s:tree id="..." label="..."&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &lt;s:treenode id="..." label="..."&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &;lt;/s:treenode&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &lt;/s:tree&gt;
*
* &lt;-- dynamically --&gt;
* &lt;s:tree
* id="..."
* rootNode="..."
* nodeIdProperty="..."
* nodeTitleProperty="..."
* childCollectionProperty="..." /&gt;
*
* <!-- END SNIPPET: example -->
* </pre>
*
*/
@StrutsTag(name="tree", tldTagClass="org.apache.struts2.views.jsp.ui.TreeTag", description="Render a tree widget.")
@StrutsTagSkipInheritance
public class Tree extends ClosingUIBean {
private static final String TEMPLATE = "tree-close";
private static final String OPEN_TEMPLATE = "tree";
private String toggle = "fade";
private String treeSelectedTopic;
private String treeExpandedTopic;
private String treeCollapsedTopic;
protected String rootNodeAttr;
protected String childCollectionProperty;
protected String nodeTitleProperty;
protected String nodeIdProperty;
private String showRootGrid;
private String showGrid;
private String blankIconSrc;
private String gridIconSrcL;
private String gridIconSrcV;
private String gridIconSrcP;
private String gridIconSrcC;
private String gridIconSrcX;
private String gridIconSrcY;
private String expandIconSrcPlus;
private String expandIconSrcMinus;
private String iconWidth;
private String iconHeight;
private String toggleDuration;
private String templateCssPath;
public Tree(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
public boolean start(Writer writer) {
boolean result = super.start(writer);
if (this.label == null) {
if ((rootNodeAttr == null)
|| (childCollectionProperty == null)
|| (nodeTitleProperty == null)
|| (nodeIdProperty == null)) {
fieldError("label","The TreeTag requires either a value for 'label' or ALL of 'rootNode', " +
"'childCollectionProperty', 'nodeTitleProperty', and 'nodeIdProperty'", null);
}
}
return result;
}
protected void evaluateExtraParams() {
super.evaluateExtraParams();
if (toggle != null) {
addParameter("toggle", findString(toggle));
}
if (treeSelectedTopic != null) {
addParameter("treeSelectedTopic", findString(treeSelectedTopic));
}
if (treeExpandedTopic != null) {
addParameter("treeExpandedTopic", findString(treeExpandedTopic));
}
if (treeCollapsedTopic != null) {
addParameter("treeCollapsedTopic", findString(treeCollapsedTopic));
}
if (rootNodeAttr != null) {
addParameter("rootNode", findValue(rootNodeAttr));
}
if (childCollectionProperty != null) {
addParameter("childCollectionProperty", findString(childCollectionProperty));
}
if (nodeTitleProperty != null) {
addParameter("nodeTitleProperty", findString(nodeTitleProperty));
}
if (nodeIdProperty != null) {
addParameter("nodeIdProperty", findString(nodeIdProperty));
}
if (showRootGrid != null) {
addParameter("showRootGrid", findValue(showRootGrid, Boolean.class));
}
if (showGrid != null) {
addParameter("showGrid", findValue(showGrid, Boolean.class));
}
if (blankIconSrc != null) {
addParameter("blankIconSrc", findString(blankIconSrc));
}
if (gridIconSrcL != null) {
addParameter("gridIconSrcL", findString(gridIconSrcL));
}
if (gridIconSrcV != null) {
addParameter("gridIconSrcV", findString(gridIconSrcV));
}
if (gridIconSrcP != null) {
addParameter("gridIconSrcP", findString(gridIconSrcP));
}
if (gridIconSrcC != null) {
addParameter("gridIconSrcC", findString(gridIconSrcC));
}
if (gridIconSrcX != null) {
addParameter("gridIconSrcX", findString(gridIconSrcX));
}
if (gridIconSrcY != null) {
addParameter("gridIconSrcY", findString(gridIconSrcY));
}
if (expandIconSrcPlus != null) {
addParameter("expandIconSrcPlus", findString(expandIconSrcPlus));
}
if (expandIconSrcMinus != null) {
addParameter("expandIconSrcMinus", findString(expandIconSrcMinus));
}
if (iconWidth != null) {
addParameter("iconWidth", findValue(iconWidth, Integer.class));
}
if (iconHeight != null) {
addParameter("iconHeight", findValue(iconHeight, Integer.class));
}
if (toggleDuration != null) {
addParameter("toggleDuration", findValue(toggleDuration, Integer.class));
}
if (templateCssPath != null) {
addParameter("templateCssPath", findString(templateCssPath));
}
}
public String getDefaultOpenTemplate() {
return OPEN_TEMPLATE;
}
protected String getDefaultTemplate() {
return TEMPLATE;
}
public String getToggle() {
return toggle;
}
@StrutsTagAttribute(description="The toggle property (either 'explode' or 'fade')", defaultValue="fade")
public void setToggle(String toggle) {
this.toggle = toggle;
}
public String getTreeSelectedTopic() {
return treeSelectedTopic;
}
@StrutsTagAttribute(description="The treeSelectedTopic property")
public void setTreeSelectedTopic(String treeSelectedTopic) {
this.treeSelectedTopic = treeSelectedTopic;
}
public String getTreeExpandedTopic() {
return treeExpandedTopic;
}
@StrutsTagAttribute(description="The treeExpandedTopic property.")
public void setTreeExpandedTopic(String treeExpandedTopic) {
this.treeExpandedTopic = treeExpandedTopic;
}
public String getTreeCollapsedTopic() {
return treeCollapsedTopic;
}
@StrutsTagAttribute(description="The treeCollapsedTopic property.")
public void setTreeCollapsedTopic(String treeCollapsedTopic) {
this.treeCollapsedTopic = treeCollapsedTopic;
}
public String getRootNode() {
return rootNodeAttr;
}
@StrutsTagAttribute(description="The rootNode property.")
public void setRootNode(String rootNode) {
this.rootNodeAttr = rootNode;
}
public String getChildCollectionProperty() {
return childCollectionProperty;
}
@StrutsTagAttribute(description="The childCollectionProperty property.")
public void setChildCollectionProperty(String childCollectionProperty) {
this.childCollectionProperty = childCollectionProperty;
}
public String getNodeTitleProperty() {
return nodeTitleProperty;
}
@StrutsTagAttribute(description="The nodeTitleProperty property.")
public void setNodeTitleProperty(String nodeTitleProperty) {
this.nodeTitleProperty = nodeTitleProperty;
}
public String getNodeIdProperty() {
return nodeIdProperty;
}
@StrutsTagAttribute(description="The nodeIdProperty property.")
public void setNodeIdProperty(String nodeIdProperty) {
this.nodeIdProperty = nodeIdProperty;
}
@StrutsTagAttribute(description="The showRootGrid property (default true).")
public void setShowRootGrid(String showRootGrid) {
this.showRootGrid = showRootGrid;
}
public String getShowRootGrid() {
return showRootGrid;
}
public String getBlankIconSrc() {
return blankIconSrc;
}
@StrutsTagAttribute(description="Blank icon image source.")
public void setBlankIconSrc(String blankIconSrc) {
this.blankIconSrc = blankIconSrc;
}
public String getExpandIconSrcMinus() {
return expandIconSrcMinus;
}
@StrutsTagAttribute(description="Expand icon (-) image source.")
public void setExpandIconSrcMinus(String expandIconSrcMinus) {
this.expandIconSrcMinus = expandIconSrcMinus;
}
public String getExpandIconSrcPlus() {
return expandIconSrcPlus;
}
@StrutsTagAttribute(description="Expand Icon (+) image source.")
public void setExpandIconSrcPlus(String expandIconSrcPlus) {
this.expandIconSrcPlus = expandIconSrcPlus;
}
public String getGridIconSrcC() {
return gridIconSrcC;
}
@StrutsTagAttribute(description="Image source for under child item child icons.")
public void setGridIconSrcC(String gridIconSrcC) {
this.gridIconSrcC = gridIconSrcC;
}
public String getGridIconSrcL() {
return gridIconSrcL;
}
@StrutsTagAttribute(description=" Image source for last child grid.")
public void setGridIconSrcL(String gridIconSrcL) {
this.gridIconSrcL = gridIconSrcL;
}
public String getGridIconSrcP() {
return gridIconSrcP;
}
@StrutsTagAttribute(description="Image source for under parent item child icons.")
public void setGridIconSrcP(String gridIconSrcP) {
this.gridIconSrcP = gridIconSrcP;
}
public String getGridIconSrcV() {
return gridIconSrcV;
}
@StrutsTagAttribute(description="Image source for vertical line.")
public void setGridIconSrcV(String gridIconSrcV) {
this.gridIconSrcV = gridIconSrcV;
}
public String getGridIconSrcX() {
return gridIconSrcX;
}
@StrutsTagAttribute(description="Image source for grid for sole root item.")
public void setGridIconSrcX(String gridIconSrcX) {
this.gridIconSrcX = gridIconSrcX;
}
public String getGridIconSrcY() {
return gridIconSrcY;
}
@StrutsTagAttribute(description="Image source for grid for last root item.")
public void setGridIconSrcY(String gridIconSrcY) {
this.gridIconSrcY = gridIconSrcY;
}
public String getIconHeight() {
return iconHeight;
}
@StrutsTagAttribute(description="Icon height", defaultValue="18px")
public void setIconHeight(String iconHeight) {
this.iconHeight = iconHeight;
}
public String getIconWidth() {
return iconWidth;
}
@StrutsTagAttribute(description="Icon width", defaultValue="19px")
public void setIconWidth(String iconWidth) {
this.iconWidth = iconWidth;
}
public String getTemplateCssPath() {
return templateCssPath;
}
@StrutsTagAttribute(description="Template css path", defaultValue="{contextPath}/struts/tree.css.")
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
public String getToggleDuration() {
return toggleDuration;
}
@StrutsTagAttribute(description="Toggle duration in milliseconds", defaultValue="150")
public void setToggleDuration(String toggleDuration) {
this.toggleDuration = toggleDuration;
}
public String getShowGrid() {
return showGrid;
}
@StrutsTagAttribute(description="Show grid", type="Boolean", defaultValue="true")
public void setShowGrid(String showGrid) {
this.showGrid = showGrid;
}
}
@@ -0,0 +1,105 @@
/*
* $Id: TreeNode.java 497654 2007-01-19 00:21:57Z rgielen $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.annotations.StrutsTag;
import org.apache.struts2.views.annotations.StrutsTagAttribute;
import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <!-- START SNIPPET: javadoc -->
*
* Renders a tree node within a tree widget with AJAX support.<p/>
*
* Either of the following combinations should be used depending on if the tree
* is to be constrcted dynamically or statically. <p/>
*
* <b>Dynamically</b>
* <ul>
* <li>id - id of this tree node</li>
* <li>title - label to be displayed for this tree node</li>
* </ul>
*
* <b>Statically</b>
* <ul>
* <li>rootNode - the parent node of which this tree is derived from</li>
* <li>nodeIdProperty - property to obtained this current tree node's id</li>
* <li>nodeTitleProperty - property to obtained this current tree node's title</li>
* <li>childCollectionProperty - property that returnds this current tree node's children</li>
* </ul>
*
* <!-- END SNIPPET: javadoc -->
*
* <p/> <b>Examples</b>
*
* <pre>
* <!-- START SNIPPET: example -->
*
* &lt-- statically --&gt;
* &lt;s:tree id="..." label="..."&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &lt;s:treenode id="..." label="..."&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &;lt;/s:treenode&gt;
* &lt;s:treenode id="..." label="..." /&gt;
* &lt;/s:tree&gt;
*
* &lt;-- dynamically --&gt;
* &lt;s:tree
* id="..."
* rootNode="..."
* nodeIdProperty="..."
* nodeTitleProperty="..."
* childCollectionProperty="..." /&gt;
*
* <!-- END SNIPPET: example -->
* </pre>
*
*/
@StrutsTag(name="treenode", tldTagClass="org.apache.struts2.views.jsp.ui.TreeNodeTag", description="Render a tree node within a tree widget.")
@StrutsTagSkipInheritance
public class TreeNode extends ClosingUIBean {
private static final String TEMPLATE = "treenode-close";
private static final String OPEN_TEMPLATE = "treenode";
public TreeNode(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
super(stack, request, response);
}
public String getDefaultOpenTemplate() {
return OPEN_TEMPLATE;
}
protected String getDefaultTemplate() {
return TEMPLATE;
}
@StrutsTagAttribute(description="Label expression used for rendering tree node label.", required=true)
public void setLabel(String label) {
super.setLabel(label);
}
}
@@ -0,0 +1,43 @@
package org.apache.struts2.views;
import java.util.Arrays;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.views.freemarker.tags.StrutsModels;
import org.apache.struts2.views.velocity.components.AnchorDirective;
import org.apache.struts2.views.velocity.components.AutocompleterDirective;
import org.apache.struts2.views.velocity.components.DateTimePickerDirective;
import org.apache.struts2.views.velocity.components.DivDirective;
import org.apache.struts2.views.velocity.components.SubmitDirective;
import org.apache.struts2.views.velocity.components.TabbedPanelDirective;
import org.apache.struts2.views.velocity.components.TreeDirective;
import org.apache.struts2.views.velocity.components.TreeNodeDirective;
import com.opensymphony.xwork2.util.ValueStack;
public class DojoTagLibrary implements TagLibrary {
public Object getFreemarkerModels(ValueStack stack, HttpServletRequest req,
HttpServletResponse res) {
return new StrutsModels(stack, req, res);
}
public List<Class> getVelocityDirectiveClasses() {
Class[] directives = new Class[] {
DateTimePickerDirective.class,
DivDirective.class,
AutocompleterDirective.class,
AnchorDirective.class,
SubmitDirective.class,
TabbedPanelDirective.class,
TreeDirective.class,
TreeNodeDirective.class,
};
return Arrays.asList(directives);
}
}
@@ -0,0 +1,43 @@
/*
* $Id: AutocompleterModel.java 502294 2007-02-01 17:28:00Z niallp $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.freemarker.tags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.Autocompleter;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see Autocompleter
*/
public class AutocompleterModel extends TagModel {
public AutocompleterModel(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
super(stack, req, res);
}
protected Component getBean() {
return new Autocompleter(stack, req, res);
}
}
@@ -0,0 +1,40 @@
/*
* $Id: DateTimePickerModel.java 493867 2007-01-07 22:26:23Z mrdon $
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts2.views.freemarker.tags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.DateTimePicker;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see DropdownDateTimePicker
*/
public class DateTimePickerModel extends TextFieldModel {
public DateTimePickerModel(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
super(stack, req, res);
}
protected Component getBean() {
return new DateTimePicker(stack, req, res);
}
}
@@ -0,0 +1,89 @@
package org.apache.struts2.views.freemarker.tags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.opensymphony.xwork2.util.ValueStack;
public class DojoModels {
protected DateTimePickerModel dateTimePicker;
protected TabbedPanelModel tabbedPanel;
protected TreeModel treeModel;
protected TreeNodeModel treenodeModel;
protected AutocompleterModel autocompleterModel;
protected DivModel div;
protected AnchorModel a;
protected SubmitModel submit;
private ValueStack stack;
private HttpServletRequest req;
private HttpServletResponse res;
public DojoModels(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
this.stack = stack;
this.req = req;
this.res = res;
}
public DateTimePickerModel getDatetimepicker() {
if (dateTimePicker == null) {
dateTimePicker = new DateTimePickerModel(stack, req, res);
}
return dateTimePicker;
}
public AutocompleterModel getAutocompleterModel() {
if (autocompleterModel == null) {
autocompleterModel = new AutocompleterModel(stack, req, res);
}
return autocompleterModel;
}
public TabbedPanelModel getTabbedpanelModel() {
if (tabbedPanel == null) {
tabbedPanel = new TabbedPanelModel(stack, req, res);
}
return tabbedPanel;
}
public TreeModel getTree() {
if (treeModel == null) {
treeModel = new TreeModel(stack,req, res);
}
return treeModel;
}
public TreeNodeModel getTreenode() {
if (treenodeModel == null) {
treenodeModel = new TreeNodeModel(stack, req, res);
}
return treenodeModel;
}
public DivModel getDiv() {
if (div == null) {
div = new DivModel(stack, req, res);
}
return div;
}
public AnchorModel getA() {
if (a == null) {
a = new AnchorModel(stack, req, res);
}
return a;
}
public SubmitModel getSubmit() {
if (submit == null) {
submit = new SubmitModel(stack, req, res);
}
return submit;
}
}
@@ -0,0 +1,42 @@
/*
* $Id: TabbedPanelModel.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.freemarker.tags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.TabbedPanel;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see TabbedPanel
*/
public class TabbedPanelModel extends TagModel {
public TabbedPanelModel(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
super(stack, req, res);
}
protected Component getBean() {
return new TabbedPanel(stack, req, res);
}
}
@@ -0,0 +1,44 @@
/*
* $Id: TreeModel.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.freemarker.tags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.Tree;
import com.opensymphony.xwork2.util.ValueStack;
/**
* TreeModel
* @see Tree
*
*/
public class TreeModel extends TagModel {
public TreeModel(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
super(stack, req, res);
}
protected Component getBean() {
return new Tree(stack,req,res);
}
}
@@ -0,0 +1,43 @@
/*
* $Id: TreeNodeModel.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.freemarker.tags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.TreeNode;
import com.opensymphony.xwork2.util.ValueStack;
/**
* TreeNodeModel
* @see TreeNode
*/
public class TreeNodeModel extends TagModel {
public TreeNodeModel(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
super(stack, req, res);
}
protected Component getBean() {
return new TreeNode(stack,req,res);
}
}
@@ -0,0 +1,117 @@
/*
* $Id: AbstractRemoteCallUITag.java 508285 2007-02-16 02:42:24Z musachy $
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts2.views.jsp.ui;
import org.apache.struts2.components.RemoteUICallBean;
public abstract class AbstractRemoteCallUITag extends AbstractClosingTag {
protected String href;
protected String listenTopics;
protected String notifyTopics;
protected String loadingText;
protected String errorText;
protected String beforeLoading;
protected String afterLoading;
protected String executeScripts;
protected String handler;
protected String formId;
protected String formFilter;
protected String showErrorTransportText;
protected String indicator;
protected String showLoadingText;
protected void populateParams() {
super.populateParams();
RemoteUICallBean remote = (RemoteUICallBean) component;
remote.setHref(href);
remote.setListenTopics(listenTopics);
remote.setLoadingText(loadingText);
remote.setErrorText(errorText);
remote.setAfterLoading(afterLoading);
remote.setBeforeLoading(beforeLoading);
remote.setExecuteScripts(executeScripts);
remote.setHandler(handler);
remote.setFormFilter(formFilter);
remote.setFormId(formId);
remote.setNotifyTopics(notifyTopics);
remote.setShowErrorTransportText(showErrorTransportText);
remote.setIndicator(indicator);
remote.setShowLoadingText(showLoadingText);
}
public void setHref(String href) {
this.href = href;
}
public void setErrorText(String errorText) {
this.errorText = errorText;
}
public void setLoadingText(String loadingText) {
this.loadingText = loadingText;
}
public void setListenTopics(String listenTopics) {
this.listenTopics = listenTopics;
}
public void setAfterLoading(String afterLoading) {
this.afterLoading = afterLoading;
}
public void setBeforeLoading(String beforeLoading) {
this.beforeLoading = beforeLoading;
}
public void setExecuteScripts(String executeScripts) {
this.executeScripts = executeScripts;
}
public void setHandler(String handler) {
this.handler = handler;
}
public void setFormFilter(String formFilter) {
this.formFilter = formFilter;
}
public void setFormId(String formId) {
this.formId = formId;
}
public void setNotifyTopics(String notifyTopics) {
this.notifyTopics = notifyTopics;
}
public void setShowErrorTransportText(String showErrorTransportText) {
this.showErrorTransportText = showErrorTransportText;
}
/**
* @param indicator The indicator to set.
*/
public void setIndicator(String indicator) {
this.indicator = indicator;
}
public void setShowLoadingText(String showLoadingText) {
this.showLoadingText = showLoadingText;
}
}
@@ -0,0 +1,62 @@
/*
* $Id: AnchorTag.java 490079 2006-12-24 22:46:07Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Anchor;
import org.apache.struts2.components.Component;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see Anchor
*/
public class AnchorTag extends AbstractRemoteCallUITag {
private static final long serialVersionUID = -1034616578492431113L;
protected String targets;
protected String preInvokeJS;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Anchor(stack, req, res);
}
protected void populateParams() {
super.populateParams();
Anchor link = (Anchor) component;
link.setTargets(targets);
}
public void setTargets(String targets) {
this.targets = targets;
}
@Deprecated()
public void setPreInvokeJS(String preInvokeJS) {
this.beforeLoading = preInvokeJS;
}
}
@@ -0,0 +1,171 @@
/*
* $Id$
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Autocompleter;
import org.apache.struts2.components.Component;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see Autocompleter
*/
public class AutocompleterTag extends ComboBoxTag {
private static final long serialVersionUID = -1112470447573172581L;
protected String forceValidOption;
protected String searchType;
protected String autoComplete;
protected String delay;
protected String disabled;
protected String href;
protected String dropdownWidth;
protected String dropdownHeight;
protected String formId;
protected String formFilter;
protected String listenTopics;
protected String notifyTopics;
protected String indicator;
protected String loadOnTextChange;
protected String loadMinimumCount;
protected String showDownArrow;
protected String templateCssPath;
protected String iconPath;
protected String keyName;
protected String dataFieldName;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Autocompleter(stack, req, res);
}
protected void populateParams() {
super.populateParams();
Autocompleter autocompleter = (Autocompleter) component;
autocompleter.setAutoComplete(autoComplete);
autocompleter.setDisabled(disabled);
autocompleter.setForceValidOption(forceValidOption);
autocompleter.setHref(href);
autocompleter.setDelay(delay);
autocompleter.setSearchType(searchType);
autocompleter.setDropdownHeight(dropdownHeight);
autocompleter.setDropdownWidth(dropdownWidth);
autocompleter.setFormFilter(formFilter);
autocompleter.setFormId(formId);
autocompleter.setListenTopics(listenTopics);
autocompleter.setNotifyTopics(notifyTopics);
autocompleter.setIndicator(indicator);
autocompleter.setLoadMinimumCount(loadMinimumCount);
autocompleter.setLoadOnTextChange(loadOnTextChange);
autocompleter.setShowDownArrow(showDownArrow);
autocompleter.setTemplateCssPath(templateCssPath);
autocompleter.setIconPath(iconPath);
autocompleter.setKeyName(keyName);
autocompleter.setDataFieldName(dataFieldName);
}
public void setAutoComplete(String autoComplete) {
this.autoComplete = autoComplete;
}
public void setDisabled(String disabled) {
this.disabled = disabled;
}
public void setForceValidOption(String forceValidOption) {
this.forceValidOption = forceValidOption;
}
public void setHref(String href) {
this.href = href;
}
public void setDelay(String searchDelay) {
this.delay = searchDelay;
}
public void setSearchType(String searchType) {
this.searchType = searchType;
}
public void setDropdownHeight(String height) {
this.dropdownHeight = height;
}
public void setDropdownWidth(String width) {
this.dropdownWidth = width;
}
public void setFormFilter(String formFilter) {
this.formFilter = formFilter;
}
public void setFormId(String formId) {
this.formId = formId;
}
public void setListenTopics(String listenTopics) {
this.listenTopics = listenTopics;
}
public void setNotifyTopics(String onValueChangedPublishTopic) {
this.notifyTopics = onValueChangedPublishTopic;
}
public void setIndicator(String indicator) {
this.indicator = indicator;
}
public void setLoadMinimumCount(String loadMinimumCount) {
this.loadMinimumCount = loadMinimumCount;
}
public String getLoadMinimumCount() {
return loadMinimumCount;
}
public void setLoadOnTextChange(String loadOnTextChange) {
this.loadOnTextChange = loadOnTextChange;
}
public void setShowDownArrow(String showDownArrow) {
this.showDownArrow = showDownArrow;
}
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
public void setDataFieldName(String dataFieldName) {
this.dataFieldName = dataFieldName;
}
}
@@ -0,0 +1,139 @@
/*
* $Id: DateTimePickerTag.java 508605 2007-02-16 21:56:50Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.DateTimePicker;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see DateTimePicker
*/
public class DateTimePickerTag extends AbstractUITag {
private static final long serialVersionUID = 4054114507143447232L;
protected String displayWeeks;
protected String adjustWeeks;
protected String startDate;
protected String endDate;
protected String weekStartsOn;
protected String staticDisplay;
protected String dayWidth;
protected String language;
protected String iconPath;
protected String formatLength;
protected String displayFormat;
protected String toggleType;
protected String toggleDuration;
protected String type;
protected String templateCssPath;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new DateTimePicker(stack, req, res);
}
protected void populateParams() {
super.populateParams();
final DateTimePicker dateTimePicker = (DateTimePicker) component;
dateTimePicker.setAdjustWeeks(adjustWeeks);
dateTimePicker.setDayWidth(dayWidth);
dateTimePicker.setDisplayWeeks(displayWeeks);
dateTimePicker.setEndDate(endDate);
dateTimePicker.setStartDate(startDate);
dateTimePicker.setStaticDisplay(staticDisplay);
dateTimePicker.setWeekStartsOn(weekStartsOn);
dateTimePicker.setLanguage(language);
dateTimePicker.setIconPath(iconPath);
dateTimePicker.setFormatLength(formatLength);
dateTimePicker.setDisplayFormat(displayFormat);
dateTimePicker.setToggleType(toggleType);
dateTimePicker.setToggleDuration(toggleDuration);
dateTimePicker.setType(type);
dateTimePicker.setTemplateCssPath(templateCssPath);
}
public void setAdjustWeeks(String adjustWeeks) {
this.adjustWeeks = adjustWeeks;
}
public void setDayWidth(String dayWidth) {
this.dayWidth = dayWidth;
}
public void setDisplayWeeks(String displayWeeks) {
this.displayWeeks = displayWeeks;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public void setStaticDisplay(String staticDisplay) {
this.staticDisplay = staticDisplay;
}
public void setWeekStartsOn(String weekStartsOn) {
this.weekStartsOn = weekStartsOn;
}
public void setLanguage(String language) {
this.language = language;
}
public void setDisplayFormat(String displayFormat) {
this.displayFormat = displayFormat;
}
public void setFormatLength(String formatLength) {
this.formatLength = formatLength;
}
public void setIconPath(String iconPath) {
this.iconPath = iconPath;
}
public void setToggleDuration(String toggleDuration) {
this.toggleDuration = toggleDuration;
}
public void setToggleType(String toggleType) {
this.toggleType = toggleType;
}
public void setType(String type) {
this.type = type;
}
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
}
@@ -0,0 +1,87 @@
/*
* $Id: DivTag.java 511300 2007-02-24 16:41:38Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.Div;
import com.opensymphony.xwork2.util.ValueStack;
public class DivTag extends AbstractRemoteCallUITag {
private static final long serialVersionUID = 5309231035916461758L;
protected String updateFreq;
protected String autoStart;
protected String delay;
protected String startTimerListenTopics;
protected String stopTimerListenTopics;
protected String refreshOnShow;
protected String separateScripts;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Div(stack, req, res);
}
protected void populateParams() {
super.populateParams();
Div div = (Div) component;
div.setUpdateFreq(updateFreq);
div.setAutoStart(autoStart);
div.setDelay(delay);
div.setStartTimerListenTopics(startTimerListenTopics);
div.setStopTimerListenTopics(stopTimerListenTopics);
div.setRefreshOnShow(refreshOnShow);
div.setSeparateScripts(separateScripts);
}
public void setAutoStart(String autoStart) {
this.autoStart = autoStart;
}
public void setDelay(String delay) {
this.delay = delay;
}
public void setUpdateFreq(String updateInterval) {
this.updateFreq = updateInterval;
}
public void setStartTimerListenTopics(String startTimerListenTopic) {
this.startTimerListenTopics = startTimerListenTopic;
}
public void setStopTimerListenTopics(String stopTimerListenTopic) {
this.stopTimerListenTopics = stopTimerListenTopic;
}
public void setRefreshOnShow(String refreshOnShow) {
this.refreshOnShow = refreshOnShow;
}
public void setSeparateScripts(String separateScripts) {
this.separateScripts = separateScripts;
}
}
@@ -0,0 +1,184 @@
/*
* $Id: SubmitTag.java 508285 2007-02-16 02:42:24Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.Submit;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see Submit
*/
public class SubmitTag extends AbstractUITag {
private static final long serialVersionUID = 2179281109958301343L;
protected String action;
protected String method;
protected String align;
protected String type;
protected String href;
protected String listenTopics;
protected String notifyTopics;
protected String loadingText;
protected String errorText;
protected String executeScripts;
protected String handler;
protected String formId;
protected String formFilter;
protected String src;
protected String showErrorTransportText;
protected String indicator;
protected String showLoadingText;
//these two are called "preInvokeJS" and "onLoadJS" on the tld
//Names changed here to keep some consistency
protected String beforeLoading;
protected String afterLoading;
//this one is called "resultDivId" on the tld
protected String targets;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Submit(stack, req, res);
}
protected void populateParams() {
super.populateParams();
Submit submit = ((Submit) component);
submit.setAction(action);
submit.setMethod(method);
submit.setAlign(align);
submit.setType(type);
submit.setHref(href);
submit.setListenTopics(listenTopics);
submit.setLoadingText(loadingText);
submit.setErrorText(errorText);
submit.setAfterLoading(afterLoading);
submit.setBeforeLoading(beforeLoading);
submit.setExecuteScripts(executeScripts);
submit.setHandler(handler);
submit.setFormFilter(formFilter);
submit.setFormId(formId);
submit.setSrc(src);
submit.setTargets(targets);
submit.setNotifyTopics(notifyTopics);
submit.setShowErrorTransportText(showErrorTransportText);
submit.setIndicator(indicator);
submit.setShowLoadingText(showLoadingText);
}
public void setAction(String action) {
this.action = action;
}
public void setMethod(String method) {
this.method = method;
}
public void setAlign(String align) {
this.align = align;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void setHref(String href) {
this.href = href;
}
public void setErrorText(String errorText) {
this.errorText = errorText;
}
public void setLoadingText(String loadingText) {
this.loadingText = loadingText;
}
public void setListenTopics(String listenTopics) {
this.listenTopics = listenTopics;
}
public void setExecuteScripts(String executeScripts) {
this.executeScripts = executeScripts;
}
public void setHandler(String handler) {
this.handler = handler;
}
public void setFormFilter(String formFilter) {
this.formFilter = formFilter;
}
public void setFormId(String formId) {
this.formId = formId;
}
public void setSrc(String src) {
this.src = src;
}
public void setTargets(String targets) {
this.targets = targets;
}
@Deprecated
public void setResultDivId(String id) {
this.targets = id;
}
@Deprecated
public void setOnLoadJS(String postJS) {
this.afterLoading = postJS;
}
@Deprecated
public void setPreInvokeJS(String preJS) {
this.beforeLoading = preJS;
}
public void setNotifyTopics(String notifyTopics) {
this.notifyTopics = notifyTopics;
}
public void setShowErrorTransportText(String showErrorTransportText) {
this.showErrorTransportText = showErrorTransportText;
}
public void setIndicator(String indicator) {
this.indicator = indicator;
}
public void setShowLoadingText(String showLoadingText) {
this.showLoadingText = showLoadingText;
}
}
@@ -0,0 +1,72 @@
/*
* $Id: TabbedPanelTag.java 508575 2007-02-16 20:46:49Z musachy $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.TabbedPanel;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see TabbedPanel
*/
public class TabbedPanelTag extends AbstractClosingTag {
private static final long serialVersionUID = -4719930205515386252L;
private String selectedTab;
private String closeButton;
private String doLayout;
private String templateCssPath;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new TabbedPanel(stack, req, res);
}
protected void populateParams() {
super.populateParams();
TabbedPanel tabbedPanel = (TabbedPanel) component;
tabbedPanel.setSelectedTab(selectedTab);
tabbedPanel.setCloseButton(closeButton);
tabbedPanel.setDoLayout(doLayout);
tabbedPanel.setLabelposition(labelPosition);
tabbedPanel.setTemplateCssPath(templateCssPath);
}
public void setSelectedTab(String selectedTab) {
this.selectedTab = selectedTab;
}
public void setCloseButton(String closeButton) {
this.closeButton = closeButton;
}
public void setDoLayout(String doLayout) {
this.doLayout = doLayout;
}
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
}
@@ -0,0 +1,56 @@
/*
* $Id: TreeNodeTag.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.TreeNode;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see TreeNode
*/
public class TreeNodeTag extends AbstractClosingTag {
private static final long serialVersionUID = 7340746943017900803L;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new TreeNode(stack,req,res);
}
public void setLabel(String label) {
this.label = label;
}
// NOTE: not necessary, label property is inherited, will be populated
// by super-class
/*protected void populateParams() {
if (label != null) {
TreeNode treeNode = (TreeNode)component;
treeNode.setLabel(label);
}
super.populateParams();
}*/
}
@@ -0,0 +1,305 @@
/*
* $Id: TreeTag.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.jsp.ui;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.Tree;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see Tree
*/
public class TreeTag extends AbstractClosingTag {
private static final long serialVersionUID = 2735218501058548013L;
private String toggle;
private String treeSelectedTopic;
private String treeExpandedTopic;
private String treeCollapsedTopic;
private String rootNode;
private String childCollectionProperty;
private String nodeTitleProperty;
private String nodeIdProperty;
private String showRootGrid;
private String showGrid;
private String blankIconSrc;
private String gridIconSrcL;
private String gridIconSrcV;
private String gridIconSrcP;
private String gridIconSrcC;
private String gridIconSrcX;
private String gridIconSrcY;
private String expandIconSrcPlus;
private String expandIconSrcMinus;
private String iconWidth;
private String iconHeight;
private String toggleDuration;
private String templateCssPath;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Tree(stack,req,res);
}
protected void populateParams() {
super.populateParams();
Tree tree = (Tree) component;
if (childCollectionProperty != null)
tree.setChildCollectionProperty(childCollectionProperty);
if (nodeIdProperty != null)
tree.setNodeIdProperty(nodeIdProperty);
if (nodeTitleProperty != null)
tree.setNodeTitleProperty(nodeTitleProperty);
if (rootNode != null)
tree.setRootNode(rootNode);
if (toggle != null)
tree.setToggle(toggle);
if (treeCollapsedTopic != null)
tree.setTreeCollapsedTopic(treeCollapsedTopic);
if (treeExpandedTopic != null)
tree.setTreeExpandedTopic(treeExpandedTopic);
if (treeSelectedTopic != null)
tree.setTreeSelectedTopic(treeSelectedTopic);
if (showRootGrid != null)
tree.setShowRootGrid(showRootGrid);
if (showGrid != null)
tree.setShowGrid(showGrid);
if (blankIconSrc != null)
tree.setBlankIconSrc(blankIconSrc);
if (gridIconSrcL != null)
tree.setGridIconSrcL(gridIconSrcC);
if (gridIconSrcV != null)
tree.setGridIconSrcV(gridIconSrcV);
if (gridIconSrcP != null)
tree.setGridIconSrcP(gridIconSrcP);
if (gridIconSrcC != null)
tree.setGridIconSrcC(gridIconSrcC);
if (gridIconSrcX != null)
tree.setGridIconSrcX(gridIconSrcX);
if (gridIconSrcY != null)
tree.setGridIconSrcY(gridIconSrcY);
if (expandIconSrcPlus != null)
tree.setExpandIconSrcPlus(expandIconSrcPlus);
if (expandIconSrcMinus != null)
tree.setExpandIconSrcMinus(expandIconSrcMinus);
if (iconWidth != null)
tree.setIconWidth(iconWidth);
if (iconHeight != null)
tree.setIconHeight(iconHeight);
if (toggleDuration != null)
tree.setToggleDuration(toggleDuration);
if (templateCssPath != null)
tree.setTemplateCssPath(templateCssPath);
}
public String getToggle() {
return toggle;
}
public void setToggle(String toggle) {
this.toggle = toggle;
}
public String getTreeSelectedTopic() {
return treeSelectedTopic;
}
public void setTreeSelectedTopic(String treeSelectedTopic) {
this.treeSelectedTopic = treeSelectedTopic;
}
public String getTreeExpandedTopic() {
return treeExpandedTopic;
}
public void setTreeExpandedTopic(String treeExpandedTopic) {
this.treeExpandedTopic = treeExpandedTopic;
}
public String getTreeCollapsedTopic() {
return treeCollapsedTopic;
}
public void setTreeCollapsedTopic(String treeCollapsedTopic) {
this.treeCollapsedTopic = treeCollapsedTopic;
}
public String getRootNode() {
return rootNode;
}
public void setRootNode(String rootNode) {
this.rootNode = rootNode;
}
public String getChildCollectionProperty() {
return childCollectionProperty;
}
public void setChildCollectionProperty(String childCollectionProperty) {
this.childCollectionProperty = childCollectionProperty;
}
public String getNodeTitleProperty() {
return nodeTitleProperty;
}
public void setNodeTitleProperty(String nodeTitleProperty) {
this.nodeTitleProperty = nodeTitleProperty;
}
public String getNodeIdProperty() {
return nodeIdProperty;
}
public void setNodeIdProperty(String nodeIdProperty) {
this.nodeIdProperty = nodeIdProperty;
}
public String getShowRootGrid() {
return showRootGrid;
}
public void setShowRootGrid(String showRootGrid) {
this.showRootGrid = showRootGrid;
}
public String getBlankIconSrc() {
return blankIconSrc;
}
public void setBlankIconSrc(String blankIconSrc) {
this.blankIconSrc = blankIconSrc;
}
public String getExpandIconSrcMinus() {
return expandIconSrcMinus;
}
public void setExpandIconSrcMinus(String expandIconSrcMinus) {
this.expandIconSrcMinus = expandIconSrcMinus;
}
public String getExpandIconSrcPlus() {
return expandIconSrcPlus;
}
public void setExpandIconSrcPlus(String expandIconSrcPlus) {
this.expandIconSrcPlus = expandIconSrcPlus;
}
public String getGridIconSrcC() {
return gridIconSrcC;
}
public void setGridIconSrcC(String gridIconSrcC) {
this.gridIconSrcC = gridIconSrcC;
}
public String getGridIconSrcL() {
return gridIconSrcL;
}
public void setGridIconSrcL(String gridIconSrcL) {
this.gridIconSrcL = gridIconSrcL;
}
public String getGridIconSrcP() {
return gridIconSrcP;
}
public void setGridIconSrcP(String gridIconSrcP) {
this.gridIconSrcP = gridIconSrcP;
}
public String getGridIconSrcV() {
return gridIconSrcV;
}
public void setGridIconSrcV(String gridIconSrcV) {
this.gridIconSrcV = gridIconSrcV;
}
public String getGridIconSrcX() {
return gridIconSrcX;
}
public void setGridIconSrcX(String gridIconSrcX) {
this.gridIconSrcX = gridIconSrcX;
}
public String getGridIconSrcY() {
return gridIconSrcY;
}
public void setGridIconSrcY(String gridIconSrcY) {
this.gridIconSrcY = gridIconSrcY;
}
public String getIconHeight() {
return iconHeight;
}
public void setIconHeight(String iconHeight) {
this.iconHeight = iconHeight;
}
public String getIconWidth() {
return iconWidth;
}
public void setIconWidth(String iconWidth) {
this.iconWidth = iconWidth;
}
public String getTemplateCssPath() {
return templateCssPath;
}
public void setTemplateCssPath(String templateCssPath) {
this.templateCssPath = templateCssPath;
}
public String getToggleDuration() {
return toggleDuration;
}
public void setToggleDuration(String toggleDuration) {
this.toggleDuration = toggleDuration;
}
public String getShowGrid() {
return showGrid;
}
public void setShowGrid(String showGrid) {
this.showGrid = showGrid;
}
}
@@ -0,0 +1,46 @@
/*
* $Id: AutocompleterDirective.java 502294 2007-02-01 17:28:00Z niallp $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.velocity.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Autocompleter;
import org.apache.struts2.components.Bean;
import org.apache.struts2.components.Component;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see Autocompleter
*/
public class AutocompleterDirective extends AbstractDirective {
protected Component getBean(ValueStack stack, HttpServletRequest req,
HttpServletResponse res) {
return new Autocompleter(stack, req, res);
}
public String getBeanName() {
return "autocompleter";
}
}
@@ -0,0 +1,40 @@
/*
* $Id: DateTimePickerDirective.java 493867 2007-01-07 22:26:23Z mrdon $
*
* Copyright 2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.struts2.views.velocity.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.DateTimePicker;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see DateTimePicker
*/
public class DateTimePickerDirective extends TextFieldDirective {
protected Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new DateTimePicker(stack, req, res);
}
public String getBeanName() {
return "datetimepicker";
}
}
@@ -0,0 +1,46 @@
/*
* $Id: DivDirective.java 494148 2007-01-08 18:41:13Z mrdon $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.velocity.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.Div;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see Div
*/
public class DivDirective extends AbstractDirective {
public String getBeanName() {
return "div";
}
protected Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Div(stack, req, res);
}
public int getType() {
return BLOCK;
}
}
@@ -0,0 +1,42 @@
/*
* $Id: TabbedPanelDirective.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.velocity.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.TabbedPanel;
import com.opensymphony.xwork2.util.ValueStack;
/**
* @see TabbedPanel
*/
public class TabbedPanelDirective extends AbstractDirective {
public String getBeanName() {
return "tabbedpanel";
}
protected Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new TabbedPanel(stack, req, res);
}
}
@@ -0,0 +1,43 @@
/*
* $Id: TreeDirective.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.velocity.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.Tree;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <code>TreeDirective</code>
* @see Tree
*/
public class TreeDirective extends AbstractDirective {
public String getBeanName() {
return "tree";
}
protected Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Tree(stack, req, res);
}
}
@@ -0,0 +1,44 @@
/*
* $Id: TreeNodeDirective.java 471756 2006-11-06 15:01:43Z husted $
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.struts2.views.velocity.components;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.components.TreeNode;
import com.opensymphony.xwork2.util.ValueStack;
/**
* <code>TreeNodeDirective</code>
* @see TreeNode
*/
public class TreeNodeDirective extends AbstractDirective {
public String getBeanName() {
return "treenode";
}
protected Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new TreeNode(stack, req, res);
}
}
@@ -0,0 +1,3 @@
TLD file is generated inside META-INF after compilation.
If META-INF is empty, Maven will not copy it to the "target/classes" folder.
Please do not remove META-INF, or this file.
@@ -0,0 +1,52 @@
/**
* Methods for the tabbed component
*/
var unselectedClass = "tab_default tab_unselected";
var unselectedContentsClass = "tab_contents_hidden";
var unselectedOverClass = "tab_default tab_unselected tab_unselected_over";
var selectedClass = "tab_default tab_selected";
var selectedContentsClass = "tab_contents_header";
function mouseIn(tab) {
var className = tab.className;
if (className.indexOf('unselected') > -1) {
className = unselectedOverClass;
tab.className = className;
}
}
function mouseOut(tab) {
var className = tab.className;
if (className.indexOf('unselected') > -1) {
className = unselectedClass;
tab.className = className;
}
}
/**
* Checks whether the current form include an ajax-ified submit button, if so
* we return true (otherwise false).
*
* @param form the HTML form element to check
*/
function isAjaxFormSubmit( form ) {
// we check whether this exists
// <INPUT type="submit" dojoattachevent="onClick: execute" dojoattachpoint="attachBtn" />
var thisForm = document.getElementById(form.id);
var matchUrl = /\s+dojoAttachPoint/;
if( thisForm.innerHTML.match(matchUrl) ) {
return false;
}
for( i=0; i<thisForm.elements.length; i++ ) {
var field = thisForm.elements[i];
if( field.type.toLowerCase()=='submit' ) {
if( field.hasAttribute("dojoAttachPoint") && field.getAttribute("dojoAttachPoint")=="attachBtn" ) {
return false;
}
}
}
return true;
}
/** end tabbed component functions ******************************************************************/
@@ -0,0 +1,195 @@
Dojo is availble under *either* the terms of the modified BSD license *or* the
Academic Free License version 2.1. As a recipient of Dojo, you may choose which
license to receive this code under (except as noted in per-module LICENSE
files). Some modules may not be the copyright of the Dojo Foundation. These
modules contain explicit declarations of copyright in both the LICENSE files in
the directories in which they reside and in the code itself. No external
contributions are allowed under licenses which are fundamentally incompatible
with the AFL or BSD licenses that Dojo is distributed under.
The text of the AFL and BSD licenses is reproduced below.
-------------------------------------------------------------------------------
The "New" BSD License:
**********************
Copyright (c) 2005, The Dojo Foundation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the Dojo Foundation nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------------------
The Academic Free License, v. 2.1:
**********************************
This Academic Free License (the "License") applies to any original work of
authorship (the "Original Work") whose owner (the "Licensor") has placed the
following notice immediately following the copyright notice for the Original
Work:
Licensed under the Academic Free License version 2.1
1) Grant of Copyright License. Licensor hereby grants You a world-wide,
royalty-free, non-exclusive, perpetual, sublicenseable license to do the
following:
a) to reproduce the Original Work in copies;
b) to prepare derivative works ("Derivative Works") based upon the Original
Work;
c) to distribute copies of the Original Work and Derivative Works to the
public;
d) to perform the Original Work publicly; and
e) to display the Original Work publicly.
2) Grant of Patent License. Licensor hereby grants You a world-wide,
royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
claims owned or controlled by the Licensor that are embodied in the Original
Work as furnished by the Licensor, to make, use, sell and offer for sale the
Original Work and Derivative Works.
3) Grant of Source Code License. The term "Source Code" means the preferred
form of the Original Work for making modifications to it and all available
documentation describing how to modify the Original Work. Licensor hereby
agrees to provide a machine-readable copy of the Source Code of the Original
Work along with each copy of the Original Work that Licensor distributes.
Licensor reserves the right to satisfy this obligation by placing a
machine-readable copy of the Source Code in an information repository
reasonably calculated to permit inexpensive and convenient access by You for as
long as Licensor continues to distribute the Original Work, and by publishing
the address of that information repository in a notice immediately following
the copyright notice that applies to the Original Work.
4) Exclusions From License Grant. Neither the names of Licensor, nor the names
of any contributors to the Original Work, nor any of their trademarks or
service marks, may be used to endorse or promote products derived from this
Original Work without express prior written permission of the Licensor. Nothing
in this License shall be deemed to grant any rights to trademarks, copyrights,
patents, trade secrets or any other intellectual property of Licensor except as
expressly stated herein. No patent license is granted to make, use, sell or
offer to sell embodiments of any patent claims other than the licensed claims
defined in Section 2. No right is granted to the trademarks of Licensor even if
such marks are included in the Original Work. Nothing in this License shall be
interpreted to prohibit Licensor from licensing under different terms from this
License any Original Work that Licensor otherwise would have a right to
license.
5) This section intentionally omitted.
6) Attribution Rights. You must retain, in the Source Code of any Derivative
Works that You create, all copyright, patent or trademark notices from the
Source Code of the Original Work, as well as any notices of licensing and any
descriptive text identified therein as an "Attribution Notice." You must cause
the Source Code for any Derivative Works that You create to carry a prominent
Attribution Notice reasonably calculated to inform recipients that You have
modified the Original Work.
7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
the copyright in and to the Original Work and the patent rights granted herein
by Licensor are owned by the Licensor or are sublicensed to You under the terms
of this License with the permission of the contributor(s) of those copyrights
and patent rights. Except as expressly stated in the immediately proceeding
sentence, the Original Work is provided under this License on an "AS IS" BASIS
and WITHOUT WARRANTY, either express or implied, including, without limitation,
the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
license to Original Work is granted hereunder except under this disclaimer.
8) Limitation of Liability. Under no circumstances and under no legal theory,
whether in tort (including negligence), contract, or otherwise, shall the
Licensor be liable to any person for any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License
or the use of the Original Work including, without limitation, damages for loss
of goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses. This limitation of liability shall not
apply to liability for death or personal injury resulting from Licensor's
negligence to the extent applicable law prohibits such limitation. Some
jurisdictions do not allow the exclusion or limitation of incidental or
consequential damages, so this exclusion and limitation may not apply to You.
9) Acceptance and Termination. If You distribute copies of the Original Work or
a Derivative Work, You must make a reasonable effort under the circumstances to
obtain the express assent of recipients to the terms of this License. Nothing
else but this License (or another written agreement between Licensor and You)
grants You permission to create Derivative Works based upon the Original Work
or to exercise any of the rights granted in Section 1 herein, and any attempt
to do so except under the terms of this License (or another written agreement
between Licensor and You) is expressly prohibited by U.S. copyright law, the
equivalent laws of other countries, and by international treaty. Therefore, by
exercising any of the rights granted to You in Section 1 herein, You indicate
Your acceptance of this License and all of its terms and conditions.
10) Termination for Patent Action. This License shall terminate automatically
and You may no longer exercise any of the rights granted to You by this License
as of the date You commence an action, including a cross-claim or counterclaim,
against Licensor or any licensee alleging that the Original Work infringes a
patent. This termination provision shall not apply for an action alleging
patent infringement by combinations of the Original Work with other software or
hardware.
11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
License may be brought only in the courts of a jurisdiction wherein the
Licensor resides or in which Licensor conducts its primary business, and under
the laws of that jurisdiction excluding its conflict-of-law provisions. The
application of the United Nations Convention on Contracts for the International
Sale of Goods is expressly excluded. Any use of the Original Work outside the
scope of this License or after its termination shall be subject to the
requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
seq., the equivalent laws of other countries, and international treaty. This
section shall survive the termination of this License.
12) Attorneys Fees. In any action to enforce the terms of this License or
seeking damages relating thereto, the prevailing party shall be entitled to
recover its costs and expenses, including, without limitation, reasonable
attorneys' fees and costs incurred in connection with such action, including
any appeal of such action. This section shall survive the termination of this
License.
13) Miscellaneous. This License represents the complete agreement concerning
the subject matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent necessary to
make it enforceable.
14) Definition of "You" in This License. "You" throughout this License, whether
in upper or lower case, means an individual or a legal entity exercising rights
under, and complying with all of the terms of, this License. For legal
entities, "You" includes any entity that controls, is controlled by, or is
under common control with you. For purposes of this definition, "control" means
(i) the power, direct or indirect, to cause the direction or management of such
entity, whether by contract or otherwise, or (ii) ownership of fifty percent
(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
entity.
15) Right to Use. You may use the Original Work in all ways not otherwise
restricted or conditioned by this License or by law, and Licensor promises not
to interfere with or be responsible for such uses by You.
This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
Permission is hereby granted to copy and distribute this license without
modification. This license may not be modified without the express written
permission of its copyright owner.
@@ -0,0 +1,176 @@
The Dojo Toolkit
----------------
Dojo is a portable JavaScript toolkit for web application developers and
JavaScript professionals. Dojo solves real-world problems by providing powerful
abstractions and solid, tested implementations.
Getting Started
---------------
To use Dojo in your application, download one of the pre-built editions from the
Dojo website, http://dojotoolkit.org. Once you have downloaded the file you will
need to unzip the archive in your website root. At a minimum, you will need to
extract:
src/ (folder)
dojo.js
iframe_history.html
To begin using dojo, include dojo in your pages by using:
<script type="text/javascript" src="/path/to/dojo.js"></script>
Depending on the edition that you have downloaded, this base dojo.js file may or
may not include the modules you wish to use in your application. The files which
have been "baked in" to the dojo.js that is part of your distribution are listed
in the file build.txt that is part of the top-level directory that is created
when you unpack the archive. To ensure modules you wish to use are available,
use dojo.require() to request them. A very rich application might include:
<script type="text/javascript" src="/path/to/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.event.*"); // sophisticated AOP event handling
dojo.require("dojo.io.*"); // for Ajax requests
dojo.require("dojo.storage.*"); // a persistent local data cache
dojo.require("dojo.json"); // serialization to JSON
dojo.require("dojo.dnd.*"); // drag-and-drop
dojo.require("dojo.lfx.*"); // animations and eye candy
dojo.require("dojo.widget.Editor2");// stable, portable HTML WYSIWYG
</script>
Note that only those modules which are *not* already "baked in" to dojo.js by
the edition's build process are requested by dojo.require(). This helps make
your application faster without forcing you to use a build tool while in
development. See "Building Dojo" and "Working From Source" for more details.
Compatibility
-------------
In addition to it's suite of unit-tests for core system components, Dojo has
been tested on almost every modern browser, including:
- IE 5.5+
- Mozilla 1.5+, Firefox 1.0+
- Safari 1.3.9+
- Konqueror 3.4+
- Opera 8.5+
Note that some widgets and features may not perform exactly the same on every
browser due to browser implementation differences.
For those looking to use Dojo in non-browser environments, please see "Working
From Source".
Documentation and Getting Help
------------------------------
Articles outlining major Dojo systems are linked from:
http://dojotoolkit.org/docs/
Toolkit APIs are listed in outline form at:
http://dojotoolkit.org/docs/apis/
And documented in full at:
http://manual.dojotoolkit.org/
The project also maintains a JotSpot Wiki at:
http://dojo.jot.com/
A FAQ has been extracted from mailing list traffic:
http://dojo.jot.com/FAQ
And the main Dojo user mailing list is archived and made searchable at:
http://news.gmane.org/gmane.comp.web.dojo.user/
You can sign up for this list, which is a great place to ask questions, at:
http://dojotoolkit.org/mailman/listinfo/dojo-interest
The Dojo developers also tend to hang out in IRC and help people with Dojo
problems. You're most likely to find them at:
irc.freenode.net #dojo
Note that 2PM Wed PST in this channel is reserved for a weekly meeting between
project developers, although anyone is welcome to participate.
Working From Source
-------------------
The core of Dojo is a powerful package system that allows developers to optimize
Dojo for deployment while using *exactly the same* application code in
development. Therefore, working from source is almost exactly like working from
a pre-built edition. Pre-built editions are significantly faster to load than
working from source, but are not as flexible when in development.
There are multiple ways to get the source. Nightly snapshots of the Dojo source
repository are available at:
http://archive.dojotoolkit.org/nightly.tgz
Anonymous Subversion access is also available:
%> svn co http://svn.dojotoolkit.org/dojo/trunk/ dojo
Each of these sources will include some extra directories not included in the
pre-packaged editions, including command-line tests and build tools for
constructing your own packages.
Running the command-line unit test suite requires Ant 1.6. If it is installed
and in your path, you can run the tests using:
%> cd buildscripts
%> ant test
The command-line test harness makes use of Rhino, a JavaScript interpreter
written in Java. Once you have a copy of Dojo's source tree, you have a copy of
Rhino. From the root directory, you can use Rhino interactively to load Dojo:
%> java -jar buildscripts/lib/js.jar
Rhino 1.5 release 3 2002 01 27
js> load("dojo.js");
js> print(dojo);
[object Object]
js> quit();
This environment is wonderful for testing raw JavaScript functionality in, or
even for scripting your system. Since Rhino has full access to anything in
Java's classpath, the sky is the limit!
Building Dojo
-------------
Dojo requires Ant 1.6.x in order to build correctly. While using Dojo from
source does *NOT* require that you make a build, speeding up your application by
constructing a custom profile build does.
Once you have Ant and a source snapshot of Dojo, you can make your own profile
build ("edition") which includes only those modules your application uses by
customizing one of the files in:
[dojo]/buildscripts/profiles/
These files are named *.profile.js and each one contains a list of modules to
include in a build. If we created a new profile called "test.profile.js", we
could then make a profile build using it by doing:
%> cd buildscripts
%> ant -Dprofile=test -Ddocless=true release intern-strings
If the build is successful, your newly minted and compressed profile build will
be placed in [dojo]/release/dojo/
-------------------------------------------------------------------------------
Copyright (c) 2004-2006, The Dojo Foundation, All Rights Reserved
vim:ts=4:et:tw=80:shiftwidth=4:
@@ -0,0 +1,86 @@
Files baked into this package:
dojoGuardStart.js,
../src/bootstrap1.js,
../src/loader.js,
dojoGuardEnd.js,
../src/hostenv_browser.js,
../src/bootstrap2.js,
../src/lang/common.js,
../src/lang.js,
../src/dom.js,
../src/html/common.js,
../src/uri/Uri.js,
../src/html/style.js,
../src/html/__package__.js,
../src/html/display.js,
../src/html/layout.js,
../src/html/util.js,
../src/lang/array.js,
../src/gfx/color.js,
../src/lang/func.js,
../src/lfx/Animation.js,
../src/html/color.js,
../src/lfx/html.js,
../src/lfx/__package__.js,
../src/lang/extras.js,
../src/event/common.js,
../src/event/topic.js,
../src/event/browser.js,
../src/event/__package__.js,
../src/logging/Logger.js,
../src/logging/__package__.js,
../src/string/common.js,
../src/string.js,
../src/io/common.js,
../src/string/extras.js,
../src/undo/browser.js,
../src/io/BrowserIO.js,
../src/io/cookie.js,
../src/io/__package__.js,
../src/uri/__package__.js,
../src/io/IframeIO.js,
../src/date.js,
../src/string/Builder.js,
../src/string/__package__.js,
../__package__.js,
../src/AdapterRegistry.js,
../src/json.js,
../src/Deferred.js,
../src/rpc/RpcService.js,
../src/rpc/JsonService.js,
../src/rpc/__package__.js,
../src/xml/Parse.js,
../src/xml/__package__.js,
../src/undo/Manager.js,
../src/undo/__package__.js,
../src/crypto.js,
../src/crypto/MD5.js,
../src/crypto/__package__.js,
../src/collections/Collections.js,
../src/collections/ArrayList.js,
../src/collections/Queue.js,
../src/collections/Stack.js,
../src/lang/declare.js,
../src/dnd/DragAndDrop.js,
../src/dnd/HtmlDragManager.js,
../src/html/selection.js,
../src/html/iframe.js,
../src/dnd/HtmlDragAndDrop.js,
../src/dnd/__package__.js,
../src/ns.js,
../src/widget/Manager.js,
../src/a11y.js,
../src/widget/Widget.js,
../src/widget/Parse.js,
../src/widget/DomWidget.js,
../src/lfx/toggle.js,
../src/widget/HtmlWidget.js,
../src/widget/__package__.js,
../src/math.js,
../src/math/curves.js,
../src/math/points.js,
../src/math/__package__.js
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,54 @@
<!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" xml:lang="en" lang="en">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
<script type="text/javascript">
// <!--
var noInit = false;
var domain = "";
// document.domain = "localhost";
function init(){
// parse the query string if there is one to try to get args that
// we can act on
var sparams = document.location.search;
if(sparams.length >= 0){
if(sparams.charAt(0) == "?"){
sparams = sparams.substring(1);
}
var ss = (sparams.indexOf("&amp;") >= 0) ? "&amp;" : "&";
sparams = sparams.split(ss);
for(var x=0; x<sparams.length; x++){
var tp = sparams[x].split("=");
if(typeof window[tp[0]] != "undefined"){
window[tp[0]] = ((tp[1]=="true")||(tp[1]=="false")) ? eval(tp[1]) : tp[1];
}
}
}
if(noInit){ return; }
if(domain.length > 0){
document.domain = domain;
}
if((window.parent != window)&&(window.parent["dojo"])){
//Set the page title so IE history shows up with a somewhat correct name.
document.title = window.parent.document.title;
//Notify parent that we are loaded.
var pdj = window.parent.dojo;
if(pdj["undo"] && pdj["undo"]["browser"]){
pdj.undo.browser.iframeLoaded(null, window.location);
}
}
}
// -->
</script>
</head>
<body onload="try{ init(); }catch(e){ alert(e); }">
<h4>The Dojo Toolkit -- iframe_history.html</h4>
<p>This file is used in Dojo's back/fwd button management.</p>
</body>
</html>
@@ -0,0 +1,89 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.AdapterRegistry");
dojo.require("dojo.lang.func");
dojo.AdapterRegistry = function(/*boolean, optional*/returnWrappers){
// summary:
// A registry to make contextual calling/searching easier.
// description:
// Objects of this class keep list of arrays in the form [name, check,
// wrap, directReturn] that are used to determine what the contextual
// result of a set of checked arguments is. All check/wrap functions
// in this registry should be of the same arity.
this.pairs = [];
this.returnWrappers = returnWrappers || false;
}
dojo.lang.extend(dojo.AdapterRegistry, {
register: function( /*string*/ name, /*function*/ check, /*function*/ wrap,
/*boolean, optional*/ directReturn,
/*boolean, optional*/ override){
// summary:
// register a check function to determine if the wrap function or
// object gets selected
// name: a way to identify this matcher.
// check:
// a function that arguments are passed to from the adapter's
// match() function. The check function should return true if the
// given arguments are appropriate for the wrap function.
// directReturn:
// If directReturn is true, the value passed in for wrap will be
// returned instead of being called. Alternately, the
// AdapterRegistry can be set globally to "return not call" using
// the returnWrappers property. Either way, this behavior allows
// the registry to act as a "search" function instead of a
// function interception library.
// override:
// If override is given and true, the check function will be given
// highest priority. Otherwise, it will be the lowest priority
// adapter.
var type = (override) ? "unshift" : "push";
this.pairs[type]([name, check, wrap, directReturn]);
},
match: function(/* ... */){
// summary:
// Find an adapter for the given arguments. If no suitable adapter
// is found, throws an exception. match() accepts any number of
// arguments, all of which are passed to all matching functions
// from the registered pairs.
for(var i = 0; i < this.pairs.length; i++){
var pair = this.pairs[i];
if(pair[1].apply(this, arguments)){
if((pair[3])||(this.returnWrappers)){
return pair[2];
}else{
return pair[2].apply(this, arguments);
}
}
}
throw new Error("No match found");
// dojo.raise("No match found");
},
unregister: function(name){
// summary: Remove a named adapter from the registry
// FIXME: this is kind of a dumb way to handle this. On a large
// registry this will be slow-ish and we can use the name as a lookup
// should we choose to trade memory for speed.
for(var i = 0; i < this.pairs.length; i++){
var pair = this.pairs[i];
if(pair[0] == name){
this.pairs.splice(i, 1);
return true;
}
}
return false;
}
});
@@ -0,0 +1,315 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.Deferred");
dojo.require("dojo.lang.func");
dojo.Deferred = function(/* optional */ canceller){
/*
NOTE: this namespace and documentation are imported wholesale
from MochiKit
Encapsulates a sequence of callbacks in response to a value that
may not yet be available. This is modeled after the Deferred class
from Twisted <http://twistedmatrix.com>.
Why do we want this? JavaScript has no threads, and even if it did,
threads are hard. Deferreds are a way of abstracting non-blocking
events, such as the final response to an XMLHttpRequest.
The sequence of callbacks is internally represented as a list
of 2-tuples containing the callback/errback pair. For example,
the following call sequence::
var d = new Deferred();
d.addCallback(myCallback);
d.addErrback(myErrback);
d.addBoth(myBoth);
d.addCallbacks(myCallback, myErrback);
is translated into a Deferred with the following internal
representation::
[
[myCallback, null],
[null, myErrback],
[myBoth, myBoth],
[myCallback, myErrback]
]
The Deferred also keeps track of its current status (fired).
Its status may be one of three things:
-1: no value yet (initial condition)
0: success
1: error
A Deferred will be in the error state if one of the following
three conditions are met:
1. The result given to callback or errback is "instanceof" Error
2. The previous callback or errback raised an exception while
executing
3. The previous callback or errback returned a value "instanceof"
Error
Otherwise, the Deferred will be in the success state. The state of
the Deferred determines the next element in the callback sequence to
run.
When a callback or errback occurs with the example deferred chain,
something equivalent to the following will happen (imagine that
exceptions are caught and returned)::
// d.callback(result) or d.errback(result)
if(!(result instanceof Error)){
result = myCallback(result);
}
if(result instanceof Error){
result = myErrback(result);
}
result = myBoth(result);
if(result instanceof Error){
result = myErrback(result);
}else{
result = myCallback(result);
}
The result is then stored away in case another step is added to the
callback sequence. Since the Deferred already has a value available,
any new callbacks added will be called immediately.
There are two other "advanced" details about this implementation that
are useful:
Callbacks are allowed to return Deferred instances themselves, so you
can build complicated sequences of events with ease.
The creator of the Deferred may specify a canceller. The canceller
is a function that will be called if Deferred.cancel is called before
the Deferred fires. You can use this to implement clean aborting of
an XMLHttpRequest, etc. Note that cancel will fire the deferred with
a CancelledError (unless your canceller returns another kind of
error), so the errbacks should be prepared to handle that error for
cancellable Deferreds.
*/
this.chain = [];
this.id = this._nextId();
this.fired = -1;
this.paused = 0;
this.results = [null, null];
this.canceller = canceller;
this.silentlyCancelled = false;
};
dojo.lang.extend(dojo.Deferred, {
getFunctionFromArgs: function(){
var a = arguments;
if((a[0])&&(!a[1])){
if(dojo.lang.isFunction(a[0])){
return a[0];
}else if(dojo.lang.isString(a[0])){
return dj_global[a[0]];
}
}else if((a[0])&&(a[1])){
return dojo.lang.hitch(a[0], a[1]);
}
return null;
},
makeCalled: function() {
var deferred = new dojo.Deferred();
deferred.callback();
return deferred;
},
repr: function(){
var state;
if(this.fired == -1){
state = 'unfired';
}else if(this.fired == 0){
state = 'success';
} else {
state = 'error';
}
return 'Deferred(' + this.id + ', ' + state + ')';
},
toString: dojo.lang.forward("repr"),
_nextId: (function(){
var n = 1;
return function(){ return n++; };
})(),
cancel: function(){
/***
Cancels a Deferred that has not yet received a value, or is
waiting on another Deferred as its value.
If a canceller is defined, the canceller is called. If the
canceller did not return an error, or there was no canceller,
then the errback chain is started with CancelledError.
***/
if(this.fired == -1){
if (this.canceller){
this.canceller(this);
}else{
this.silentlyCancelled = true;
}
if(this.fired == -1){
this.errback(new Error(this.repr()));
}
}else if( (this.fired == 0)&&
(this.results[0] instanceof dojo.Deferred)){
this.results[0].cancel();
}
},
_pause: function(){
// Used internally to signal that it's waiting on another Deferred
this.paused++;
},
_unpause: function(){
// Used internally to signal that it's no longer waiting on
// another Deferred.
this.paused--;
if ((this.paused == 0) && (this.fired >= 0)) {
this._fire();
}
},
_continue: function(res){
// Used internally when a dependent deferred fires.
this._resback(res);
this._unpause();
},
_resback: function(res){
// The primitive that means either callback or errback
this.fired = ((res instanceof Error) ? 1 : 0);
this.results[this.fired] = res;
this._fire();
},
_check: function(){
if(this.fired != -1){
if(!this.silentlyCancelled){
dojo.raise("already called!");
}
this.silentlyCancelled = false;
return;
}
},
callback: function(res){
/*
Begin the callback sequence with a non-error value.
callback or errback should only be called once on a given
Deferred.
*/
this._check();
this._resback(res);
},
errback: function(res){
// Begin the callback sequence with an error result.
this._check();
if(!(res instanceof Error)){
res = new Error(res);
}
this._resback(res);
},
addBoth: function(cb, cbfn){
/*
Add the same function as both a callback and an errback as the
next element on the callback sequence. This is useful for code
that you want to guarantee to run, e.g. a finalizer.
*/
var enclosed = this.getFunctionFromArgs(cb, cbfn);
if(arguments.length > 2){
enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2);
}
return this.addCallbacks(enclosed, enclosed);
},
addCallback: function(cb, cbfn){
// Add a single callback to the end of the callback sequence.
var enclosed = this.getFunctionFromArgs(cb, cbfn);
if(arguments.length > 2){
enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2);
}
return this.addCallbacks(enclosed, null);
},
addErrback: function(cb, cbfn){
// Add a single callback to the end of the callback sequence.
var enclosed = this.getFunctionFromArgs(cb, cbfn);
if(arguments.length > 2){
enclosed = dojo.lang.curryArguments(null, enclosed, arguments, 2);
}
return this.addCallbacks(null, enclosed);
return this.addCallbacks(null, cbfn);
},
addCallbacks: function (cb, eb) {
// Add separate callback and errback to the end of the callback
// sequence.
this.chain.push([cb, eb])
if (this.fired >= 0) {
this._fire();
}
return this;
},
_fire: function(){
// Used internally to exhaust the callback sequence when a result
// is available.
var chain = this.chain;
var fired = this.fired;
var res = this.results[fired];
var self = this;
var cb = null;
while (chain.length > 0 && this.paused == 0) {
// Array
var pair = chain.shift();
var f = pair[fired];
if (f == null) {
continue;
}
try {
res = f(res);
fired = ((res instanceof Error) ? 1 : 0);
if(res instanceof dojo.Deferred) {
cb = function(res){
self._continue(res);
}
this._pause();
}
}catch(err){
fired = 1;
res = err;
}
}
this.fired = fired;
this.results[fired] = res;
if((cb)&&(this.paused)){
// this is for "tail recursion" in case the dependent
// deferred is already fired
res.addBoth(cb);
}
}
});
@@ -0,0 +1,88 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.Deferred");
dojo.provide("dojo.DeferredList");
dojo.DeferredList = function (list, /*bool?*/ fireOnOneCallback, /*bool?*/ fireOnOneErrback, /*bool?*/ consumeErrors, /*Function?*/ canceller) {
this.list = list;
this.resultList = new Array(this.list.length);
// Deferred init
this.chain = [];
this.id = this._nextId();
this.fired = -1;
this.paused = 0;
this.results = [null, null];
this.canceller = canceller;
this.silentlyCancelled = false;
if (this.list.length === 0 && !fireOnOneCallback) {
this.callback(this.resultList);
}
this.finishedCount = 0;
this.fireOnOneCallback = fireOnOneCallback;
this.fireOnOneErrback = fireOnOneErrback;
this.consumeErrors = consumeErrors;
var index = 0;
var _this = this;
dojo.lang.forEach(this.list, function(d) {
var _index = index;
//dojo.debug("add cb/errb index "+_index);
d.addCallback(function(r) { _this._cbDeferred(_index, true, r) });
d.addErrback(function(r) { _this._cbDeferred(_index, false, r) });
index++;
});
};
dojo.inherits(dojo.DeferredList, dojo.Deferred);
dojo.lang.extend(dojo.DeferredList, {
_cbDeferred: function (index, succeeded, result) {
//dojo.debug("Fire "+index+" succ "+succeeded+" res "+result);
this.resultList[index] = [succeeded, result];
this.finishedCount += 1;
if (this.fired !== 0) {
if (succeeded && this.fireOnOneCallback) {
this.callback([index, result]);
} else if (!succeeded && this.fireOnOneErrback) {
this.errback(result);
} else if (this.finishedCount == this.list.length) {
this.callback(this.resultList);
}
}
if (!succeeded && this.consumeErrors) {
result = null;
}
return result;
},
gatherResults: function (deferredList) {
var d = new dojo.DeferredList(deferredList, false, true, false);
d.addCallback(function (results) {
var ret = [];
for (var i = 0; i < results.length; i++) {
ret.push(results[i][1]);
}
return ret;
});
return d;
}
});
@@ -0,0 +1,103 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.a11y");
dojo.require("dojo.uri.*");
dojo.require("dojo.html.common");
dojo.a11y = {
// imgPath: String path to the test image for determining if images are displayed or not
// doAccessibleCheck: Boolean if true will perform check for need to create accessible widgets
// accessible: Boolean uninitialized when null (accessible check has not been performed)
// if true generate accessible widgets
imgPath:dojo.uri.dojoUri("src/widget/templates/images"),
doAccessibleCheck: true,
accessible: null,
checkAccessible: function(){
// summary:
// perform check for accessibility if accessibility checking is turned
// on and the accessibility test has not been performed yet
if(this.accessible === null){
this.accessible = false; //default
if(this.doAccessibleCheck == true){
this.accessible = this.testAccessible();
}
}
return this.accessible; /* Boolean */
},
testAccessible: function(){
// summary:
// Always perform the accessibility check to determine if high
// contrast mode is on or display of images are turned off. Currently only checks
// in IE and Mozilla.
this.accessible = false; //default
if (dojo.render.html.ie || dojo.render.html.mozilla){
var div = document.createElement("div");
//div.style.color="rgb(153,204,204)";
div.style.backgroundImage = "url(\"" + this.imgPath + "/tab_close.gif\")";
// must add to hierarchy before can view currentStyle below
dojo.body().appendChild(div);
// in FF and IE the value for the current background style of the added div
// will be "none" in high contrast mode
// in FF the return value will be url(invalid-url:) when running over http
var bkImg = null;
if (window.getComputedStyle ) {
var cStyle = getComputedStyle(div, "");
bkImg = cStyle.getPropertyValue("background-image");
}else{
bkImg = div.currentStyle.backgroundImage;
}
var bUseImgElem = false;
if (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" )) {
this.accessible = true;
}
/*
if(this.accessible == false && document.images){
// test if images are off in IE
var testImg = new Image();
if(testImg.fileSize) {
testImg.src = this.imgPath + "/tab_close.gif";
if(testImg.fileSize < 0){
this.accessible = true;
}
}
}*/
dojo.body().removeChild(div);
}
return this.accessible; /* Boolean */
},
setCheckAccessible: function(/* Boolean */ bTest){
// summary:
// Set whether or not to check for accessibility mode. Default value
// of module is true - perform check for accessibility modes.
// bTest: Boolean - true to check; false to turn off checking
this.doAccessibleCheck = bTest;
},
setAccessibleMode: function(){
// summary:
// perform the accessibility check and sets the correct mode to load
// a11y widgets. Only runs if test for accessiiblity has not been performed yet.
// Call testAccessible() to force the test.
if (this.accessible === null){
if (this.checkAccessible()){
dojo.render.html.prefixes.unshift("a11y");
}
}
return this.accessible; /* Boolean */
}
};
//dojo.hostenv.modulesLoadedListeners.unshift(function() { dojo.a11y.setAccessibleMode(); });
//dojo.event.connect("before", dojo.hostenv, "makeWidgets", dojo.a11y, "setAccessibleMode");
@@ -0,0 +1,14 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation");
dojo.require("dojo.animation.Animation");
dojo.deprecated("dojo.animation is slated for removal in 0.5; use dojo.lfx instead.", "0.5");
@@ -0,0 +1,245 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.Animation");
dojo.require("dojo.animation.AnimationEvent");
dojo.require("dojo.lang.func");
dojo.require("dojo.math");
dojo.require("dojo.math.curves");
dojo.deprecated("dojo.animation.Animation is slated for removal in 0.5; use dojo.lfx.* instead.", "0.5");
/*
Animation package based off of Dan Pupius' work on Animations:
http://pupius.co.uk/js/Toolkit.Drawing.js
*/
dojo.animation.Animation = function(/*dojo.math.curves.* */ curve, /*int*/ duration, /*Decimal?*/ accel, /*int?*/ repeatCount, /*int?*/ rate) {
// summary: Animation object iterates a set of numbers over a curve for a given amount of time, calling 'onAnimate' at each step.
// curve: Curve to animate over.
// duration: Duration of the animation, in milliseconds.
// accel: Either an integer or curve representing amount of acceleration. (?) Default is linear acceleration.
// repeatCount: Number of times to repeat the animation. Default is 0.
// rate: Time between animation steps, in milliseconds. Default is 25.
// description: Calls the following events: "onBegin", "onAnimate", "onEnd", "onPlay", "onPause", "onStop"
// If the animation implements a "handler" function, that will be called before each event is called.
if(dojo.lang.isArray(curve)) {
// curve: Array
// id: i
curve = new dojo.math.curves.Line(curve[0], curve[1]);
}
this.curve = curve;
this.duration = duration;
this.repeatCount = repeatCount || 0;
this.rate = rate || 25;
if(accel) {
// accel: Decimal
// id: j
if(dojo.lang.isFunction(accel.getValue)) {
// accel: dojo.math.curves.CatmullRom
// id: k
this.accel = accel;
} else {
var i = 0.35*accel+0.5; // 0.15 <= i <= 0.85
this.accel = new dojo.math.curves.CatmullRom([[0], [i], [1]], 0.45);
}
}
}
dojo.lang.extend(dojo.animation.Animation, {
// public properties
curve: null,
duration: 0,
repeatCount: 0,
accel: null,
// events
onBegin: null,
onAnimate: null,
onEnd: null,
onPlay: null,
onPause: null,
onStop: null,
handler: null,
// "private" properties
_animSequence: null,
_startTime: null,
_endTime: null,
_lastFrame: null,
_timer: null,
_percent: 0,
_active: false,
_paused: false,
_startRepeatCount: 0,
// public methods
play: function(/*Boolean?*/ gotoStart) {
// summary: Play the animation.
// goToStart: If true, will restart the animation from the beginning.
// Otherwise, starts from current play counter.
// description: Sends an "onPlay" event to any observers.
// Also sends an "onBegin" event if starting from the beginning.
if( gotoStart ) {
clearTimeout(this._timer);
this._active = false;
this._paused = false;
this._percent = 0;
} else if( this._active && !this._paused ) {
return;
}
this._startTime = new Date().valueOf();
if( this._paused ) {
this._startTime -= (this.duration * this._percent / 100);
}
this._endTime = this._startTime + this.duration;
this._lastFrame = this._startTime;
var e = new dojo.animation.AnimationEvent(this, null, this.curve.getValue(this._percent),
this._startTime, this._startTime, this._endTime, this.duration, this._percent, 0);
this._active = true;
this._paused = false;
if( this._percent == 0 ) {
if(!this._startRepeatCount) {
this._startRepeatCount = this.repeatCount;
}
e.type = "begin";
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onBegin == "function") { this.onBegin(e); }
}
e.type = "play";
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onPlay == "function") { this.onPlay(e); }
if(this._animSequence) { this._animSequence._setCurrent(this); }
this._cycle();
},
pause: function() {
// summary: Temporarily stop the animation, leaving the play counter at the current location.
// Resume later with sequence.play()
// description: Sends an "onPause" AnimationEvent to any observers.
clearTimeout(this._timer);
if( !this._active ) { return; }
this._paused = true;
var e = new dojo.animation.AnimationEvent(this, "pause", this.curve.getValue(this._percent),
this._startTime, new Date().valueOf(), this._endTime, this.duration, this._percent, 0);
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onPause == "function") { this.onPause(e); }
},
playPause: function() {
// summary: Toggle between play and paused states.
if( !this._active || this._paused ) {
this.play();
} else {
this.pause();
}
},
gotoPercent: function(/*int*/ pct, /*Boolean*/ andPlay) {
// summary: Set the play counter at a certain point in the animation.
// pct: Point to set the play counter to, expressed as a percentage (0 to 100).
// andPlay: If true, will start the animation at the counter automatically.
clearTimeout(this._timer);
this._active = true;
this._paused = true;
this._percent = pct;
if( andPlay ) { this.play(); }
},
stop: function(/*Boolean?*/ gotoEnd) {
// summary: Stop the animation.
// gotoEnd: If true, will advance play counter to the end before sending the event.
// description: Sends an "onStop" AnimationEvent to any observers.
clearTimeout(this._timer);
var step = this._percent / 100;
if( gotoEnd ) {
step = 1;
}
var e = new dojo.animation.AnimationEvent(this, "stop", this.curve.getValue(step),
this._startTime, new Date().valueOf(), this._endTime, this.duration, this._percent);
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onStop == "function") { this.onStop(e); }
this._active = false;
this._paused = false;
},
status: function() {
// summary: Return the status of the animation.
// description: Returns one of "playing", "paused" or "stopped".
if( this._active ) {
return this._paused ? "paused" : "playing"; /* String */
} else {
return "stopped"; /* String */
}
},
// "private" methods
_cycle: function() {
// summary: Perform once 'cycle' or step of the animation.
clearTimeout(this._timer);
if( this._active ) {
var curr = new Date().valueOf();
var step = (curr - this._startTime) / (this._endTime - this._startTime);
var fps = 1000 / (curr - this._lastFrame);
this._lastFrame = curr;
if( step >= 1 ) {
step = 1;
this._percent = 100;
} else {
this._percent = step * 100;
}
// Perform accelleration
if(this.accel && this.accel.getValue) {
step = this.accel.getValue(step);
}
var e = new dojo.animation.AnimationEvent(this, "animate", this.curve.getValue(step),
this._startTime, curr, this._endTime, this.duration, this._percent, Math.round(fps));
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onAnimate == "function") { this.onAnimate(e); }
if( step < 1 ) {
this._timer = setTimeout(dojo.lang.hitch(this, "_cycle"), this.rate);
} else {
e.type = "end";
this._active = false;
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onEnd == "function") { this.onEnd(e); }
if( this.repeatCount > 0 ) {
this.repeatCount--;
this.play(true);
} else if( this.repeatCount == -1 ) {
this.play(true);
} else {
if(this._startRepeatCount) {
this.repeatCount = this._startRepeatCount;
this._startRepeatCount = 0;
}
if( this._animSequence ) {
this._animSequence._playNext();
}
}
}
}
}
});
@@ -0,0 +1,64 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.AnimationEvent");
dojo.require("dojo.lang.common");
dojo.deprecated("dojo.animation.AnimationEvent is slated for removal in 0.5; use dojo.lfx.* instead.", "0.5");
dojo.animation.AnimationEvent = function(
/*dojo.animation.Animation*/ animation,
/*String*/type,
/*int[] */ coords,
/*int*/ startTime,
/*int*/ currentTime,
/*int*/ endTime,
/*int*/ duration,
/*int*/ percent,
/*int?*/ fps) {
// summary: Event sent at various points during an Animation.
// animation: Animation throwing the event.
// type: One of: "animate", "begin", "end", "play", "pause" or "stop".
// coords: Current coordinates of the animation.
// startTime: Time the animation was started, as milliseconds.
// currentTime: Time the event was thrown, as milliseconds.
// endTime: Time the animation is expected to complete, as milliseconds.
// duration: Duration of the animation, in milliseconds.
// percent: Percent of the animation that has completed, between 0 and 100.
// fps: Frames currently shown per second. (Only sent for "animate" event).
// description: The AnimationEvent has public properties of the same name as
// all constructor arguments, plus "x", "y" and "z".
this.type = type; // "animate", "begin", "end", "play", "pause", "stop"
this.animation = animation;
this.coords = coords;
this.x = coords[0];
this.y = coords[1];
this.z = coords[2];
this.startTime = startTime;
this.currentTime = currentTime;
this.endTime = endTime;
this.duration = duration;
this.percent = percent;
this.fps = fps;
};
dojo.extend(dojo.animation.AnimationEvent, {
coordsAsInts: function() {
// summary: Coerce the coordinates into integers.
var cints = new Array(this.coords.length);
for(var i = 0; i < this.coords.length; i++) {
cints[i] = Math.round(this.coords[i]);
}
return cints;
}
});
@@ -0,0 +1,162 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.AnimationSequence");
dojo.require("dojo.animation.AnimationEvent");
dojo.require("dojo.animation.Animation");
dojo.deprecated("dojo.animation.AnimationSequence is slated for removal in 0.5; use dojo.lfx.* instead.", "0.5");
dojo.animation.AnimationSequence = function(/*int?*/ repeatCount){
// summary: Sequence of Animations, played one after the other.
// repeatCount: Number of times to repeat the entire sequence. Default is 0 (play once only).
// description: Calls the following events: "onBegin", "onEnd", "onNext"
// If the animation implements a "handler" function, that will be called before each event is called.
this._anims = [];
this.repeatCount = repeatCount || 0;
}
dojo.lang.extend(dojo.animation.AnimationSequence, {
repeatCount: 0,
_anims: [],
_currAnim: -1,
onBegin: null,
onEnd: null,
onNext: null,
handler: null,
add: function() {
// summary: Add one or more Animations to the sequence.
// description: args: Animations (dojo.animation.Animation) to add to the sequence.
for(var i = 0; i < arguments.length; i++) {
this._anims.push(arguments[i]);
arguments[i]._animSequence = this;
}
},
remove: function(/*dojo.animation.Animation*/ anim) {
// summary: Remove one particular animation from the sequence.
// amim: Animation to remove.
for(var i = 0; i < this._anims.length; i++) {
if( this._anims[i] == anim ) {
this._anims[i]._animSequence = null;
this._anims.splice(i, 1);
break;
}
}
},
removeAll: function() {
// summary: Remove all animations from the sequence.
for(var i = 0; i < this._anims.length; i++) {
this._anims[i]._animSequence = null;
}
this._anims = [];
this._currAnim = -1;
},
clear: function() {
// summary: Remove all animations from the sequence.
this.removeAll();
},
play: function(/*Boolean?*/ gotoStart) {
// summary: Play the animation sequence.
// gotoStart: If true, will start at the beginning of the first sequence.
// Otherwise, starts at the current play counter of the current animation.
// description: Sends an "onBegin" event to any observers.
if( this._anims.length == 0 ) { return; }
if( gotoStart || !this._anims[this._currAnim] ) {
this._currAnim = 0;
}
if( this._anims[this._currAnim] ) {
if( this._currAnim == 0 ) {
var e = {type: "begin", animation: this._anims[this._currAnim]};
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onBegin == "function") { this.onBegin(e); }
}
this._anims[this._currAnim].play(gotoStart);
}
},
pause: function() {
// summary: temporarily stop the current animation. Resume later with sequence.play()
if( this._anims[this._currAnim] ) {
this._anims[this._currAnim].pause();
}
},
playPause: function() {
// summary: Toggle between play and paused states.
if( this._anims.length == 0 ) { return; }
if( this._currAnim == -1 ) { this._currAnim = 0; }
if( this._anims[this._currAnim] ) {
this._anims[this._currAnim].playPause();
}
},
stop: function() {
// summary: Stop the current animation.
if( this._anims[this._currAnim] ) {
this._anims[this._currAnim].stop();
}
},
status: function() {
// summary: Return the status of the current animation.
// description: Returns one of "playing", "paused" or "stopped".
if( this._anims[this._currAnim] ) {
return this._anims[this._currAnim].status();
} else {
return "stopped";
}
},
_setCurrent: function(/*dojo.animation.Animation*/ anim) {
// summary: Set the current animation.
// anim: Animation to make current, must have already been added to the sequence.
for(var i = 0; i < this._anims.length; i++) {
if( this._anims[i] == anim ) {
this._currAnim = i;
break;
}
}
},
_playNext: function() {
// summary: Play the next animation in the sequence.
// description: Sends an "onNext" event to any observers.
// Also sends "onEnd" if the last animation is finished.
if( this._currAnim == -1 || this._anims.length == 0 ) { return; }
this._currAnim++;
if( this._anims[this._currAnim] ) {
var e = {type: "next", animation: this._anims[this._currAnim]};
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onNext == "function") { this.onNext(e); }
this._anims[this._currAnim].play(true);
} else {
var e = {type: "end", animation: this._anims[this._anims.length-1]};
if(typeof this.handler == "function") { this.handler(e); }
if(typeof this.onEnd == "function") { this.onEnd(e); }
if(this.repeatCount > 0) {
this._currAnim = 0;
this.repeatCount--;
this._anims[this._currAnim].play(true);
} else if(this.repeatCount == -1) {
this._currAnim = 0;
this._anims[this._currAnim].play(true);
} else {
this._currAnim = -1;
}
}
}
});
@@ -0,0 +1,16 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.animation.Timer");
dojo.require("dojo.lang.timing.Timer");
dojo.deprecated("dojo.animation.Timer is now dojo.lang.timing.Timer", "0.5");
dojo.animation.Timer = dojo.lang.timing.Timer;
@@ -0,0 +1,20 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: [
"dojo.animation.AnimationEvent",
"dojo.animation.Animation",
"dojo.animation.AnimationSequence"
]
});
dojo.provide("dojo.animation.*");
dojo.deprecated("dojo.Animation.* is slated for removal in 0.5; use dojo.lfx.* instead.", "0.5");
@@ -0,0 +1,248 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.behavior");
dojo.require("dojo.event.*");
dojo.require("dojo.experimental");
dojo.experimental("dojo.behavior");
dojo.behavior = new function(){
function arrIn(obj, name){
if(!obj[name]){ obj[name] = []; }
return obj[name];
}
function forIn(obj, scope, func){
var tmpObj = {};
for(var x in obj){
if(typeof tmpObj[x] == "undefined"){
if(!func){
scope(obj[x], x);
}else{
func.call(scope, obj[x], x);
}
}
}
}
// FIXME: need a better test so we don't exclude nightly Safari's!
this.behaviors = {};
this.add = function(behaviorObj){
/* behavior objects are specified in the following format:
*
* {
* "#id": {
* "found": function(element){
* // ...
* },
*
* "onblah": {targetObj: foo, targetFunc: "bar"},
*
* "onblarg": "/foo/bar/baz/blarg",
*
* "onevent": function(evt){
* },
*
* "onotherevent: function(evt){
* // ...
* }
* },
*
* "#id2": {
* // ...
* },
*
* "#id3": function(element){
* // ...
* },
*
* // publish the match on a topic
* "#id4": "/found/topic/name",
*
* // match all direct descendants
* "#id4 > *": function(element){
* // ...
* },
*
* // match the first child node that's an element
* "#id4 > @firstElement": { ... },
*
* // match the last child node that's an element
* "#id4 > @lastElement": { ... },
*
* // all elements of type tagname
* "tagname": {
* // ...
* },
*
* // maps to roughly:
* // dojo.lang.forEach(body.getElementsByTagName("tagname1"), function(node){
* // dojo.lang.forEach(node.getElementsByTagName("tagname2"), function(node2){
* // dojo.lang.forEach(node2.getElementsByTagName("tagname3", function(node3){
* // // apply rules
* // });
* // });
* // });
* "tagname1 tagname2 tagname3": {
* // ...
* },
*
* ".classname": {
* // ...
* },
*
* "tagname.classname": {
* // ...
* },
* }
*
* The "found" method is a generalized handler that's called as soon
* as the node matches the selector. Rules for values that follow also
* apply to the "found" key.
*
* The "on*" handlers are attached with dojo.event.connect(). If the
* value is not a function but is rather an object, it's assumed to be
* the "other half" of a dojo.event.kwConnect() argument object. It
* may contain any/all properties of such a connection modifier save
* for the sourceObj and sourceFunc properties which are filled in by
* the system automatically. If a string is instead encountered, the
* node publishes the specified event on the topic contained in the
* string value.
*
* If the value corresponding to the ID key is a function and not a
* list, it's treated as though it was the value of "found".
*
*/
var tmpObj = {};
forIn(behaviorObj, this, function(behavior, name){
var tBehavior = arrIn(this.behaviors, name);
if((dojo.lang.isString(behavior))||(dojo.lang.isFunction(behavior))){
behavior = { found: behavior };
}
forIn(behavior, function(rule, ruleName){
arrIn(tBehavior, ruleName).push(rule);
});
});
}
this.apply = function(){
dojo.profile.start("dojo.behavior.apply");
var r = dojo.render.html;
// note, we apply one way for fast queries and one way for slow
// iteration. So be it.
var safariGoodEnough = (!r.safari);
if(r.safari){
// Anything over release #420 should work the fast way
var uas = r.UA.split("AppleWebKit/")[1];
if(parseInt(uas.match(/[0-9.]{3,}/)) >= 420){
safariGoodEnough = true;
}
}
if((dj_undef("behaviorFastParse", djConfig) ? (safariGoodEnough) : djConfig["behaviorFastParse"])){
this.applyFast();
}else{
this.applySlow();
}
dojo.profile.end("dojo.behavior.apply");
}
this.matchCache = {};
this.elementsById = function(id, handleRemoved){
var removed = [];
var added = [];
arrIn(this.matchCache, id);
if(handleRemoved){
var nodes = this.matchCache[id];
for(var x=0; x<nodes.length; x++){
if(nodes[x].id != ""){
removed.push(nodes[x]);
nodes.splice(x, 1);
x--;
}
}
}
var tElem = dojo.byId(id);
while(tElem){
if(!tElem["idcached"]){
added.push(tElem);
}
tElem.id = "";
tElem = dojo.byId(id);
}
this.matchCache[id] = this.matchCache[id].concat(added);
dojo.lang.forEach(this.matchCache[id], function(node){
node.id = id;
node.idcached = true;
});
return { "removed": removed, "added": added, "match": this.matchCache[id] };
}
this.applyToNode = function(node, action, ruleSetName){
if(typeof action == "string"){
dojo.event.topic.registerPublisher(action, node, ruleSetName);
}else if(typeof action == "function"){
if(ruleSetName == "found"){
action(node);
}else{
dojo.event.connect(node, ruleSetName, action);
}
}else{
action.srcObj = node;
action.srcFunc = ruleSetName;
dojo.event.kwConnect(action);
}
}
this.applyFast = function(){
dojo.profile.start("dojo.behavior.applyFast");
// fast DOM queries...wheeee!
forIn(this.behaviors, function(tBehavior, id){
var elems = dojo.behavior.elementsById(id);
dojo.lang.forEach(elems.added,
function(elem){
forIn(tBehavior, function(ruleSet, ruleSetName){
if(dojo.lang.isArray(ruleSet)){
dojo.lang.forEach(ruleSet, function(action){
dojo.behavior.applyToNode(elem, action, ruleSetName);
});
}
});
}
);
});
dojo.profile.end("dojo.behavior.applyFast");
}
this.applySlow = function(){
// iterate. Ugg.
dojo.profile.start("dojo.behavior.applySlow");
var all = document.getElementsByTagName("*");
var allLen = all.length;
for(var x=0; x<allLen; x++){
var elem = all[x];
if((elem.id)&&(!elem["behaviorAdded"])&&(this.behaviors[elem.id])){
elem["behaviorAdded"] = true;
forIn(this.behaviors[elem.id], function(ruleSet, ruleSetName){
if(dojo.lang.isArray(ruleSet)){
dojo.lang.forEach(ruleSet, function(action){
dojo.behavior.applyToNode(elem, action, ruleSetName);
});
}
});
}
}
dojo.profile.end("dojo.behavior.applySlow");
}
}
dojo.addOnLoad(dojo.behavior, "apply");
@@ -0,0 +1,343 @@
/**
* @file bootstrap1.js
*
* summary: First file that is loaded that 'bootstraps' the entire dojo library suite.
* note: Must run before hostenv_*.js file.
*
* @author Copyright 2004 Mark D. Anderson (mda@discerning.com)
* TODOC: should the copyright be changed to Dojo Foundation?
* @license Licensed under the Academic Free License 2.1 http://www.opensource.org/licenses/afl-2.1.php
*
* $Id: bootstrap1.js 6258 2006-10-20 03:12:36Z jburke $
*/
// TODOC: HOW TO DOC THE BELOW?
// @global: djConfig
// summary:
// Application code can set the global 'djConfig' prior to loading
// the library to override certain global settings for how dojo works.
// description: The variables that can be set are as follows:
// - isDebug: false
// - allowQueryConfig: false
// - baseScriptUri: ""
// - baseRelativePath: ""
// - libraryScriptUri: ""
// - iePreventClobber: false
// - ieClobberMinimal: true
// - locale: undefined
// - extraLocale: undefined
// - preventBackButtonFix: true
// - searchIds: []
// - parseWidgets: true
// TODOC: HOW TO DOC THESE VARIABLES?
// TODOC: IS THIS A COMPLETE LIST?
// note:
// 'djConfig' does not exist under 'dojo.*' so that it can be set before the
// 'dojo' variable exists.
// note:
// Setting any of these variables *after* the library has loaded does nothing at all.
// TODOC: is this still true? Release notes for 0.3 indicated they could be set after load.
//
//TODOC: HOW TO DOC THIS?
// @global: dj_global
// summary:
// an alias for the top-level global object in the host environment
// (e.g., the window object in a browser).
// description:
// Refer to 'dj_global' rather than referring to window to ensure your
// code runs correctly in contexts other than web browsers (eg: Rhino on a server).
var dj_global = this;
//TODOC: HOW TO DOC THIS?
// @global: dj_currentContext
// summary:
// Private global context object. Where 'dj_global' always refers to the boot-time
// global context, 'dj_currentContext' can be modified for temporary context shifting.
// dojo.global() returns dj_currentContext.
// description:
// Refer to dojo.global() rather than referring to dj_global to ensure your
// code runs correctly in managed contexts.
var dj_currentContext = this;
// ****************************************************************
// global public utils
// TODOC: DO WE WANT TO NOTE THAT THESE ARE GLOBAL PUBLIC UTILS?
// ****************************************************************
function dj_undef(/*String*/ name, /*Object?*/ object){
//summary: Returns true if 'name' is defined on 'object' (or globally if 'object' is null).
//description: Note that 'defined' and 'exists' are not the same concept.
return (typeof (object || dj_currentContext)[name] == "undefined"); // Boolean
}
// make sure djConfig is defined
if(dj_undef("djConfig", this)){
var djConfig = {};
}
//TODOC: HOW TO DOC THIS?
// dojo is the root variable of (almost all) our public symbols -- make sure it is defined.
if(dj_undef("dojo", this)){
var dojo = {};
}
dojo.global = function(){
// summary:
// return the current global context object
// (e.g., the window object in a browser).
// description:
// Refer to 'dojo.global()' rather than referring to window to ensure your
// code runs correctly in contexts other than web browsers (eg: Rhino on a server).
return dj_currentContext;
}
// Override locale setting, if specified
dojo.locale = djConfig.locale;
//TODOC: HOW TO DOC THIS?
dojo.version = {
// summary: version number of this instance of dojo.
major: 0, minor: 3, patch: 1, flag: "+",
revision: Number("$Rev: 6258 $".match(/[0-9]+/)[0]),
toString: function(){
with(dojo.version){
return major + "." + minor + "." + patch + flag + " (" + revision + ")"; // String
}
}
}
dojo.evalProp = function(/*String*/ name, /*Object*/ object, /*Boolean?*/ create){
// summary: Returns 'object[name]'. If not defined and 'create' is true, will return a new Object.
// description:
// Returns null if 'object[name]' is not defined and 'create' is not true.
// Note: 'defined' and 'exists' are not the same concept.
if((!object)||(!name)) return undefined; // undefined
if(!dj_undef(name, object)) return object[name]; // mixed
return (create ? (object[name]={}) : undefined); // mixed
}
dojo.parseObjPath = function(/*String*/ path, /*Object?*/ context, /*Boolean?*/ create){
// summary: Parse string path to an object, and return corresponding object reference and property name.
// description:
// Returns an object with two properties, 'obj' and 'prop'.
// 'obj[prop]' is the reference indicated by 'path'.
// path: Path to an object, in the form "A.B.C".
// context: Object to use as root of path. Defaults to 'dojo.global()'.
// create: If true, Objects will be created at any point along the 'path' that is undefined.
var object = (context || dojo.global());
var names = path.split('.');
var prop = names.pop();
for (var i=0,l=names.length;i<l && object;i++){
object = dojo.evalProp(names[i], object, create);
}
return {obj: object, prop: prop}; // Object: {obj: Object, prop: String}
}
dojo.evalObjPath = function(/*String*/ path, /*Boolean?*/ create){
// summary: Return the value of object at 'path' in the global scope, without using 'eval()'.
// path: Path to an object, in the form "A.B.C".
// create: If true, Objects will be created at any point along the 'path' that is undefined.
if(typeof path != "string"){
return dojo.global();
}
// fast path for no periods
if(path.indexOf('.') == -1){
return dojo.evalProp(path, dojo.global(), create); // mixed
}
//MOW: old 'with' syntax was confusing and would throw an error if parseObjPath returned null.
var ref = dojo.parseObjPath(path, dojo.global(), create);
if(ref){
return dojo.evalProp(ref.prop, ref.obj, create); // mixed
}
return null;
}
dojo.errorToString = function(/*Error*/ exception){
// summary: Return an exception's 'message', 'description' or text.
// TODO: overriding Error.prototype.toString won't accomplish this?
// ... since natively generated Error objects do not always reflect such things?
if(!dj_undef("message", exception)){
return exception.message; // String
}else if(!dj_undef("description", exception)){
return exception.description; // String
}else{
return exception; // Error
}
}
dojo.raise = function(/*String*/ message, /*Error?*/ exception){
// summary: Common point for raising exceptions in Dojo to enable logging.
// Throws an error message with text of 'exception' if provided, or
// rethrows exception object.
if(exception){
message = message + ": "+dojo.errorToString(exception);
}
// print the message to the user if hostenv.println is defined
try { if(djConfig.isDebug){ dojo.hostenv.println("FATAL exception raised: "+message); } } catch (e) {}
throw exception || Error(message);
}
//Stub functions so things don't break.
//TODOC: HOW TO DOC THESE?
dojo.debug = function(){};
dojo.debugShallow = function(obj){};
dojo.profile = { start: function(){}, end: function(){}, stop: function(){}, dump: function(){} };
function dj_eval(/*String*/ scriptFragment){
// summary: Perform an evaluation in the global scope. Use this rather than calling 'eval()' directly.
// description: Placed in a separate function to minimize size of trapped evaluation context.
// note:
// - JSC eval() takes an optional second argument which can be 'unsafe'.
// - Mozilla/SpiderMonkey eval() takes an optional second argument which is the
// scope object for new symbols.
return dj_global.eval ? dj_global.eval(scriptFragment) : eval(scriptFragment); // mixed
}
dojo.unimplemented = function(/*String*/ funcname, /*String?*/ extra){
// summary: Throw an exception because some function is not implemented.
// extra: Text to append to the exception message.
var message = "'" + funcname + "' not implemented";
if (extra != null) { message += " " + extra; }
dojo.raise(message);
}
dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
// summary: Log a debug message to indicate that a behavior has been deprecated.
// extra: Text to append to the message.
// removal: Text to indicate when in the future the behavior will be removed.
var message = "DEPRECATED: " + behaviour;
if(extra){ message += " " + extra; }
if(removal){ message += " -- will be removed in version: " + removal; }
dojo.debug(message);
}
dojo.render = (function(){
//TODOC: HOW TO DOC THIS?
// summary: Details rendering support, OS and browser of the current environment.
// TODOC: is this something many folks will interact with? If so, we should doc the structure created...
function vscaffold(prefs, names){
var tmp = {
capable: false,
support: {
builtin: false,
plugin: false
},
prefixes: prefs
};
for(var i=0; i<names.length; i++){
tmp[names[i]] = false;
}
return tmp;
}
return {
name: "",
ver: dojo.version,
os: { win: false, linux: false, osx: false },
html: vscaffold(["html"], ["ie", "opera", "khtml", "safari", "moz"]),
svg: vscaffold(["svg"], ["corel", "adobe", "batik"]),
vml: vscaffold(["vml"], ["ie"]),
swf: vscaffold(["Swf", "Flash", "Mm"], ["mm"]),
swt: vscaffold(["Swt"], ["ibm"])
};
})();
// ****************************************************************
// dojo.hostenv methods that must be defined in hostenv_*.js
// ****************************************************************
/**
* The interface definining the interaction with the EcmaScript host environment.
*/
/*
* None of these methods should ever be called directly by library users.
* Instead public methods such as loadModule should be called instead.
*/
dojo.hostenv = (function(){
// TODOC: HOW TO DOC THIS?
// summary: Provides encapsulation of behavior that changes across different 'host environments'
// (different browsers, server via Rhino, etc).
// description: None of these methods should ever be called directly by library users.
// Use public methods such as 'loadModule' instead.
// default configuration options
var config = {
isDebug: false,
allowQueryConfig: false,
baseScriptUri: "",
baseRelativePath: "",
libraryScriptUri: "",
iePreventClobber: false,
ieClobberMinimal: true,
preventBackButtonFix: true,
delayMozLoadingFix: false,
searchIds: [],
parseWidgets: true
};
if (typeof djConfig == "undefined") { djConfig = config; }
else {
for (var option in config) {
if (typeof djConfig[option] == "undefined") {
djConfig[option] = config[option];
}
}
}
return {
name_: '(unset)',
version_: '(unset)',
getName: function(){
// sumary: Return the name of the host environment.
return this.name_; // String
},
getVersion: function(){
// summary: Return the version of the hostenv.
return this.version_; // String
},
getText: function(/*String*/ uri){
// summary: Read the plain/text contents at the specified 'uri'.
// description:
// If 'getText()' is not implemented, then it is necessary to override
// 'loadUri()' with an implementation that doesn't rely on it.
dojo.unimplemented('getText', "uri=" + uri);
}
};
})();
dojo.hostenv.getBaseScriptUri = function(){
// summary: Return the base script uri that other scripts are found relative to.
// TODOC: HUH? This comment means nothing to me. What other scripts? Is this the path to other dojo libraries?
// MAYBE: Return the base uri to scripts in the dojo library. ???
// return: Empty string or a path ending in '/'.
if(djConfig.baseScriptUri.length){
return djConfig.baseScriptUri;
}
// MOW: Why not:
// uri = djConfig.libraryScriptUri || djConfig.baseRelativePath
// ??? Why 'new String(...)'
var uri = new String(djConfig.libraryScriptUri||djConfig.baseRelativePath);
if (!uri) { dojo.raise("Nothing returned by getLibraryScriptUri(): " + uri); }
// MOW: uri seems to not be actually used. Seems to be hard-coding to djConfig.baseRelativePath... ???
var lastslash = uri.lastIndexOf('/'); // MOW ???
djConfig.baseScriptUri = djConfig.baseRelativePath;
return djConfig.baseScriptUri; // String
}
@@ -0,0 +1,59 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
//Semicolon is for when this file is integrated with a custom build on one line
//with some other file's contents. Sometimes that makes things not get defined
//properly, particularly with the using the closure below to do all the work.
;(function(){
//Don't do this work if dojo.js has already done it.
if(typeof dj_usingBootstrap != "undefined"){
return;
}
var isRhino = false;
var isSpidermonkey = false;
var isDashboard = false;
if((typeof this["load"] == "function")&&((typeof this["Packages"] == "function")||(typeof this["Packages"] == "object"))){
isRhino = true;
}else if(typeof this["load"] == "function"){
isSpidermonkey = true;
}else if(window.widget){
isDashboard = true;
}
var tmps = [];
if((this["djConfig"])&&((djConfig["isDebug"])||(djConfig["debugAtAllCosts"]))){
tmps.push("debug.js");
}
if((this["djConfig"])&&(djConfig["debugAtAllCosts"])&&(!isRhino)&&(!isDashboard)){
tmps.push("browser_debug.js");
}
var loaderRoot = djConfig["baseScriptUri"];
if((this["djConfig"])&&(djConfig["baseLoaderUri"])){
loaderRoot = djConfig["baseLoaderUri"];
}
for(var x=0; x < tmps.length; x++){
var spath = loaderRoot+"src/"+tmps[x];
if(isRhino||isSpidermonkey){
load(spath);
} else {
try {
document.write("<scr"+"ipt type='text/javascript' src='"+spath+"'></scr"+"ipt>");
} catch (e) {
var script = document.createElement("script");
script.src = spath;
document.getElementsByTagName("head")[0].appendChild(script);
}
}
}
})();
@@ -0,0 +1,176 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.hostenv.loadedUris.push("../src/bootstrap1.js");
dojo.hostenv.loadedUris.push("../src/loader.js");
dojo.hostenv.loadedUris.push("../src/hostenv_browser.js");
dojo.hostenv.loadedUris.push("../src/bootstrap2.js");
dojo.hostenv._loadedUrisListStart = dojo.hostenv.loadedUris.length;
function removeComments(contents){
contents = new String((!contents) ? "" : contents);
// clobber all comments
// FIXME broken if // or /* inside quotes or regexp
contents = contents.replace( /^(.*?)\/\/(.*)$/mg , "$1");
contents = contents.replace( /(\n)/mg , "__DOJONEWLINE");
contents = contents.replace( /\/\*(.*?)\*\//g , "");
return contents.replace( /__DOJONEWLINE/mg , "\n");
}
dojo.hostenv.getRequiresAndProvides = function(contents){
// FIXME: should probably memoize this!
if(!contents){ return []; }
// check to see if we need to load anything else first. Ugg.
var deps = [];
var tmp;
RegExp.lastIndex = 0;
var testExp = /dojo.(hostenv.loadModule|hostenv.require|require|requireIf|kwCompoundRequire|hostenv.conditionalLoadModule|hostenv.startPackage|provide)\([\w\W]*?\)/mg;
while((tmp = testExp.exec(contents)) != null){
deps.push(tmp[0]);
}
return deps;
}
dojo.hostenv.getDelayRequiresAndProvides = function(contents){
// FIXME: should probably memoize this!
if(!contents){ return []; }
// check to see if we need to load anything else first. Ugg.
var deps = [];
var tmp;
RegExp.lastIndex = 0;
var testExp = /dojo.(requireAfterIf)\([\w\W]*?\)/mg;
while((tmp = testExp.exec(contents)) != null){
deps.push(tmp[0]);
}
return deps;
}
/*
dojo.getNonExistantDescendants = function(objpath){
var ret = [];
// fast path for no periods
if(typeof objpath != "string"){ return dj_global; }
if(objpath.indexOf('.') == -1){
if(dj_undef(objpath, dj_global)){
ret.push[objpath];
}
return ret;
}
var syms = objpath.split(/\./);
var obj = dj_global;
for(var i=0;i<syms.length;++i){
if(dj_undef(syms[i], obj)){
for(var j=i; j<syms.length; j++){
ret.push(syms.slice(0, j+1).join("."));
}
break;
}
}
return ret;
}
*/
dojo.clobberLastObject = function(objpath){
if(objpath.indexOf('.') == -1){
if(!dj_undef(objpath, dj_global)){
delete dj_global[objpath];
}
return true;
}
var syms = objpath.split(/\./);
var base = dojo.evalObjPath(syms.slice(0, -1).join("."), false);
var child = syms[syms.length-1];
if(!dj_undef(child, base)){
// alert(objpath);
delete base[child];
return true;
}
return false;
}
var removals = [];
function zip(arr){
var ret = [];
var seen = {};
for(var x=0; x<arr.length; x++){
if(!seen[arr[x]]){
ret.push(arr[x]);
seen[arr[x]] = true;
}
}
return ret;
}
// over-write dj_eval to prevent actual loading of subsequent files
var old_dj_eval = dj_eval;
dj_eval = function(){ return true; }
dojo.hostenv.oldLoadUri = dojo.hostenv.loadUri;
dojo.hostenv.loadUri = function(uri, cb /*optional*/){
if(dojo.hostenv.loadedUris[uri]){
return true; // fixes endless recursion opera trac 471
}
try{
var text = this.getText(uri, null, true);
if(!text) { return false; }
if(cb){
// No way to load i18n bundles but to eval them, and they usually
// don't have script needing to be debugged anyway
var expr = old_dj_eval('('+text+')');
cb(expr);
}else {
var requires = dojo.hostenv.getRequiresAndProvides(text);
eval(requires.join(";"));
dojo.hostenv.loadedUris.push(uri);
dojo.hostenv.loadedUris[uri] = true;
var delayRequires = dojo.hostenv.getDelayRequiresAndProvides(text);
eval(delayRequires.join(";"));
}
}catch(e){
alert(e);
}
return true;
}
dojo.hostenv._writtenIncludes = {};
dojo.hostenv.writeIncludes = function(willCallAgain){
for(var x=removals.length-1; x>=0; x--){
dojo.clobberLastObject(removals[x]);
}
var depList = [];
var seen = dojo.hostenv._writtenIncludes;
for(var x=0; x<dojo.hostenv.loadedUris.length; x++){
var curi = dojo.hostenv.loadedUris[x];
// dojo.debug(curi);
if(!seen[curi]){
seen[curi] = true;
depList.push(curi);
}
}
dojo.hostenv._global_omit_module_check = true;
for(var x= dojo.hostenv._loadedUrisListStart; x<depList.length; x++){
document.write("<script type='text/javascript' src='"+depList[x]+"'></script>");
}
document.write("<script type='text/javascript'>dojo.hostenv._global_omit_module_check = false;</script>");
dojo.hostenv._loadedUrisListStart = 0;
if (!willCallAgain) {
// turn off debugAtAllCosts, so that dojo.require() calls inside of ContentPane hrefs
// work correctly
dj_eval = old_dj_eval;
dojo.hostenv.loadUri = dojo.hostenv.oldLoadUri;
}
}
@@ -0,0 +1,815 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.cal.iCalendar");
dojo.require("dojo.lang.common");
dojo.require("dojo.cal.textDirectory");
dojo.require("dojo.date.common");
dojo.require("dojo.date.serialize");
dojo.cal.iCalendar.fromText = function (/* string */text) {
// summary
// Parse text of an iCalendar and return an array of iCalendar objects
var properties = dojo.cal.textDirectory.tokenise(text);
var calendars = [];
//dojo.debug("Parsing iCal String");
for (var i = 0, begun = false; i < properties.length; i++) {
var prop = properties[i];
if (!begun) {
if (prop.name == 'BEGIN' && prop.value == 'VCALENDAR') {
begun = true;
var calbody = [];
}
} else if (prop.name == 'END' && prop.value == 'VCALENDAR') {
calendars.push(new dojo.cal.iCalendar.VCalendar(calbody));
begun = false;
} else {
calbody.push(prop);
}
}
return /* array */calendars;
}
dojo.cal.iCalendar.Component = function (/* string */ body ) {
// summary
// A component is the basic container of all this stuff.
if (!this.name) {
this.name = "COMPONENT"
}
this.properties = [];
this.components = [];
if (body) {
for (var i = 0, context = ''; i < body.length; i++) {
if (context == '') {
if (body[i].name == 'BEGIN') {
context = body[i].value;
var childprops = [];
} else {
this.addProperty(new dojo.cal.iCalendar.Property(body[i]));
}
} else if (body[i].name == 'END' && body[i].value == context) {
if (context=="VEVENT") {
this.addComponent(new dojo.cal.iCalendar.VEvent(childprops));
} else if (context=="VTIMEZONE") {
this.addComponent(new dojo.cal.iCalendar.VTimeZone(childprops));
} else if (context=="VTODO") {
this.addComponent(new dojo.cal.iCalendar.VTodo(childprops));
} else if (context=="VJOURNAL") {
this.addComponent(new dojo.cal.iCalendar.VJournal(childprops));
} else if (context=="VFREEBUSY") {
this.addComponent(new dojo.cal.iCalendar.VFreeBusy(childprops));
} else if (context=="STANDARD") {
this.addComponent(new dojo.cal.iCalendar.Standard(childprops));
} else if (context=="DAYLIGHT") {
this.addComponent(new dojo.cal.iCalendar.Daylight(childprops));
} else if (context=="VALARM") {
this.addComponent(new dojo.cal.iCalendar.VAlarm(childprops));
}else {
dojo.unimplemented("dojo.cal.iCalendar." + context);
}
context = '';
} else {
childprops.push(body[i]);
}
}
if (this._ValidProperties) {
this.postCreate();
}
}
}
dojo.extend(dojo.cal.iCalendar.Component, {
addProperty: function (prop) {
// summary
// push a new property onto a component.
this.properties.push(prop);
this[prop.name.toLowerCase()] = prop;
},
addComponent: function (prop) {
// summary
// add a component to this components list of children.
this.components.push(prop);
},
postCreate: function() {
for (var x=0; x<this._ValidProperties.length; x++) {
var evtProperty = this._ValidProperties[x];
var found = false;
for (var y=0; y<this.properties.length; y++) {
var prop = this.properties[y];
var propName = prop.name.toLowerCase();
if (dojo.lang.isArray(evtProperty)) {
var alreadySet = false;
for (var z=0; z<evtProperty.length; z++) {
var evtPropertyName = evtProperty[z].name.toLowerCase();
if((this[evtPropertyName]) && (evtPropertyName != propName )) {
alreadySet=true;
}
}
if (!alreadySet) {
this[propName] = prop;
}
} else {
if (propName == evtProperty.name.toLowerCase()) {
found = true;
if (evtProperty.occurance == 1){
this[propName] = prop;
} else {
found = true;
if (!dojo.lang.isArray(this[propName])) {
this[propName] = [];
}
this[propName].push(prop);
}
}
}
}
if (evtProperty.required && !found) {
dojo.debug("iCalendar - " + this.name + ": Required Property not found: " + evtProperty.name);
}
}
// parse any rrules
if (dojo.lang.isArray(this.rrule)) {
for(var x=0; x<this.rrule.length; x++) {
var rule = this.rrule[x].value;
//add a place to cache dates we have checked for recurrance
this.rrule[x].cache = function() {};
var temp = rule.split(";");
for (var y=0; y<temp.length; y++) {
var pair = temp[y].split("=");
var key = pair[0].toLowerCase();
var val = pair[1];
if ((key == "freq") || (key=="interval") || (key=="until")) {
this.rrule[x][key]= val;
} else {
var valArray = val.split(",");
this.rrule[x][key] = valArray;
}
}
}
this.recurring = true;
}
},
toString: function () {
// summary
// output a string representation of this component.
return "[iCalendar.Component; " + this.name + ", " + this.properties.length +
" properties, " + this.components.length + " components]";
}
});
dojo.cal.iCalendar.Property = function (prop) {
// summary
// A single property of a component.
// unpack the values
this.name = prop.name;
this.group = prop.group;
this.params = prop.params;
this.value = prop.value;
}
dojo.extend(dojo.cal.iCalendar.Property, {
toString: function () {
// summary
// output a string reprensentation of this component.
return "[iCalenday.Property; " + this.name + ": " + this.value + "]";
}
});
// This is just a little helper function for the Component Properties
var _P = function (n, oc, req) {
return {name: n, required: (req) ? true : false,
occurance: (oc == '*' || !oc) ? -1 : oc}
}
/*
* VCALENDAR
*/
dojo.cal.iCalendar.VCalendar = function (/* string */ calbody) {
// summary
// VCALENDAR Component
this.name = "VCALENDAR";
this.recurring = [];
this.nonRecurringEvents = function(){};
dojo.cal.iCalendar.Component.call(this, calbody);
}
dojo.inherits(dojo.cal.iCalendar.VCalendar, dojo.cal.iCalendar.Component);
dojo.extend(dojo.cal.iCalendar.VCalendar, {
addComponent: function (prop) {
// summary
// add component to the calenadar that makes it easy to pull them out again later.
this.components.push(prop);
if (prop.name.toLowerCase() == "vevent") {
if (prop.rrule) {
this.recurring.push(prop);
} else {
var startDate = prop.getDate();
var month = startDate.getMonth() + 1;
var dateString= month + "-" + startDate.getDate() + "-" + startDate.getFullYear();
if (!dojo.lang.isArray(this[dateString])) {
this.nonRecurringEvents[dateString] = [];
}
this.nonRecurringEvents[dateString].push(prop);
}
}
},
preComputeRecurringEvents: function(until) {
var calculatedEvents = function(){};
for(var x=0; x<this.recurring.length; x++) {
var dates = this.recurring[x].getDates(until);
for (var y=0; y<dates.length;y++) {
var month = dates[y].getMonth() + 1;
var dateStr = month + "-" + dates[y].getDate() + "-" + dates[y].getFullYear();
if (!dojo.lang.isArray(calculatedEvents[dateStr])) {
calculatedEvents[dateStr] = [];
}
if (!dojo.lang.inArray(calculatedEvents[dateStr], this.recurring[x])) {
calculatedEvents[dateStr].push(this.recurring[x]);
}
}
}
this.recurringEvents = calculatedEvents;
},
getEvents: function(/* Date */ date) {
// summary
// Gets all events occuring on a particular date
var events = [];
var recur = [];
var nonRecur = [];
var month = date.getMonth() + 1;
var dateStr= month + "-" + date.getDate() + "-" + date.getFullYear();
if (dojo.lang.isArray(this.nonRecurringEvents[dateStr])) {
nonRecur= this.nonRecurringEvents[dateStr];
dojo.debug("Number of nonRecurring Events: " + nonRecur.length);
}
if (dojo.lang.isArray(this.recurringEvents[dateStr])) {
recur= this.recurringEvents[dateStr];
}
events = recur.concat(nonRecur);
if (events.length > 0) {
return events;
}
return null;
}
});
/*
* STANDARD
*/
var StandardProperties = [
_P("dtstart", 1, true), _P("tzoffsetto", 1, true), _P("tzoffsetfrom", 1, true),
_P("comment"), _P("rdate"), _P("rrule"), _P("tzname")
];
dojo.cal.iCalendar.Standard = function (/* string */ body) {
// summary
// STANDARD Component
this.name = "STANDARD";
this._ValidProperties = StandardProperties;
dojo.cal.iCalendar.Component.call(this, body);
}
dojo.inherits(dojo.cal.iCalendar.Standard, dojo.cal.iCalendar.Component);
/*
* DAYLIGHT
*/
var DaylightProperties = [
_P("dtstart", 1, true), _P("tzoffsetto", 1, true), _P("tzoffsetfrom", 1, true),
_P("comment"), _P("rdate"), _P("rrule"), _P("tzname")
];
dojo.cal.iCalendar.Daylight = function (/* string */ body) {
// summary
// Daylight Component
this.name = "DAYLIGHT";
this._ValidProperties = DaylightProperties;
dojo.cal.iCalendar.Component.call(this, body);
}
dojo.inherits(dojo.cal.iCalendar.Daylight, dojo.cal.iCalendar.Component);
/*
* VEVENT
*/
var VEventProperties = [
// these can occur once only
_P("class", 1), _P("created", 1), _P("description", 1), _P("dtstart", 1),
_P("geo", 1), _P("last-mod", 1), _P("location", 1), _P("organizer", 1),
_P("priority", 1), _P("dtstamp", 1), _P("seq", 1), _P("status", 1),
_P("summary", 1), _P("transp", 1), _P("uid", 1), _P("url", 1), _P("recurid", 1),
// these two are exclusive
[_P("dtend", 1), _P("duration", 1)],
// these can occur many times over
_P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"),
_P("exdate"), _P("exrule"), _P("rstatus"), _P("related"), _P("resources"),
_P("rdate"), _P("rrule")
];
dojo.cal.iCalendar.VEvent = function (/* string */ body) {
// summary
// VEVENT Component
this._ValidProperties = VEventProperties;
this.name = "VEVENT";
dojo.cal.iCalendar.Component.call(this, body);
this.recurring = false;
this.startDate = dojo.date.fromIso8601(this.dtstart.value);
}
dojo.inherits(dojo.cal.iCalendar.VEvent, dojo.cal.iCalendar.Component);
dojo.extend(dojo.cal.iCalendar.VEvent, {
getDates: function(until) {
var dtstart = this.getDate();
var recurranceSet = [];
var weekdays=["su","mo","tu","we","th","fr","sa"];
var order = {
"daily": 1, "weekly": 2, "monthly": 3, "yearly": 4,
"byday": 1, "bymonthday": 1, "byweekno": 2, "bymonth": 3, "byyearday": 4};
// expand rrules into the recurrance
for (var x=0; x<this.rrule.length; x++) {
var rrule = this.rrule[x];
var freq = rrule.freq.toLowerCase();
var interval = 1;
if (rrule.interval > interval) {
interval = rrule.interval;
}
var set = [];
var freqInt = order[freq];
if (rrule.until) {
var tmpUntil = dojo.date.fromIso8601(rrule.until);
} else {
var tmpUntil = until
}
if (tmpUntil > until) {
tmpUntil = until
}
if (dtstart<tmpUntil) {
var expandingRules = function(){};
var cullingRules = function(){};
expandingRules.length=0;
cullingRules.length =0;
switch(freq) {
case "yearly":
var nextDate = new Date(dtstart);
set.push(nextDate);
while(nextDate < tmpUntil) {
nextDate.setYear(nextDate.getFullYear()+interval);
tmpDate = new Date(nextDate);
if(tmpDate < tmpUntil) {
set.push(tmpDate);
}
}
break;
case "monthly":
nextDate = new Date(dtstart);
set.push(nextDate);
while(nextDate < tmpUntil) {
nextDate.setMonth(nextDate.getMonth()+interval);
var tmpDate = new Date(nextDate);
if (tmpDate < tmpUntil) {
set.push(tmpDate);
}
}
break;
case "weekly":
nextDate = new Date(dtstart);
set.push(nextDate);
while(nextDate < tmpUntil) {
nextDate.setDate(nextDate.getDate()+(7*interval));
var tmpDate = new Date(nextDate);
if (tmpDate < tmpUntil) {
set.push(tmpDate);
}
}
break;
case "daily":
nextDate = new Date(dtstart);
set.push(nextDate);
while(nextDate < tmpUntil) {
nextDate.setDate(nextDate.getDate()+interval);
var tmpDate = new Date(nextDate);
if (tmpDate < tmpUntil) {
set.push(tmpDate);
}
}
break;
}
if ((rrule["bymonth"]) && (order["bymonth"]<freqInt)) {
for (var z=0; z<rrule["bymonth"].length; z++) {
if (z==0) {
for (var zz=0; zz < set.length; zz++) {
set[zz].setMonth(rrule["bymonth"][z]-1);
}
} else {
var subset=[];
for (var zz=0; zz < set.length; zz++) {
var newDate = new Date(set[zz]);
newDate.setMonth(rrule[z]);
subset.push(newDate);
}
tmp = set.concat(subset);
set = tmp;
}
}
}
// while the spec doesn't prohibit it, it makes no sense to have a bymonth and a byweekno at the same time
// and if i'm wrong then i don't know how to apply that rule. This is also documented elsewhere on the web
if (rrule["byweekno"] && !rrule["bymonth"]) {
dojo.debug("TODO: no support for byweekno yet");
}
// while the spec doesn't prohibit it, it makes no sense to have a bymonth and a byweekno at the same time
// and if i'm wrong then i don't know how to apply that rule. This is also documented elsewhere on the web
if (rrule["byyearday"] && !rrule["bymonth"] && !rrule["byweekno"] ) {
if (rrule["byyearday"].length > 1) {
var regex = "([+-]?)([0-9]{1,3})";
for (var z=1; x<rrule["byyearday"].length; z++) {
var regexResult = rrule["byyearday"][z].match(regex);
if (z==1) {
for (var zz=0; zz < set.length; zz++) {
if (regexResult[1] == "-") {
dojo.date.setDayOfYear(set[zz],366-regexResult[2]);
} else {
dojo.date.setDayOfYear(set[zz],regexResult[2]);
}
}
} else {
var subset=[];
for (var zz=0; zz < set.length; zz++) {
var newDate = new Date(set[zz]);
if (regexResult[1] == "-") {
dojo.date.setDayOfYear(newDate,366-regexResult[2]);
} else {
dojo.date.setDayOfYear(newDate,regexResult[2]);
}
subset.push(newDate);
}
tmp = set.concat(subset);
set = tmp;
}
}
}
}
if (rrule["bymonthday"] && (order["bymonthday"]<freqInt)) {
if (rrule["bymonthday"].length > 0) {
var regex = "([+-]?)([0-9]{1,3})";
for (var z=0; z<rrule["bymonthday"].length; z++) {
var regexResult = rrule["bymonthday"][z].match(regex);
if (z==0) {
for (var zz=0; zz < set.length; zz++) {
if (regexResult[1] == "-") {
if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
set[zz].setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
}
} else {
if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
set[zz].setDate(regexResult[2]);
}
}
}
} else {
var subset=[];
for (var zz=0; zz < set.length; zz++) {
var newDate = new Date(set[zz]);
if (regexResult[1] == "-") {
if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
newDate.setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
}
} else {
if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
newDate.setDate(regexResult[2]);
}
}
subset.push(newDate);
}
tmp = set.concat(subset);
set = tmp;
}
}
}
}
if (rrule["byday"] && (order["byday"]<freqInt)) {
if (rrule["bymonth"]) {
if (rrule["byday"].length > 0) {
var regex = "([+-]?)([0-9]{0,1}?)([A-Za-z]{1,2})";
for (var z=0; z<rrule["byday"].length; z++) {
var regexResult = rrule["byday"][z].match(regex);
var occurance = regexResult[2];
var day = regexResult[3].toLowerCase();
if (z==0) {
for (var zz=0; zz < set.length; zz++) {
if (regexResult[1] == "-") {
//find the nth to last occurance of date
var numDaysFound = 0;
var lastDayOfMonth = dojo.date.getDaysInMonth(set[zz]);
var daysToSubtract = 1;
set[zz].setDate(lastDayOfMonth);
if (weekdays[set[zz].getDay()] == day) {
numDaysFound++;
daysToSubtract=7;
}
daysToSubtract = 1;
while (numDaysFound < occurance) {
set[zz].setDate(set[zz].getDate()-daysToSubtract);
if (weekdays[set[zz].getDay()] == day) {
numDaysFound++;
daysToSubtract=7;
}
}
} else {
if (occurance) {
var numDaysFound=0;
set[zz].setDate(1);
var daysToAdd=1;
if(weekdays[set[zz].getDay()] == day) {
numDaysFound++;
daysToAdd=7;
}
while(numDaysFound < occurance) {
set[zz].setDate(set[zz].getDate()+daysToAdd);
if(weekdays[set[zz].getDay()] == day) {
numDaysFound++;
daysToAdd=7;
}
}
} else {
//we're gonna expand here to add a date for each of the specified days for each month
var numDaysFound=0;
var subset = [];
lastDayOfMonth = new Date(set[zz]);
var daysInMonth = dojo.date.getDaysInMonth(set[zz]);
lastDayOfMonth.setDate(daysInMonth);
set[zz].setDate(1);
if (weekdays[set[zz].getDay()] == day) {
numDaysFound++;
}
var tmpDate = new Date(set[zz]);
daysToAdd = 1;
while(tmpDate.getDate() < lastDayOfMonth) {
if (weekdays[tmpDate.getDay()] == day) {
numDaysFound++;
if (numDaysFound==1) {
set[zz] = tmpDate;
} else {
subset.push(tmpDate);
tmpDate = new Date(tmpDate);
daysToAdd=7;
tmpDate.setDate(tmpDate.getDate() + daysToAdd);
}
} else {
tmpDate.setDate(tmpDate.getDate() + daysToAdd);
}
}
var t = set.concat(subset);
set = t;
}
}
}
} else {
var subset=[];
for (var zz=0; zz < set.length; zz++) {
var newDate = new Date(set[zz]);
if (regexResult[1] == "-") {
if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
newDate.setDate(dojo.date.getDaysInMonth(set[zz]) - regexResult[2]);
}
} else {
if (regexResult[2] < dojo.date.getDaysInMonth(set[zz])) {
newDate.setDate(regexResult[2]);
}
}
subset.push(newDate);
}
tmp = set.concat(subset);
set = tmp;
}
}
}
} else {
dojo.debug("TODO: byday within a yearly rule without a bymonth");
}
}
dojo.debug("TODO: Process BYrules for units larger than frequency");
//add this set of events to the complete recurranceSet
var tmp = recurranceSet.concat(set);
recurranceSet = tmp;
}
}
// TODO: add rdates to the recurrance set here
// TODO: subtract exdates from the recurrance set here
//TODO: subtract dates generated by exrules from recurranceSet here
recurranceSet.push(dtstart);
return recurranceSet;
},
getDate: function() {
return dojo.date.fromIso8601(this.dtstart.value);
}
});
/*
* VTIMEZONE
*/
var VTimeZoneProperties = [
_P("tzid", 1, true), _P("last-mod", 1), _P("tzurl", 1)
// one of 'standardc' or 'daylightc' must occur
// and each may occur more than once.
];
dojo.cal.iCalendar.VTimeZone = function (/* string */ body) {
// summary
// VTIMEZONE Component
this.name = "VTIMEZONE";
this._ValidProperties = VTimeZoneProperties;
dojo.cal.iCalendar.Component.call(this, body);
}
dojo.inherits(dojo.cal.iCalendar.VTimeZone, dojo.cal.iCalendar.Component);
/*
* VTODO
*/
var VTodoProperties = [
// these can occur once only
_P("class", 1), _P("completed", 1), _P("created", 1), _P("description", 1),
_P("dtstart", 1), _P("geo", 1), _P("last-mod", 1), _P("location", 1),
_P("organizer", 1), _P("percent", 1), _P("priority", 1), _P("dtstamp", 1),
_P("seq", 1), _P("status", 1), _P("summary", 1), _P("uid", 1), _P("url", 1),
_P("recurid", 1),
// these two are exclusive
[_P("due", 1), _P("duration", 1)],
// these can occur many times over
_P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"),
_P("exdate"), _P("exrule"), _P("rstatus"), _P("related"), _P("resources"),
_P("rdate"), _P("rrule")
];
dojo.cal.iCalendar.VTodo= function (/* string */ body) {
// summary
// VTODO Componenet
this.name = "VTODO";
this._ValidProperties = VTodoProperties;
dojo.cal.iCalendar.Component.call(this, body);
}
dojo.inherits(dojo.cal.iCalendar.VTodo, dojo.cal.iCalendar.Component);
/*
* VJOURNAL
*/
var VJournalProperties = [
// these can occur once only
_P("class", 1), _P("created", 1), _P("description", 1), _P("dtstart", 1),
_P("last-mod", 1), _P("organizer", 1), _P("dtstamp", 1), _P("seq", 1),
_P("status", 1), _P("summary", 1), _P("uid", 1), _P("url", 1), _P("recurid", 1),
// these can occur many times over
_P("attach"), _P("attendee"), _P("categories"), _P("comment"), _P("contact"),
_P("exdate"), _P("exrule"), _P("related"), _P("rstatus"), _P("rdate"), _P("rrule")
];
dojo.cal.iCalendar.VJournal= function (/* string */ body) {
// summary
// VJOURNAL Component
this.name = "VJOURNAL";
this._ValidProperties = VJournalProperties;
dojo.cal.iCalendar.Component.call(this, body);
}
dojo.inherits(dojo.cal.iCalendar.VJournal, dojo.cal.iCalendar.Component);
/*
* VFREEBUSY
*/
var VFreeBusyProperties = [
// these can occur once only
_P("contact"), _P("dtstart", 1), _P("dtend"), _P("duration"),
_P("organizer", 1), _P("dtstamp", 1), _P("uid", 1), _P("url", 1),
// these can occur many times over
_P("attendee"), _P("comment"), _P("freebusy"), _P("rstatus")
];
dojo.cal.iCalendar.VFreeBusy= function (/* string */ body) {
// summary
// VFREEBUSY Component
this.name = "VFREEBUSY";
this._ValidProperties = VFreeBusyProperties;
dojo.cal.iCalendar.Component.call(this, body);
}
dojo.inherits(dojo.cal.iCalendar.VFreeBusy, dojo.cal.iCalendar.Component);
/*
* VALARM
*/
var VAlarmProperties = [
[_P("action", 1, true), _P("trigger", 1, true), [_P("duration", 1), _P("repeat", 1)],
_P("attach", 1)],
[_P("action", 1, true), _P("description", 1, true), _P("trigger", 1, true),
[_P("duration", 1), _P("repeat", 1)]],
[_P("action", 1, true), _P("description", 1, true), _P("trigger", 1, true),
_P("summary", 1, true), _P("attendee", "*", true),
[_P("duration", 1), _P("repeat", 1)],
_P("attach", 1)],
[_P("action", 1, true), _P("attach", 1, true), _P("trigger", 1, true),
[_P("duration", 1), _P("repeat", 1)],
_P("description", 1)],
];
dojo.cal.iCalendar.VAlarm= function (/* string */ body) {
// summary
// VALARM Component
this.name = "VALARM";
this._ValidProperties = VAlarmProperties;
dojo.cal.iCalendar.Component.call(this, body);
}
dojo.inherits(dojo.cal.iCalendar.VAlarm, dojo.cal.iCalendar.Component);
@@ -0,0 +1,75 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.cal.textDirectory");
dojo.require("dojo.string");
/*
* This class parses a single line from a text/directory file
* and returns an object with four named values; name, group, params
* and value. name, group and value are strings containing the original
* tokens unaltered and values is an array containing name/value pairs
* or a single name token packed into arrays.
*/
dojo.cal.textDirectory.Property = function (line) {
// split into name/value pair
var left = dojo.string.trim(line.substring(0, line.indexOf(':')));
var right = dojo.string.trim(line.substr(line.indexOf(':') + 1));
// seperate name and paramters
var parameters = dojo.string.splitEscaped(left,';');
this.name = parameters[0]
parameters.splice(0, 1);
// parse paramters
this.params = [];
for (var i = 0; i < parameters.length; i++) {
var arr = parameters[i].split("=");
var key = dojo.string.trim(arr[0].toUpperCase());
if (arr.length == 1) { this.params.push([key]); continue; }
var values = dojo.string.splitEscaped(arr[1],',');
for (var j = 0; j < values.length; j++) {
if (dojo.string.trim(values[j]) != '') {
this.params.push([key, dojo.string.trim(values[j])]);
}
}
}
// seperate group
if (this.name.indexOf('.') > 0) {
var arr = this.name.split('.');
this.group = arr[0];
this.name = arr[1];
}
// don't do any parsing, leave to implementation
this.value = right;
}
// tokeniser, parses into an array of properties.
dojo.cal.textDirectory.tokenise = function (text) {
// normlize to one propterty per line and parse
var nText = dojo.string.normalizeNewlines(text,"\n");
nText = nText.replace(/\n[ \t]/g, '');
nText = nText.replace(/\x00/g, '');
var lines = nText.split("\n");
var properties = []
for (var i = 0; i < lines.length; i++) {
if (dojo.string.trim(lines[i]) == '') { continue; }
var prop = new dojo.cal.textDirectory.Property(lines[i]);
properties.push(prop);
}
return properties;
}
@@ -0,0 +1,146 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.Axis");
dojo.require("dojo.lang.common");
dojo.charting.Axis = function(/* string? */label, /* string? */scale, /* array? */labels){
var id = "dojo-charting-axis-"+dojo.charting.Axis.count++;
this.getId=function(){ return id; };
this.setId=function(key){ id = key; };
this.scale = scale || "linear"; // linear || log
this.label = label || "";
this.showLabel = true; // show axis label.
this.showLabels = true; // show interval ticks.
this.showLines = false; // if you want lines over the range of the plot area
this.showTicks = false; // if you want tick marks on the axis.
this.range = { upper : 0, lower : 0 }; // range of individual axis.
this.origin = "min"; // this can be any number, "min" or "max". min/max is translated on init.
this.labels = labels || [];
this._labels = []; // what we really use to draw things.
this.nodes={ main: null, axis: null, label: null, labels: null, lines: null, ticks: null };
};
dojo.charting.Axis.count = 0;
dojo.extend(dojo.charting.Axis, {
// TODO: implement log scaling.
getCoord: function(
/* float */val,
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot
){
// summary
// returns the coordinate of val based on this axis range, plot area and plot.
val = parseFloat(val, 10);
var area = plotArea.getArea();
if(plot.axisX == this){
var offset = 0 - this.range.lower;
var min = this.range.lower + offset; // FIXME: check this.
var max = this.range.upper + offset;
val += offset;
return (val*((area.right-area.left)/max))+area.left; // float
} else {
var max = this.range.upper;
var min = this.range.lower;
var offset = 0;
if(min<0){
offset += Math.abs(min);
}
max += offset; min += offset; val += offset;
var pmin = area.bottom;
var pmax = area.top;
return (((pmin-pmax)/(max-min))*(max-val))+pmax;
}
},
initializeOrigin: function(drawAgainst, plane){
// figure out the origin value.
if(isNaN(this.origin)){
if(this.origin.toLowerCase() == "max"){
this.origin = drawAgainst.range[(plane=="y")?"upper":"lower"];
}
else if (this.origin.toLowerCase() == "min"){
this.origin = drawAgainst.range[(plane=="y")?"lower":"upper"];
}
else { this.origin=0; }
}
},
initializeLabels: function(){
// Translate the labels if needed.
if(this.labels.length == 0){
this.showLabels = false;
this.showLines = false;
this.showTicks = false;
} else {
if(this.labels[0].label && this.labels[0].value != null){
for(var i=0; i<this.labels.length; i++){
this._labels.push(this.labels[i]);
}
}
else if(!isNaN(this.labels[0])){
for(var i=0; i<this.labels.length; i++){
this._labels.push({ label: this.labels[i], value: this.labels[i] });
}
}
else {
// clone me
var a = [];
for(var i=0; i<this.labels.length; i++){
a.push(this.labels[i]);
}
// do the bottom one.
var s=a.shift();
this._labels.push({ label: s, value: this.range.lower });
// do the top one.
if(a.length>0){
var s=a.pop();
this._labels.push({ label: s, value: this.range.upper });
}
// do the rest.
if(a.length>0){
var range = this.range.upper - this.range.lower;
var step = range / (this.labels.length-1);
for(var i=1; i<=a.length; i++){
this._labels.push({
label: a[i-1],
value: this.range.lower+(step*i)
});
}
}
}
}
},
initialize: function(plotArea, plot, drawAgainst, plane){
// summary
// Initialize the passed axis descriptor. Note that this should always
// be the result of plotArea.getAxes, and not the axis directly!
this.destroy();
this.initializeOrigin(drawAgainst, plane);
this.initializeLabels();
var node = this.render(plotArea, plot, drawAgainst, plane);
return node;
},
destroy: function(){
for(var p in this.nodes){
while(this.nodes[p] && this.nodes[p].childNodes.length > 0){
this.nodes[p].removeChild(this.nodes[p].childNodes[0]);
}
if(this.nodes[p] && this.nodes[p].parentNode){
this.nodes[p].parentNode.removeChild(this.nodes[p]);
}
this.nodes[p] = null;
}
}
});
dojo["requireIf"](dojo.render.svg.capable, "dojo.charting.svg.Axis");
dojo["requireIf"](!dojo.render.svg.capable && dojo.render.vml.capable, "dojo.charting.vml.Axis");
@@ -0,0 +1,85 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.Chart");
dojo.require("dojo.lang.common");
dojo.require("dojo.charting.PlotArea");
dojo.charting.Chart = function(
/* HTMLElement? */node,
/* string? */title,
/* string? */description
){
// summary
// Create the basic Chart object.
this.node = node || null;
this.title = title || "Chart"; // pure string.
this.description = description || ""; // HTML is allowed.
this.plotAreas = [];
};
dojo.extend(dojo.charting.Chart, {
// methods
addPlotArea: function(/* object */obj, /* bool? */doRender){
// summary
// Add a PlotArea to this chart; object should be in the
// form of: { plotArea, (x, y) or (top, left) }
if(obj.x && !obj.left){ obj.left = obj.x; }
if(obj.y && !obj.top){ obj.top = obj.y; }
this.plotAreas.push(obj);
if(doRender){ this.render(); }
},
// events
onInitialize:function(chart){ },
onRender:function(chart){ },
onDestroy:function(chart){ },
// standard build methods
initialize: function(){
// summary
// Initialize the Chart by rendering it.
if(!this.node){
dojo.raise("dojo.charting.Chart.initialize: there must be a root node defined for the Chart.");
}
this.destroy();
this.render();
this.onInitialize(this);
},
render:function(){
// summary
// Render the chart in its entirety.
if(this.node.style.position != "absolute"){
this.node.style.position = "relative";
}
for(var i=0; i<this.plotAreas.length; i++){
var area = this.plotAreas[i].plotArea;
var node = area.initialize();
node.style.position = "absolute";
node.style.top = this.plotAreas[i].top + "px";
node.style.left = this.plotAreas[i].left + "px";
this.node.appendChild(node);
area.render();
}
},
destroy: function(){
// summary
// Destroy any nodes that have maintained references.
// kill any existing plotAreas
for(var i=0; i<this.plotAreas.length; i++){
this.plotAreas[i].plotArea.destroy();
};
// clean out any child nodes.
while(this.node && this.node.childNodes && this.node.childNodes.length > 0){
this.node.removeChild(this.node.childNodes[0]);
}
}
});
@@ -0,0 +1,103 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.Plot");
dojo.require("dojo.lang.common");
dojo.require("dojo.charting.Axis");
dojo.require("dojo.charting.Series");
dojo.charting.RenderPlotSeries = { Singly:"single", Grouped:"grouped" };
dojo.charting.Plot = function(
/* dojo.charting.Axis? */xaxis,
/* dojo.charting.Axis? */yaxis,
/* dojo.charting.Series[]? */series
){
// summary
// Creates a new instance of a Plot (X/Y Axis + n Series).
var id = "dojo-charting-plot-"+dojo.charting.Plot.count++;
this.getId=function(){ return id; };
this.setId=function(key){ id = key; };
this.axisX = null;
this.axisY = null;
this.series = [];
this.dataNode = null;
// for bar charts, pie charts and stacked charts, change to Grouped.
this.renderType = dojo.charting.RenderPlotSeries.Singly;
if(xaxis){
this.setAxis(xaxis,"x");
}
if(yaxis){
this.setAxis(yaxis,"y");
}
if(series){
for(var i=0; i<series.length; i++){ this.addSeries(series[i]); }
}
}
dojo.charting.Plot.count=0;
dojo.extend(dojo.charting.Plot, {
addSeries: function(
/* dojo.charting.Series || object */series,
/* function? */plotter
){
// summary
// Add a new Series to this plot. Can take the form of a Series, or an object
// of the form { series, plotter }
if(series.plotter){
this.series.push(series);
} else {
this.series.push({
data: series,
plotter: plotter || dojo.charting.Plotters["Default"]
});
}
},
setAxis: function(/* dojo.charting.Axis */axis, /* string */which){
// summary
// Set the axis on which plane.
if(which.toLowerCase()=="x"){ this.axisX = axis; }
else if(which.toLowerCase()=="y"){ this.axisY = axis; }
},
getRanges: function(){
// summary
// set the ranges on these axes.
var xmin, xmax, ymin, ymax;
xmin=ymin=Number.MAX_VALUE;
xmax=ymax=Number.MIN_VALUE;
for(var i=0; i<this.series.length; i++){
var values = this.series[i].data.evaluate(); // full data range.
for(var j=0; j<values.length; j++){
var comp=values[j];
xmin=Math.min(comp.x, xmin);
ymin=Math.min(comp.y, ymin);
xmax=Math.max(comp.x, xmax);
ymax=Math.max(comp.y, ymax);
}
}
return {
x:{ upper: xmax, lower:xmin },
y:{ upper: ymax, lower:ymin },
toString:function(){
return "[ x:"+xmax+" - "+xmin+", y:"+ymax+" - "+ymin+"]";
}
}; // object
},
destroy: function(){
// summary
// Clean out any existing DOM node references.
var node=this.dataNode;
while(node && node.childNodes && node.childNodes.length > 0){
node.removeChild(node.childNodes[0]);
}
this.dataNode=null;
}
});
@@ -0,0 +1,193 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.PlotArea");
dojo.require("dojo.lang.common");
dojo.require("dojo.gfx.color");
dojo.require("dojo.gfx.color.hsl");
dojo.require("dojo.charting.Plot");
dojo.charting.PlotArea = function(){
// summary
// Creates a new PlotArea for drawing onto a Chart.
var id="dojo-charting-plotarea-"+dojo.charting.PlotArea.count++;
this.getId=function(){ return id; };
this.setId=function(key){ id = key; };
this.areaType = "standard"; // standard || radar
this.plots = []; // plots that will be drawn on this area
this.size={ width:600, height:400 };
this.padding={ top:10, right:10, bottom:20, left:20 };
// drawing node references.
this.nodes = {
main:null,
area:null,
background: null,
axes: null,
plots: null
};
// this is preset for a limited color range (green to purple),
// anticipating a max of 32 series on this plot area.
// if you need more flexibility, override these numbers.
this._color = { h: 140, s: 120, l: 120, step: 27 };
};
dojo.charting.PlotArea.count = 0;
dojo.extend(dojo.charting.PlotArea, {
nextColor: function(){
// summary
// Advances the internal HSV cursor and returns the next generated color.
var rgb=dojo.gfx.color.hsl2rgb(this._color.h, this._color.s, this._color.l);
this._color.h = (this._color.h + this._color.step)%360;
while(this._color.h < 140){
this._color.h += this._color.step;
}
return dojo.gfx.color.rgb2hex(rgb[0], rgb[1], rgb[2]); // string
},
getArea:function(){
// summary
// Return an object describing the coordinates of the available area to plot on.
return {
left: this.padding.left,
right: this.size.width - this.padding.right,
top: this.padding.top,
bottom: this.size.height - this.padding.bottom,
toString:function(){
var a=[ this.top, this.right, this.bottom, this.left ];
return "["+a.join()+"]";
}
}; // object
},
getAxes: function(){
// summary
// get the unique axes for this plot area.
var axes={};
for(var i=0; i<this.plots.length; i++){
var plot=this.plots[i];
axes[plot.axisX.getId()] = {
axis: plot.axisX,
drawAgainst: plot.axisY,
plot: plot,
plane: "x"
};
axes[plot.axisY.getId()] = {
axis: plot.axisY,
drawAgainst: plot.axisX,
plot: plot,
plane: "y"
};
}
return axes; // object
},
getLegendInfo: function(){
// summary
// return an array describing all data series on this plot area.
var a=[];
for(var i=0; i<this.plots.length; i++){
for(var j=0; j<this.plots[i].series.length; j++){
var data = this.plots[i].series[j].data;
a.push({ label:data.label, color:data.color });
}
}
return a; // array
},
setAxesRanges: function(){
// summary
// Find and set the ranges on all axes on this plotArea.
// We do this because plots may have axes in common; if you
// want to use this, make sure you do it *before* initialization.
var ranges={};
var axes={};
for(var i=0; i<this.plots.length; i++){
var plot = this.plots[i];
var ranges=plot.getRanges();
var x=ranges.x;
var y=ranges.y;
var ax, ay;
if(!axes[plot.axisX.getId()]){
axes[plot.axisX.getId()]=plot.axisX;
ranges[plot.axisX.getId()]={upper: x.upper, lower:x.lower};
}
ax=ranges[plot.axisX.getId()];
ax.upper=Math.max(ax.upper, x.upper);
ax.lower=Math.min(ax.lower, x.lower);
if(!axes[plot.axisY.getId()]){
axes[plot.axisY.getId()]=plot.axisY;
ranges[plot.axisY.getId()]={upper: y.upper, lower:y.lower};
}
ay=ranges[plot.axisY.getId()];
ay.upper=Math.max(ay.upper, y.upper);
ay.lower=Math.min(ay.lower, y.lower);
}
// now that we have all the max/min ranges, set the axes
for(var p in axes){
axes[p].range=ranges[p];
}
},
render: function(/* object? */kwArgs, /* function? */applyToData){
// summary
// Render this plotArea. Optional kwArgs are the same as that taken for Series.evaluate;
// applyToData is a callback function used by plotters for customization.
if(!this.nodes.main
|| !this.nodes.area
|| !this.nodes.background
|| !this.nodes.plots
|| !this.nodes.axes
){ this.initialize(); }
// plot it.
for(var i=0; i<this.plots.length; i++){
var plot=this.plots[i];
this.nodes.plots.removeChild(plot.dataNode);
var target = this.initializePlot(plot);
switch(plot.renderType){
case dojo.charting.RenderPlotSeries.Grouped: {
// ALWAYS plot using the first plotter, ignore any others.
target.appendChild(plot.series[0].plotter(this, plot, kwArgs, applyToData));
break;
}
case dojo.charting.RenderPlotSeries.Singly:
default: {
for(var j=0; j<plot.series.length; j++){
var series = plot.series[j];
var data = series.data.evaluate(kwArgs);
target.appendChild(series.plotter(data, this, plot, applyToData));
}
}
}
this.nodes.plots.appendChild(target);
}
},
destroy: function(){
// summary
// Clean out any existing DOM references.
for(var i=0; i<this.plots.length; i++){
this.plots[i].destroy();
};
// clean out any child nodes.
for(var p in this.nodes){
var node=this.nodes[p];
if(!node) continue;
if(!node.childNodes) continue;
while(node.childNodes.length > 0){
node.removeChild(node.childNodes[0]);
}
this.nodes[p]=null;
}
}
});
dojo["requireIf"](dojo.render.svg.capable, "dojo.charting.svg.PlotArea");
dojo["requireIf"](!dojo.render.svg.capable && dojo.render.vml.capable, "dojo.charting.vml.PlotArea");
@@ -0,0 +1,19 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.Plotters");
/*
* Plotters is the placeholder; what will happen is that the proper renderer types
* will be mixed into this object (as opposed to creating a new one).
*/
dojo["requireIf"](dojo.render.svg.capable, "dojo.charting.svg.Plotters");
dojo["requireIf"](!dojo.render.svg.capable && dojo.render.vml.capable, "dojo.charting.vml.Plotters");
@@ -0,0 +1,46 @@
Dojo Charting Engine
=========================================================================
The Dojo Charting Engine is a (fairly) complex object structure, designed
to provide as much flexibility as possible in terms of chart construction.
To this end, the engine details the following structure:
Chart
---PlotArea[]
------Plot[]
---------Axis (axisX)
---------Axis (axisY)
---------Series[]
A Chart object is the main entity; it is the entire graphic. A Chart may
have any number of PlotArea objects, which are the basic canvas against
which data is plotted. A PlotArea may have any number of Plot objects,
which is a container representing up to 2 axes and any number of series
to be plotted against those axes; a Series represents a binding against
two fields from a data source (initial rev, this data source is always of
type dojo.collections.Store but this will probably change once dojo.data
is in production).
The point of this structure is to allow for as much flexibility as possible
in terms of what kinds of charts can be represented by the engine. The
current plan is to accomodate up to analytical financial charts, which tend
to have 3 plot areas and any number of different types of axes on each one.
The main exception to this is the pie chart, which will have it's own
custom codebase. Also, 3D charts are not accounted for at this time,
although the only thing that will probably need to be altered to make
that work would be Plot and Series (to accomodate the additional Z axis).
Finally, a Plot will render its series[] through the use of Plotters, which
are custom methods to render specific types of charts.
-------------------------------------------------------------------------
In terms of widgets, the basic concept is that there is a central, super-
flexible Chart widget (Chart, oddly enough), and then any number of preset
chart type widgets, that are basically built to serve a simple, easy
purpose. For instance, if someone just needs to plot a series of lines,
they would be better off using the LineChart widget; but if someone needed
to plot a combo chart, that has 2 Y Axes (one linear, one log) against the
same X Axis, using lines and areas, then they will want to use a Chart widget.
Note also that unlike other widgets, the Charting engine *can* be called
directly from script *without* the need for the actual widget engine to be
loaded; the Chart widgets are thin wrappers around the charting engine.
@@ -0,0 +1,215 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.Series");
dojo.require("dojo.lang.common");
dojo.require("dojo.charting.Plotters");
dojo.charting.Series = function(/* object? */kwArgs){
// summary
// Create an instance of data series for plotting.
var args = kwArgs || { length:1 };
this.dataSource = args.dataSource || null;
this.bindings = { };
this.color = args.color;
this.label = args.label;
if(args.bindings){
for(var p in args.bindings){
this.addBinding(p, args.bindings[p]);
}
}
};
dojo.extend(dojo.charting.Series, {
bind:function(/* dojo.collections.Store */src, /* object */bindings){
// summary
// Bind this series to src, with bindings.
this.dataSource = src;
this.bindings = bindings;
},
addBinding:function(/* string */name, /* string */binding){
// summary
// Bind to field "binding" using "name".
this.bindings[name] = binding;
},
evaluate:function(/* object? */kwArgs){
// summary
// Evaluate all bindings and return an array of objects describing the bind.
var ret = [];
var a = this.dataSource.getData();
var l = a.length;
var start = 0;
var end = l;
/* Allow for ranges. Can be done in one of two ways:
* 1. { from, to } as 0-based indices
* 2. { length } as num of data points to get; a negative
* value will start from the end of the data set.
* No kwArg object means the full data set will be evaluated
* and returned.
*/
if(kwArgs){
if(kwArgs.from){
start = Math.max(kwArgs.from,0);
if(kwArgs.to){
end = Math.min(kwArgs.to, end);
}
}
else if(kwArgs.length){
if(kwArgs.length < 0){
// length points from end
start = Math.max((end + length),0);
} else {
end = Math.min((start + length), end);
}
}
}
for(var i=start; i<end; i++){
var o = { src: a[i], series: this };
for(var p in this.bindings){
o[p] = this.dataSource.getField(a[i], this.bindings[p]);
}
ret.push(o);
}
// sort by the x axis, if available.
if(typeof(ret[0].x) != "undefined"){
ret.sort(function(a,b){
if(a.x > b.x) return 1;
if(a.x < b.x) return -1;
return 0;
});
}
return ret; // array
},
// trends
trends:{
createRange: function(/* array */values, /* int */len){
// summary
// Creates the data range used for all trends.
var idx = values.length-1;
var length = (len||values.length);
return { "index": idx, "length": length, "start":Math.max(idx-length,0) }; // object
},
mean: function(/* array */values, /* int */len){
// summary
// Returns the mean or average over the set of values.
var range = this.createRange(values, len);
if(range.index<0){ return 0; }
var total = 0;
var count = 0;
for(var i=range.index; i>=range.start; i--){
total += values[i].y;
count++;
}
total /= Math.max(count,1);
return total; // float
},
variance: function(/* array */values,/* int */len){
// summary
// Returns the variance of the set of values.
var range = this.createRange(values,len);
if(range.index < 0){ return 0; }
var total = 0;
var square = 0;
var count = 0;
for(var i=range.index; i>=range.start; i--){
total += values[i].y;
square += Math.pow(values[i].y, 2);
count++;
}
return (square/count)-Math.pow(total/count,2); // float
},
standardDeviation: function(/* array */values, /* int */len){
// summary
// Returns the standard deviation of the set of values.
return Math.sqrt(this.getVariance(values, len)); // float
},
max: function(/* array */values, /* int */len){
// summary
// Returns the max number in the set of values.
var range = this.createRange(values, len);
if(range.index < 0){ return 0; }
var max = Number.MIN_VALUE;
for (var i=range.index; i>=range.start; i--){
max = Math.max(values[i].y,max);
}
return max; // float
},
min: function(/* array */values, /* int */len){
// summary
// Returns the lowest number in the set of values.
var range=this.createRange(values, len);
if(range.index < 0){ return 0; }
var min = Number.MAX_VALUE;
for(var i=range.index; i>=range.start; i--){
min = Math.min(values[i].y, min);
}
return min; // float
},
median: function(/* array */values, /* int */len){
// summary
// Returns the median in the set of values (number closest to the middle of a sorted set).
var range = this.createRange(values, len);
if(range.index<0){ return 0; }
var a = [];
for (var i=range.index; i>=range.start; i--){
var b=false;
for(var j=0; j<a.length; j++){
if(values[i].y == a[j]){
b = true;
break;
}
}
if(!b){
a.push(values[i].y);
}
}
a.sort();
if(a.length > 0){
return a[Math.ceil(a.length / 2)]; // float
}
return 0; // float
},
mode: function(/* array */values, /* int */len){
// summary
// Returns the mode in the set of values
var range=this.createRange(values, len);
if(range.index<0){ return 0; }
var o = {};
var ret = 0
var median = Number.MIN_VALUE;
for(var i=range.index; i>=range.start; i--){
if (!o[values[i].y]){
o[values[i].y] = 1;
} else {
o[values[i].y]++;
}
}
for(var p in o){
if(median < o[p]){
median = o[p];
ret=p;
}
}
return ret;
}
}
});
@@ -0,0 +1,11 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.*");
@@ -0,0 +1,224 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.svg.Axis");
dojo.require("dojo.lang.common");
dojo.extend(dojo.charting.Axis, {
renderLines: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* string */plane
){
// summary
// Renders any reference lines for this axis.
if(this.nodes.lines){
while(this.nodes.lines.childNodes.length > 0){
this.nodes.lines.removeChild(this.nodes.lines.childNodes[0]);
}
if(this.nodes.lines.parentNode){
this.nodes.lines.parentNode.removeChild(this.nodes.lines);
this.nodes.lines = null;
}
}
var area = plotArea.getArea();
var g = this.nodes.lines = document.createElementNS(dojo.svg.xmlns.svg, "g");
g.setAttribute("id", this.getId()+"-lines");
for(var i=0; i<this._labels.length; i++){
if (this._labels[i].value == this.origin){ continue; }
var v = this.getCoord(this._labels[i].value, plotArea, plot);
var l=document.createElementNS(dojo.svg.xmlns.svg, "line");
l.setAttribute("style","stroke:#999;stroke-width:1px;stroke-dasharray:1,4;");
if(plane == "x"){
l.setAttribute("y1",area.top);
l.setAttribute("y2",area.bottom);
l.setAttribute("x1",v);
l.setAttribute("x2",v);
}
else if (plane == "y"){
l.setAttribute("y1",v);
l.setAttribute("y2",v);
l.setAttribute("x1",area.left);
l.setAttribute("x2",area.right);
}
g.appendChild(l);
}
return g; // SVGGElement
},
renderTicks: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* string */plane,
/* float */coord
){
// summary
// Renders any tick lines for this axis.
if(this.nodes.ticks){
while(this.nodes.ticks.childNodes.length > 0){
this.nodes.ticks.removeChild(this.nodes.ticks.childNodes[0]);
}
if(this.nodes.ticks.parentNode){
this.nodes.ticks.parentNode.removeChild(this.nodes.ticks);
this.nodes.ticks = null;
}
}
var g = this.nodes.ticks = document.createElementNS(dojo.svg.xmlns.svg, "g");
g.setAttribute("id", this.getId()+"-ticks");
for(var i=0; i<this._labels.length; i++){
var v = this.getCoord(this._labels[i].value, plotArea, plot);
var l=document.createElementNS(dojo.svg.xmlns.svg, "line");
l.setAttribute("style","stroke:#000;stroke-width:1pt;");
if(plane == "x"){
l.setAttribute("y1",coord);
l.setAttribute("y2",coord+3);
l.setAttribute("x1",v);
l.setAttribute("x2",v);
}
else if (plane == "y"){
l.setAttribute("y1",v);
l.setAttribute("y2",v);
l.setAttribute("x1",coord-2);
l.setAttribute("x2",coord+2);
}
g.appendChild(l);
}
return g; // SVGGElement
},
renderLabels: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* string */plane,
/* float */coord,
/* int */textSize,
/* string */anchor
){
// summary
// Render all labels for this axis.
function createLabel(label, x, y, textSize, anchor){
var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
text.setAttribute("x", x);
text.setAttribute("y", (plane=="x"?y:y+2));
text.setAttribute("style", "text-anchor:"+anchor+";font-family:sans-serif;font-size:"+textSize+"px;fill:#000;");
text.appendChild(document.createTextNode(label));
return text;
};
// wipe if needed
if(this.nodes.labels){
while(this.nodes.labels.childNodes.length > 0){
this.nodes.labels.removeChild(this.nodes.labels.childNodes[0]);
}
if(this.nodes.labels.parentNode){
this.nodes.labels.parentNode.removeChild(this.nodes.labels);
this.nodes.labels = null;
}
}
var g = this.nodes.labels = document.createElementNS(dojo.svg.xmlns.svg, "g");
g.setAttribute("id", this.getId()+"-labels");
for(var i=0; i<this._labels.length; i++){
var v = this.getCoord(this._labels[i].value, plotArea, plot);
if(plane == "x"){
g.appendChild(createLabel(this._labels[i].label, v, coord, textSize, anchor));
}
else if (plane == "y"){
g.appendChild(createLabel(this._labels[i].label, coord, v, textSize, anchor));
}
}
return g; // SVGGelement
},
render: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* dojo.charting.Axis */drawAgainst,
/* string */plane
){
// summary
// Renders this axis to the given plot.
// get the origin plot point.
var area = plotArea.getArea();
var stroke = 1;
var style = "stroke:#000;stroke-width:"+stroke+"px;";
var textSize=10;
var coord = drawAgainst.getCoord(this.origin, plotArea, plot);
// draw the axis.
this.nodes.main = document.createElementNS(dojo.svg.xmlns.svg, "g");
var g = this.nodes.main;
g.setAttribute("id", this.getId()); // need a handle if we have to kill parts of the axis def.
var line = this.nodes.axis = document.createElementNS(dojo.svg.xmlns.svg, "line");
if(plane == "x"){
line.setAttribute("y1", coord);
line.setAttribute("y2", coord);
line.setAttribute("x1", area.left-stroke);
line.setAttribute("x2", area.right+stroke);
line.setAttribute("style", style);
// set up the labels
var y = coord+textSize+2;
if(this.showLines){
g.appendChild(this.renderLines(plotArea, plot, plane, y));
}
if(this.showTicks){
g.appendChild(this.renderTicks(plotArea, plot, plane, coord));
}
if(this.showLabels){
g.appendChild(this.renderLabels(plotArea, plot, plane, y, textSize, "middle"));
}
if(this.showLabel && this.label){
var x = plotArea.size.width/2;
var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
text.setAttribute("x", x);
text.setAttribute("y", (coord + (textSize*2) + (textSize/2)));
text.setAttribute("style", "text-anchor:middle;font-family:sans-serif;font-weight:bold;font-size:"+(textSize+2)+"px;fill:#000;");
text.appendChild(document.createTextNode(this.label));
g.appendChild(text);
}
} else {
line.setAttribute("x1", coord);
line.setAttribute("x2", coord);
line.setAttribute("y1", area.top);
line.setAttribute("y2", area.bottom);
line.setAttribute("style", style);
// set up the labels
var isMax = this.origin == drawAgainst.range.upper;
var x = coord + (isMax?4:-4);
var anchor = isMax?"start":"end";
if(this.showLines){
g.appendChild(this.renderLines(plotArea, plot, plane, x));
}
if(this.showTicks){
g.appendChild(this.renderTicks(plotArea, plot, plane, coord));
}
if(this.showLabels){
g.appendChild(this.renderLabels(plotArea, plot, plane, x, textSize, anchor));
}
if(this.showLabel && this.label){
var x = isMax?(coord+(textSize*2)+(textSize/2)):(coord-(textSize*4));
var y = plotArea.size.height / 2;
var text = document.createElementNS(dojo.svg.xmlns.svg, "text");
text.setAttribute("x", x);
text.setAttribute("y", y);
text.setAttribute("transform", "rotate(90, " + x + ", " + y + ")");
text.setAttribute("style", "text-anchor:middle;font-family:sans-serif;font-weight:bold;font-size:"+(textSize+2)+"px;fill:#000;");
text.appendChild(document.createTextNode(this.label));
g.appendChild(text);
}
}
g.appendChild(line);
return g; // SVGGElement
}
});
@@ -0,0 +1,79 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.svg.PlotArea");
dojo.require("dojo.lang.common");
dojo.require("dojo.svg");
dojo.extend(dojo.charting.PlotArea, {
initializePlot: function(plot){
// summary
// Initialize the plot node for data rendering.
plot.destroy();
plot.dataNode = document.createElementNS(dojo.svg.xmlns.svg, "g");
plot.dataNode.setAttribute("id", plot.getId());
return plot.dataNode; // SVGGElement
},
initialize: function(){
// summary
// Initialize the PlotArea.
this.destroy(); // kill everything first.
// start with the background
this.nodes.main = document.createElement("div");
this.nodes.area = document.createElementNS(dojo.svg.xmlns.svg, "svg");
this.nodes.area.setAttribute("id", this.getId());
this.nodes.area.setAttribute("width", this.size.width);
this.nodes.area.setAttribute("height", this.size.height);
this.nodes.main.appendChild(this.nodes.area);
var area=this.getArea();
var defs = document.createElementNS(dojo.svg.xmlns.svg, "defs");
var clip = document.createElementNS(dojo.svg.xmlns.svg, "clipPath");
clip.setAttribute("id",this.getId()+"-clip");
var rect = document.createElementNS(dojo.svg.xmlns.svg, "rect");
rect.setAttribute("x", area.left);
rect.setAttribute("y", area.top);
rect.setAttribute("width", area.right-area.left);
rect.setAttribute("height", area.bottom-area.top);
clip.appendChild(rect);
defs.appendChild(clip);
this.nodes.area.appendChild(defs);
this.nodes.background = document.createElementNS(dojo.svg.xmlns.svg, "rect");
this.nodes.background.setAttribute("id", this.getId()+"-background");
this.nodes.background.setAttribute("width", this.size.width);
this.nodes.background.setAttribute("height", this.size.height);
this.nodes.background.setAttribute("fill", "#fff");
this.nodes.area.appendChild(this.nodes.background);
this.nodes.plots = document.createElementNS(dojo.svg.xmlns.svg, "g");
this.nodes.plots.setAttribute("id", this.getId()+"-plots");
this.nodes.plots.setAttribute("style","clip-path:url(#"+this.getId()+"-clip);");
this.nodes.area.appendChild(this.nodes.plots);
for(var i=0; i<this.plots.length; i++){
this.nodes.plots.appendChild(this.initializePlot(this.plots[i]));
}
// do the axes
this.nodes.axes = document.createElementNS(dojo.svg.xmlns.svg, "g");
this.nodes.axes.setAttribute("id", this.getId()+"-axes");
this.nodes.area.appendChild(this.nodes.axes);
var axes = this.getAxes();
for(var p in axes){
var obj = axes[p];
this.nodes.axes.appendChild(obj.axis.initialize(this, obj.plot, obj.drawAgainst, obj.plane));
}
return this.nodes.main; // HTMLDivElement
}
});
@@ -0,0 +1,872 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.svg.Plotters");
dojo.require("dojo.lang.common");
dojo.require("dojo.svg");
// TODO for 0.5: look at replacing manual plotting with dojo.gfx.
// Mixin the SVG-specific plotter object.
dojo.mixin(dojo.charting.Plotters, {
/*********************************************************
* Grouped plotters: need all series on a plot at once.
*********************************************************/
Bar: function(
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* object? */kwArgs,
/* function? */applyTo
){
// summary
// Plots a set of grouped bars.
// Bindings: y
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
// precompile the data
var n = plot.series.length; // how many series
var data = [];
for(var i=0; i<n; i++){
var tmp = plot.series[i].data.evaluate(kwArgs);
data.push(tmp);
}
// calculate the width of each bar.
var space = 8;
var nPoints = data[0].length;
var width = ((area.right-area.left)-(space*(nPoints-1)))/nPoints; // the width of each group.
var barWidth = width/n; // the width of each bar, no spaces.
var yOrigin = plot.axisY.getCoord(plot.axisX.origin, plotarea, plot);
for(var i=0; i<nPoints; i++){
// calculate offset
var xStart = area.left+(width*i)+(space*i);
for(var j=0; j<n; j++){
var value = data[j][i].y;
var yA = yOrigin;
var x = xStart + (barWidth*j);
var y = plot.axisY.getCoord(value, plotarea, plot);
var h = Math.abs(yA-y);
if(value < plot.axisX.origin){
yA = y;
y = yOrigin;
}
var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
bar.setAttribute("fill", data[j][i].series.color);
bar.setAttribute("stroke-width", "0");
bar.setAttribute("x", x);
bar.setAttribute("y", y);
bar.setAttribute("width", barWidth);
bar.setAttribute("height", h);
bar.setAttribute("fill-opacity", "0.6");
if(applyTo){ applyTo(bar, data[j][i].src); }
group.appendChild(bar);
}
}
return group; // SVGGElement
},
HorizontalBar: function(
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* object? */kwArgs,
/* function? */applyTo
){
// summary
// Plots data in a set of grouped bars horizontally.
// Bindings: y
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
// precompile the data
var n = plot.series.length; // how many series
var data = [];
for(var i=0; i<n; i++){
var tmp = plot.series[i].data.evaluate(kwArgs);
data.push(tmp);
}
var space = 6;
var nPoints = data[0].length;
var h = ((area.bottom-area.top)-(space*(nPoints-1)))/nPoints;
var barH = h/n;
var xOrigin = plot.axisX.getCoord(0, plotarea, plot);
for(var i=0; i<nPoints; i++){
// calculate offset
var yStart = area.top+(h*i)+(space*i);
for(var j=0; j<n; j++){
var value = data[j][i].y;
var y = yStart + (barH*j);
var xA = xOrigin;
var x = plot.axisX.getCoord(value, plotarea, plot);
var w = Math.abs(x-xA);
if(value > 0){
x = xOrigin;
}
var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
bar.setAttribute("fill", data[j][i].series.color);
bar.setAttribute("stroke-width", "0");
bar.setAttribute("x", xA);
bar.setAttribute("y", y);
bar.setAttribute("width", w);
bar.setAttribute("height", barH);
bar.setAttribute("fill-opacity", "0.6");
if(applyTo){ applyTo(bar, data[j][i].src); }
group.appendChild(bar);
}
}
return group; // SVGGElement
},
Gantt: function(
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* object? */kwArgs,
/* function? */applyTo
){
// summary
// Plots a grouped set of Gantt bars
// Bindings: high/low
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
// precompile the data
var n = plot.series.length; // how many series
var data = [];
for(var i=0; i<n; i++){
var tmp = plot.series[i].data.evaluate(kwArgs);
data.push(tmp);
}
var space = 2;
var nPoints = data[0].length;
var h = ((area.bottom-area.top)-(space*(nPoints-1)))/nPoints;
var barH = h/n;
for(var i=0; i<nPoints; i++){
// calculate offset
var yStart = area.top+(h*i)+(space*i);
for(var j=0; j<n; j++){
var high = data[j][i].high;
var low = data[j][i].low;
if(low > high){
var t = high;
high = low;
low = t;
}
var x = plot.axisX.getCoord(low, plotarea, plot);
var w = plot.axisX.getCoord(high, plotarea, plot) - x;
var y = yStart + (barH*j);
var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
bar.setAttribute("fill", data[j][i].series.color);
bar.setAttribute("stroke-width", "0");
bar.setAttribute("x", x);
bar.setAttribute("y", y);
bar.setAttribute("width", w);
bar.setAttribute("height", barH);
bar.setAttribute("fill-opacity", "0.6");
if(applyTo){ applyTo(bar, data[j][i].src); }
group.appendChild(bar);
}
}
return group; // SVGGElement
},
StackedArea: function(
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* object? */kwArgs,
/* function? */applyTo
){
// summary
// Plots a set of stacked areas.
// Bindings: x/y
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
// precompile the data
var n = plot.series.length; // how many series
var data = [];
var totals = [];
// we're assuming that all series for this plot has the name x assignment for now.
for(var i=0; i<n; i++){
var tmp = plot.series[i].data.evaluate(kwArgs);
// run through and add current totals
for(var j=0; j<tmp.length; j++){
if(i==0){ totals.push(tmp[j].y); }
else { totals[j] += tmp[j].y; }
tmp[j].y = totals[j];
}
data.push(tmp);
}
for(var i=n-1; i>=0; i--){
var path = document.createElementNS(dojo.svg.xmlns.svg, "path");
path.setAttribute("fill", data[i][0].series.color);
path.setAttribute("fill-opacity", "0.4");
path.setAttribute("stroke", data[i][0].series.color);
path.setAttribute("stroke-width" , "1");
path.setAttribute("stroke-opacity", "0.85");
var cmd = [];
var r=3;
for(var j=0; j<data[i].length; j++){
var values = data[i];
var x = plot.axisX.getCoord(values[j].x, plotarea, plot);
var y = plot.axisY.getCoord(values[j].y, plotarea, plot);
if(j==0){ cmd.push("M"); }
else { cmd.push("L"); }
cmd.push(x+","+y);
// points on the line
var c=document.createElementNS(dojo.svg.xmlns.svg, "circle");
c.setAttribute("cx",x);
c.setAttribute("cy",y);
c.setAttribute("r","3");
c.setAttribute("fill", values[j].series.color);
c.setAttribute("fill-opacity", "0.6");
c.setAttribute("stroke-width", "1");
c.setAttribute("stroke-opacity", "0.85");
group.appendChild(c);
if(applyTo){ applyTo(c, data[i].src); }
}
// now run the path backwards from the previous series.
if(i == 0){
cmd.push("L");
cmd.push(x + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("L");
cmd.push(plot.axisX.getCoord(data[0][0].x, plotarea, plot) + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("Z");
} else {
var values = data[i-1];
cmd.push("L");
cmd.push(x + "," + Math.round(plot.axisY.getCoord(values[values.length-1].y, plotarea, plot)));
for(var j=values.length-2; j>=0; j--){
var x = plot.axisX.getCoord(values[j].x, plotarea, plot);
var y = plot.axisY.getCoord(values[j].y, plotarea, plot);
cmd.push("L");
cmd.push(x+","+y);
}
}
path.setAttribute("d", cmd.join(" ")+ " Z");
group.appendChild(path);
}
return group; // SVGGElement
},
StackedCurvedArea: function(
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* object? */kwArgs,
/* function? */applyTo
){
// summary
// Plots a set of stacked areas, using a tensioning factor to soften points.
// Bindings: x/y
var tension = 3;
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
// precompile the data
var n = plot.series.length; // how many series
var data = [];
var totals = [];
// we're assuming that all series for this plot has the name x assignment for now.
for(var i=0; i<n; i++){
var tmp = plot.series[i].data.evaluate(kwArgs);
// run through and add current totals
for(var j=0; j<tmp.length; j++){
if(i==0){ totals.push(tmp[j].y); }
else { totals[j] += tmp[j].y; }
tmp[j].y = totals[j];
}
data.push(tmp);
}
for(var i=n-1; i>=0; i--){
var path = document.createElementNS(dojo.svg.xmlns.svg, "path");
path.setAttribute("fill", data[i][0].series.color);
path.setAttribute("fill-opacity", "0.4");
path.setAttribute("stroke", data[i][0].series.color);
path.setAttribute("stroke-width" , "1");
path.setAttribute("stroke-opacity", "0.85");
var cmd = [];
var r=3;
for(var j=0; j<data[i].length; j++){
var values = data[i];
var x = plot.axisX.getCoord(values[j].x, plotarea, plot);
var y = plot.axisY.getCoord(values[j].y, plotarea, plot);
var dx = area.left + 1;
var dy = area.bottom;
if(j>0){
dx = x - plot.axisX.getCoord(values[j-1].x, plotarea, plot);
dy = plot.axisY.getCoord(values[j-1].y, plotarea, plot);
}
if(j==0){ cmd.push("M"); }
else {
cmd.push("C");
var cx = x-(tension-1) * (dx/tension);
cmd.push(cx + "," + dy);
cx = x - (dx/tension);
cmd.push(cx + "," + y);
}
cmd.push(x+","+y);
// points on the line
var c=document.createElementNS(dojo.svg.xmlns.svg, "circle");
c.setAttribute("cx",x);
c.setAttribute("cy",y);
c.setAttribute("r","3");
c.setAttribute("fill", values[j].series.color);
c.setAttribute("fill-opacity", "0.6");
c.setAttribute("stroke-width", "1");
c.setAttribute("stroke-opacity", "0.85");
group.appendChild(c);
if(applyTo){ applyTo(c, data[i].src); }
}
// now run the path backwards from the previous series.
if(i == 0){
cmd.push("L");
cmd.push(x + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("L");
cmd.push(plot.axisX.getCoord(data[0][0].x, plotarea, plot) + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("Z");
} else {
var values = data[i-1];
cmd.push("L");
cmd.push(x + "," + Math.round(plot.axisY.getCoord(values[values.length-1].y, plotarea, plot)));
for(var j=values.length-2; j>=0; j--){
var x = plot.axisX.getCoord(values[j].x, plotarea, plot);
var y = plot.axisY.getCoord(values[j].y, plotarea, plot);
var dx = x - plot.axisX.getCoord(values[j+1].x, plotarea, plot);
var dy = plot.axisY.getCoord(values[j+1].y, plotarea, plot);
cmd.push("C");
var cx = x-(tension-1) * (dx/tension);
cmd.push(cx + "," + dy);
cx = x - (dx/tension);
cmd.push(cx + "," + y);
cmd.push(x+","+y);
}
}
path.setAttribute("d", cmd.join(" ")+ " Z");
group.appendChild(path);
}
return group; // SVGGElement
},
/*********************************************************
* Single plotters: one series at a time.
*********************************************************/
DataBar: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots a set of bars in relation to y==0.
// Bindings: x/y
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
var n = data.length;
var w = (area.right-area.left)/(plot.axisX.range.upper - plot.axisX.range.lower); // the width of each group.
var yOrigin = plot.axisY.getCoord(plot.axisX.origin, plotarea, plot);
for(var i=0; i<n; i++){
// calculate offset
var value = data[i].y;
var yA = yOrigin;
var x = plot.axisX.getCoord(data[i].x, plotarea, plot) - (w/2);
var y = plot.axisY.getCoord(value, plotarea, plot);
var h = Math.abs(yA-y);
if(value < plot.axisX.origin){
yA = y;
y = yOrigin;
}
var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
bar.setAttribute("fill", data[i].series.color);
bar.setAttribute("stroke-width", "0");
bar.setAttribute("x", x);
bar.setAttribute("y", y);
bar.setAttribute("width", w);
bar.setAttribute("height", h);
bar.setAttribute("fill-opacity", "0.6");
if(applyTo){ applyTo(bar, data[i].src); }
group.appendChild(bar);
}
return group; // SVGGElement
},
Line: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as a line.
// Bindings: x/y
var area = plotarea.getArea();
var line = document.createElementNS(dojo.svg.xmlns.svg, "g");
var path = document.createElementNS(dojo.svg.xmlns.svg, "path");
line.appendChild(path);
path.setAttribute("fill", "none");
path.setAttribute("stroke", data[0].series.color);
path.setAttribute("stroke-width" , "2");
path.setAttribute("stroke-opacity", "0.85");
if(data[0].series.label != null){
path.setAttribute("title", data[0].series.label);
}
var cmd=[];
for(var i=0; i<data.length; i++){
var x = plot.axisX.getCoord(data[i].x, plotarea, plot);
var y = plot.axisY.getCoord(data[i].y, plotarea, plot);
if(i==0){ cmd.push("M"); }
else { cmd.push("L"); }
cmd.push(x+","+y);
// points on the line
var c=document.createElementNS(dojo.svg.xmlns.svg, "circle");
c.setAttribute("cx",x);
c.setAttribute("cy",y);
c.setAttribute("r","3");
c.setAttribute("fill", data[i].series.color);
c.setAttribute("fill-opacity", "0.6");
c.setAttribute("stroke-width", "1");
c.setAttribute("stroke-opacity", "0.85");
line.appendChild(c);
if(applyTo){ applyTo(c, data[i].src); }
}
path.setAttribute("d", cmd.join(" "));
return line; // SVGGElement
},
CurvedLine: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as a line with a tension factor for softening.
// Bindings: x/y
var tension = 3;
var area = plotarea.getArea();
var line = document.createElementNS(dojo.svg.xmlns.svg, "g");
var path = document.createElementNS(dojo.svg.xmlns.svg, "path");
line.appendChild(path);
path.setAttribute("fill", "none");
path.setAttribute("stroke", data[0].series.color);
path.setAttribute("stroke-width" , "2");
path.setAttribute("stroke-opacity", "0.85");
if(data[0].series.label != null){
path.setAttribute("title", data[0].series.label);
}
var cmd=[];
for(var i=0; i<data.length; i++){
var x = plot.axisX.getCoord(data[i].x, plotarea, plot);
var y = plot.axisY.getCoord(data[i].y, plotarea, plot);
var dx = area.left + 1;
var dy = area.bottom;
if(i>0){
dx = x - plot.axisX.getCoord(data[i-1].x, plotarea, plot);
dy = plot.axisY.getCoord(data[i-1].y, plotarea, plot);
}
if(i==0){ cmd.push("M"); }
else {
cmd.push("C");
var cx = x-(tension-1) * (dx/tension);
cmd.push(cx + "," + dy);
cx = x - (dx/tension);
cmd.push(cx + "," + y);
}
cmd.push(x+","+y);
// points on the line
var c=document.createElementNS(dojo.svg.xmlns.svg, "circle");
c.setAttribute("cx",x);
c.setAttribute("cy",y);
c.setAttribute("r","3");
c.setAttribute("fill", data[i].series.color);
c.setAttribute("fill-opacity", "0.6");
c.setAttribute("stroke-width", "1");
c.setAttribute("stroke-opacity", "0.85");
line.appendChild(c);
if(applyTo){ applyTo(c, data[i].src); }
}
path.setAttribute("d", cmd.join(" "));
return line; // SVGGElement
},
Area: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as an area.
// Bindings: x/y
var area = plotarea.getArea();
var line = document.createElementNS(dojo.svg.xmlns.svg, "g");
var path = document.createElementNS(dojo.svg.xmlns.svg, "path");
line.appendChild(path);
path.setAttribute("fill", data[0].series.color);
path.setAttribute("fill-opacity", "0.4");
path.setAttribute("stroke", data[0].series.color);
path.setAttribute("stroke-width" , "1");
path.setAttribute("stroke-opacity", "0.85");
if(data[0].series.label != null){
path.setAttribute("title", data[0].series.label);
}
var cmd=[];
for(var i=0; i<data.length; i++){
var x = plot.axisX.getCoord(data[i].x, plotarea, plot);
var y = plot.axisY.getCoord(data[i].y, plotarea, plot);
if(i==0){ cmd.push("M"); }
else { cmd.push("L"); }
cmd.push(x+","+y);
// points on the line
var c=document.createElementNS(dojo.svg.xmlns.svg, "circle");
c.setAttribute("cx",x);
c.setAttribute("cy",y);
c.setAttribute("r","3");
c.setAttribute("fill", data[i].series.color);
c.setAttribute("fill-opacity", "0.6");
c.setAttribute("stroke-width", "1");
c.setAttribute("stroke-opacity", "0.85");
line.appendChild(c);
if(applyTo){ applyTo(c, data[i].src); }
}
// finish it off
cmd.push("L");
cmd.push(x + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("L");
cmd.push(plot.axisX.getCoord(data[0].x, plotarea, plot) + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("Z");
path.setAttribute("d", cmd.join(" "));
return line; // SVGGElement
},
CurvedArea: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as an area with a tension for softening.
// Bindings: x/y
var tension = 3;
var area = plotarea.getArea();
var line = document.createElementNS(dojo.svg.xmlns.svg, "g");
var path = document.createElementNS(dojo.svg.xmlns.svg, "path");
line.appendChild(path);
path.setAttribute("fill", data[0].series.color);
path.setAttribute("fill-opacity", "0.4");
path.setAttribute("stroke", data[0].series.color);
path.setAttribute("stroke-width" , "1");
path.setAttribute("stroke-opacity", "0.85");
if(data[0].series.label != null){
path.setAttribute("title", data[0].series.label);
}
var cmd=[];
for(var i=0; i<data.length; i++){
var x = plot.axisX.getCoord(data[i].x, plotarea, plot);
var y = plot.axisY.getCoord(data[i].y, plotarea, plot);
var dx = area.left + 1;
var dy = area.bottom;
if(i>0){
dx = x - plot.axisX.getCoord(data[i-1].x, plotarea, plot);
dy = plot.axisY.getCoord(data[i-1].y, plotarea, plot);
}
if(i==0){ cmd.push("M"); }
else {
cmd.push("C");
var cx = x-(tension-1) * (dx/tension);
cmd.push(cx + "," + dy);
cx = x - (dx/tension);
cmd.push(cx + "," + y);
}
cmd.push(x+","+y);
// points on the line
var c=document.createElementNS(dojo.svg.xmlns.svg, "circle");
c.setAttribute("cx",x);
c.setAttribute("cy",y);
c.setAttribute("r","3");
c.setAttribute("fill", data[i].series.color);
c.setAttribute("fill-opacity", "0.6");
c.setAttribute("stroke-width", "1");
c.setAttribute("stroke-opacity", "0.85");
line.appendChild(c);
if(applyTo){ applyTo(c, data[i].src); }
}
// finish it off
cmd.push("L");
cmd.push(x + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("L");
cmd.push(plot.axisX.getCoord(data[0].x, plotarea, plot) + "," + plot.axisY.getCoord(plot.axisX.origin, plotarea, plot));
cmd.push("Z");
path.setAttribute("d", cmd.join(" "));
return line; // SVGGElement
},
HighLow: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as a set of high/low bars.
// Bindings: x/high/low
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
var n = data.length;
var part = ((area.right-area.left)/(plot.axisX.range.upper - plot.axisX.range.lower))/4;
var w = part*2;
for(var i=0; i<n; i++){
var high = data[i].high;
var low = data[i].low;
if(low > high){
var t = low;
low = high;
high = t;
}
var x = plot.axisX.getCoord(data[i].x, plotarea, plot) - (w/2);
var y = plot.axisY.getCoord(high, plotarea, plot);
var h = plot.axisY.getCoord(low, plotarea, plot)-y;
// high + low
var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
bar.setAttribute("fill", data[i].series.color);
bar.setAttribute("stroke-width", "0");
bar.setAttribute("x", x);
bar.setAttribute("y", y);
bar.setAttribute("width", w);
bar.setAttribute("height", h);
bar.setAttribute("fill-opacity", "0.6");
if(applyTo){ applyTo(bar, data[i].src); }
group.appendChild(bar);
}
return group; // SVGGElement
},
HighLowClose: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as a set of high/low bars with a close indicator.
// Bindings: x/high/low/close
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
var n = data.length;
var part = ((area.right-area.left)/(plot.axisX.range.upper - plot.axisX.range.lower))/4;
var w = part*2;
for(var i=0; i<n; i++){
var high = data[i].high;
var low = data[i].low;
if(low > high){
var t = low;
low = high;
high = t;
}
var c = data[i].close;
var x = plot.axisX.getCoord(data[i].x, plotarea, plot) - (w/2);
var y = plot.axisY.getCoord(high, plotarea, plot);
var h = plot.axisY.getCoord(low, plotarea, plot)-y;
var close = plot.axisY.getCoord(c, plotarea, plot);
var g = document.createElementNS(dojo.svg.xmlns.svg, "g");
// high + low
var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
bar.setAttribute("fill", data[i].series.color);
bar.setAttribute("stroke-width", "0");
bar.setAttribute("x", x);
bar.setAttribute("y", y);
bar.setAttribute("width", w);
bar.setAttribute("height", h);
bar.setAttribute("fill-opacity", "0.6");
g.appendChild(bar);
// close
var line=document.createElementNS(dojo.svg.xmlns.svg, "line");
line.setAttribute("x1", x);
line.setAttribute("x2", x+w+(part*2));
line.setAttribute("y1", close);
line.setAttribute("y2", close);
line.setAttribute("style", "stroke:"+data[i].series.color+";stroke-width:1px;stroke-opacity:0.6;");
g.appendChild(line);
if(applyTo){ applyTo(g, data[i].src); }
group.appendChild(g);
}
return group; // SVGGElement
},
HighLowOpenClose: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as a set of high/low bars with open and close indicators.
// Bindings: x/high/low/open/close
var area = plotarea.getArea();
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
var n = data.length;
var part = ((area.right-area.left)/(plot.axisX.range.upper - plot.axisX.range.lower))/4;
var w = part*2;
for(var i=0; i<n; i++){
var high = data[i].high;
var low = data[i].low;
if(low > high){
var t = low;
low = high;
high = t;
}
var o = data[i].open;
var c = data[i].close;
var x = plot.axisX.getCoord(data[i].x, plotarea, plot) - (w/2);
var y = plot.axisY.getCoord(high, plotarea, plot);
var h = plot.axisY.getCoord(low, plotarea, plot)-y;
var open = plot.axisY.getCoord(o, plotarea, plot);
var close = plot.axisY.getCoord(c, plotarea, plot);
var g = document.createElementNS(dojo.svg.xmlns.svg, "g");
// high + low
var bar=document.createElementNS(dojo.svg.xmlns.svg, "rect");
bar.setAttribute("fill", data[i].series.color);
bar.setAttribute("stroke-width", "0");
bar.setAttribute("x", x);
bar.setAttribute("y", y);
bar.setAttribute("width", w);
bar.setAttribute("height", h);
bar.setAttribute("fill-opacity", "0.6");
g.appendChild(bar);
// open
var line=document.createElementNS(dojo.svg.xmlns.svg, "line");
line.setAttribute("x1", x-(part*2));
line.setAttribute("x2", x+w);
line.setAttribute("y1", open);
line.setAttribute("y2", open);
line.setAttribute("style", "stroke:"+data[i].series.color+";stroke-width:1px;stroke-opacity:0.6;");
g.appendChild(line);
// close
var line=document.createElementNS(dojo.svg.xmlns.svg, "line");
line.setAttribute("x1", x);
line.setAttribute("x2", x+w+(part*2));
line.setAttribute("y1", close);
line.setAttribute("y2", close);
line.setAttribute("style", "stroke:"+data[i].series.color+";stroke-width:1px;stroke-opacity:0.6;");
g.appendChild(line);
if(applyTo){ applyTo(g, data[i].src); }
group.appendChild(g);
}
return group; // SVGGElement
},
Scatter: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as a set of points.
// Bindings: x/y
var r=7;
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
for (var i=0; i<data.length; i++){
var x = plot.axisX.getCoord(data[i].x, plotarea, plot);
var y = plot.axisY.getCoord(data[i].y, plotarea, plot);
var point = document.createElementNS(dojo.svg.xmlns.svg, "path");
point.setAttribute("fill", data[i].series.color);
point.setAttribute("stroke-width", "0");
point.setAttribute("d",
"M " + x + "," + (y-r) + " " +
"Q " + x + "," + y + " " + (x+r) + "," + y + " " +
"Q " + x + "," + y + " " + x + "," + (y+r) + " " +
"Q " + x + "," + y + " " + (x-r) + "," + y + " " +
"Q " + x + "," + y + " " + x + "," + (y-r) + " " +
"Z"
);
if(applyTo){ applyTo(point, data[i].src); }
group.appendChild(point);
}
return group; // SVGGElement
},
Bubble: function(
/* array */data,
/* dojo.charting.PlotArea */plotarea,
/* dojo.charting.Plot */plot,
/* function? */applyTo
){
// summary
// Plots the series as a set of points with a size factor.
// Bindings: x/y/size
var group = document.createElementNS(dojo.svg.xmlns.svg, "g");
var sizeFactor=1;
for (var i=0; i<data.length; i++){
var x = plot.axisX.getCoord(data[i].x, plotarea, plot);
var y = plot.axisY.getCoord(data[i].y, plotarea, plot);
if(i==0){
// figure out the size factor, start with the axis with the greater range.
var raw = data[i].size;
var dy = plot.axisY.getCoord(data[i].y + raw, plotarea, plot)-y;
sizeFactor = dy/raw;
}
if(sizeFactor<1) { sizeFactor = 1; }
var point = document.createElementNS(dojo.svg.xmlns.svg, "circle");
point.setAttribute("fill", data[i].series.color);
point.setAttribute("fill-opacity", "0.8");
point.setAttribute("stroke", data[i].series.color);
point.setAttribute("stroke-width", "1");
point.setAttribute("cx",x);
point.setAttribute("cy",y);
point.setAttribute("r", (data[i].size/2)*sizeFactor);
if(applyTo){ applyTo(point, data[i].src); }
group.appendChild(point);
}
return group; // SVGGElement
}
});
dojo.charting.Plotters["Default"] = dojo.charting.Plotters.Line;
@@ -0,0 +1,270 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.vml.Axis");
dojo.require("dojo.lang.common");
dojo.extend(dojo.charting.Axis, {
renderLines: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* string */plane
){
// summary
// Renders any reference lines for this axis.
if(this.nodes.lines){
while(this.nodes.lines.childNodes.length > 0){
this.nodes.lines.removeChild(this.nodes.lines.childNodes[0]);
}
if(this.nodes.lines.parentNode){
this.nodes.lines.parentNode.removeChild(this.nodes.lines);
this.nodes.lines = null;
}
}
var area = plotArea.getArea();
var g = this.nodes.lines = document.createElement("div");
g.setAttribute("id", this.getId()+"-lines");
for(var i=0; i<this._labels.length; i++){
if (this._labels[i].value == this.origin){ continue; }
var v = this.getCoord(this._labels[i].value, plotArea, plot);
var l=document.createElement("v:line");
var str=document.createElement("v:stroke");
str.dashstyle="dot";
l.appendChild(str);
l.setAttribute("strokecolor", "#666");
l.setAttribute("strokeweight", "1px");
var s=l.style;
s.position="absolute";
s.top="0px";
s.left="0px";
s.antialias="false";
if(plane == "x"){
l.setAttribute("from", v+"px,"+area.top+"px");
l.setAttribute("to", v+"px,"+area.bottom+"px");
}
else if (plane == "y"){
l.setAttribute("from", area.left+"px,"+v+"px");
l.setAttribute("to", area.right+"px,"+v+"px");
}
g.appendChild(l);
}
return g; // HTMLDivElement
},
renderTicks: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* string */plane,
/* float */coord
){
// summary
// Renders any tick lines for this axis.
if(this.nodes.ticks){
while(this.nodes.ticks.childNodes.length > 0){
this.nodes.ticks.removeChild(this.nodes.ticks.childNodes[0]);
}
if(this.nodes.ticks.parentNode){
this.nodes.ticks.parentNode.removeChild(this.nodes.ticks);
this.nodes.ticks = null;
}
}
var g = this.nodes.ticks = document.createElement("div");
g.setAttribute("id", this.getId()+"-ticks");
for(var i=0; i<this._labels.length; i++){
var v = this.getCoord(this._labels[i].value, plotArea, plot);
var l=document.createElement("v:line");
l.setAttribute("strokecolor", "#000");
l.setAttribute("strokeweight", "1px");
var s=l.style;
s.position="absolute";
s.top="0px";
s.left="0px";
s.antialias="false";
if(plane == "x"){
l.setAttribute("from", v+"px,"+coord+"px");
l.setAttribute("to", v+"px,"+(coord+3)+"px");
}
else if (plane == "y"){
l.setAttribute("from", (coord-2)+"px,"+v+"px");
l.setAttribute("to", (coord+2)+"px,"+v+"px");
}
g.appendChild(l);
}
return g; // HTMLDivElement
},
renderLabels: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* string */plane,
/* float */coord,
/* int */textSize,
/* string */anchor
){
// summary
// Render all labels for this axis.
function createLabel(label, x, y, textSize, anchor){
var text = document.createElement("div");
var s=text.style;
text.innerHTML=label;
s.fontSize=textSize+"px";
s.fontFamily="sans-serif";
s.position="absolute";
s.top = y+"px";
if(anchor == "center"){
s.left = x + "px";
s.textAlign="center";
} else if (anchor == "left"){
s.left = x + "px";
s.textAlign="left";
} else if (anchor == "right"){
s.right = x + "px";
s.textAlign="right";
}
return text;
};
// wipe if needed
if(this.nodes.labels){
while(this.nodes.labels.childNodes.length > 0){
this.nodes.labels.removeChild(this.nodes.labels.childNodes[0]);
}
if(this.nodes.labels.parentNode){
this.nodes.labels.parentNode.removeChild(this.nodes.labels);
this.nodes.labels = null;
}
}
var g = this.nodes.labels = document.createElement("div");
g.setAttribute("id", this.getId()+"-labels");
for(var i=0; i<this._labels.length; i++){
var v = this.getCoord(this._labels[i].value, plotArea, plot);
if(plane == "x"){
// ugly hack but it works.
var node=createLabel(this._labels[i].label, v, coord, textSize, anchor);
document.body.appendChild(node);
node.style.left = v-(node.offsetWidth/2)+"px";
g.appendChild(node);
}
else if (plane == "y"){
var node = createLabel(this._labels[i].label, coord, v, textSize, anchor);
document.body.appendChild(node);
node.style.top = v-(node.offsetHeight/2)+"px";
g.appendChild(node);
}
}
return g; // HTMLDivElement
},
render: function(
/* dojo.charting.PlotArea */plotArea,
/* dojo.charting.Plot */plot,
/* dojo.charting.Axis */drawAgainst,
/* string */plane
){
// summary
// Renders this axis to the given plot.
// get the origin plot point.
var area = plotArea.getArea();
var stroke = 1;
var style = "stroke:#000;stroke-width:"+stroke+"px;";
var textSize=10;
var coord = drawAgainst.getCoord(this.origin, plotArea, plot);
// draw the axis.
var g = this.nodes.main = document.createElement("div");
g.setAttribute("id", this.getId()); // need a handle if we have to kill parts of the axis def.
var line = this.nodes.axis = document.createElement("v:line");
line.setAttribute("strokecolor", "#000");
line.setAttribute("strokeweight", stroke+"px");
var s=line.style;
s.position="absolute";
s.top="0px";
s.left="0px";
s.antialias="false";
if(plane == "x"){
line.setAttribute("from", area.left+"px,"+coord+"px");
line.setAttribute("to", area.right+"px,"+coord+"px");
// set up the labels
var y = coord + Math.floor(textSize/2);
if(this.showLines){
g.appendChild(this.renderLines(plotArea, plot, plane, y));
}
if(this.showTicks){
g.appendChild(this.renderTicks(plotArea, plot, plane, coord));
}
if(this.showLabels){
g.appendChild(this.renderLabels(plotArea, plot, plane, y, textSize, "center"));
}
if(this.showLabel && this.label){
var x = plotArea.size.width/2;
var y = coord + Math.round(textSize*1.5);
var text = document.createElement("div");
var s=text.style;
text.innerHTML=this.label;
s.fontSize=(textSize+2)+"px";
s.fontFamily="sans-serif";
s.fontWeight="bold";
s.position="absolute";
s.top = y+"px";
s.left = x + "px";
s.textAlign="center";
document.body.appendChild(text);
text.style.left = x-(text.offsetWidth/2)+"px";
g.appendChild(text);
}
} else {
line.setAttribute("from", coord+"px,"+area.top+"px");
line.setAttribute("to", coord+"px,"+area.bottom+"px");
// set up the labels
var isMax = this.origin == drawAgainst.range.upper;
var x = coord+4;
var anchor = "left";
if(!isMax){
x = area.right-coord+textSize+4;
anchor = "right";
if(coord == area.left){ x += (textSize*2)-(textSize/2); }
}
if(this.showLines){
g.appendChild(this.renderLines(plotArea, plot, plane, x));
}
if(this.showTicks){
g.appendChild(this.renderTicks(plotArea, plot, plane, coord));
}
if(this.showLabels){
g.appendChild(this.renderLabels(plotArea, plot, plane, x, textSize, anchor));
}
if(this.showLabel && this.label){
x += (textSize*2)-2;
var y = plotArea.size.height/2;
var text = document.createElement("div");
var s=text.style;
text.innerHTML=this.label;
s.fontSize=(textSize+2)+"px";
s.fontFamily="sans-serif";
s.fontWeight="bold";
s.position="absolute";
s.height = plotArea.size.height+"px";
s.writingMode = "tb-rl";
s.textAlign="center";
s[anchor] = x+"px";
document.body.appendChild(text);
s.top = y-(text.offsetHeight/2)+"px";
g.appendChild(text);
}
}
g.appendChild(line);
return g; // HTMLDivElement
}
});
@@ -0,0 +1,78 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.charting.vml.PlotArea");
dojo.require("dojo.lang.common");
dojo.extend(dojo.charting.PlotArea, {
initializePlot: function(plot){
// summary
// Initialize the plot node for data rendering.
plot.destroy();
plot.dataNode = document.createElement("div");
plot.dataNode.id = plot.getId();
return plot.dataNode; // HTMLDivElement
},
initialize:function(){
// summary
// Initialize the PlotArea.
this.destroy(); // kill everything first.
var main = this.nodes.main = document.createElement("div");
// start with the background
var area = this.nodes.area = document.createElement("div");
area.id = this.getId();
area.style.width=this.size.width+"px";
area.style.height=this.size.height+"px";
area.style.position="absolute";
main.appendChild(area);
var bg = this.nodes.background = document.createElement("div");
bg.id = this.getId()+"-background";
bg.style.width=this.size.width+"px";
bg.style.height=this.size.height+"px";
bg.style.position="absolute";
bg.style.top="0px";
bg.style.left="0px";
bg.style.backgroundColor="#fff";
area.appendChild(bg);
// the plot group
var a=this.getArea();
var plots = this.nodes.plots = document.createElement("div");
plots.id = this.getId()+"-plots";
plots.style.width=this.size.width+"px";
plots.style.height=this.size.height+"px";
plots.style.position="absolute";
plots.style.top="0px";
plots.style.left="0px";
plots.style.clip="rect("
+ a.top+" "
+ a.right+" "
+ a.bottom+" "
+ a.left
+")";
area.appendChild(plots);
for(var i=0; i<this.plots.length; i++){
plots.appendChild(this.initializePlot(this.plots[i]));
}
var axes = this.nodes.axes = document.createElement("div");
axes.id = this.getId() + "-axes";
area.appendChild(axes);
var ax = this.getAxes();
for(var p in ax){
var obj = ax[p];
axes.appendChild(obj.axis.initialize(this, obj.plot, obj.drawAgainst, obj.plane));
}
return main; // HTMLDivElement
}
});
@@ -0,0 +1,146 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.ArrayList");
dojo.require("dojo.collections.Collections");
dojo.collections.ArrayList=function(/* array? */arr){
// summary
// Returns a new object of type dojo.collections.ArrayList
var items=[];
if(arr) items=items.concat(arr);
this.count=items.length;
this.add=function(/* object */obj){
// summary
// Add an element to the collection.
items.push(obj);
this.count=items.length;
};
this.addRange=function(/* array */a){
// summary
// Add a range of objects to the ArrayList
if(a.getIterator){
var e=a.getIterator();
while(!e.atEnd()){
this.add(e.get());
}
this.count=items.length;
}else{
for(var i=0; i<a.length; i++){
items.push(a[i]);
}
this.count=items.length;
}
};
this.clear=function(){
// summary
// Clear all elements out of the collection, and reset the count.
items.splice(0, items.length);
this.count=0;
};
this.clone=function(){
// summary
// Clone the array list
return new dojo.collections.ArrayList(items); // dojo.collections.ArrayList
};
this.contains=function(/* object */obj){
// summary
// Check to see if the passed object is a member in the ArrayList
for(var i=0; i < items.length; i++){
if(items[i] == obj) {
return true; // bool
}
}
return false; // bool
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(items, fn, s);
}else{
for(var i=0; i<items.length; i++){
fn.call(s, items[i], i, items);
}
}
};
this.getIterator=function(){
// summary
// Get an Iterator for this object
return new dojo.collections.Iterator(items); // dojo.collections.Iterator
};
this.indexOf=function(/* object */obj){
// summary
// Return the numeric index of the passed object; will return -1 if not found.
for(var i=0; i < items.length; i++){
if(items[i] == obj) {
return i; // int
}
}
return -1; // int
};
this.insert=function(/* int */ i, /* object */ obj){
// summary
// Insert the passed object at index i
items.splice(i,0,obj);
this.count=items.length;
};
this.item=function(/* int */ i){
// summary
// return the element at index i
return items[i]; // object
};
this.remove=function(/* object */obj){
// summary
// Look for the passed object, and if found, remove it from the internal array.
var i=this.indexOf(obj);
if(i >=0) {
items.splice(i,1);
}
this.count=items.length;
};
this.removeAt=function(/* int */ i){
// summary
// return an array with function applied to all elements
items.splice(i,1);
this.count=items.length;
};
this.reverse=function(){
// summary
// Reverse the internal array
items.reverse();
};
this.sort=function(/* function? */ fn){
// summary
// sort the internal array
if(fn){
items.sort(fn);
}else{
items.sort();
}
};
this.setByIndex=function(/* int */ i, /* object */ obj){
// summary
// Set an element in the array by the passed index.
items[i]=obj;
this.count=items.length;
};
this.toArray=function(){
// summary
// Return a new array with all of the items of the internal array concatenated.
return [].concat(items);
}
this.toString=function(/* string */ delim){
// summary
// implementation of toString, follows [].toString();
return items.join((delim||","));
};
};
@@ -0,0 +1,203 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.BinaryTree");
dojo.require("dojo.collections.Collections");
dojo.require("dojo.experimental");
dojo.experimental("dojo.collections.BinaryTree");
dojo.collections.BinaryTree=function(data){
function node(data, rnode, lnode){
this.value=data||null;
this.right=rnode||null;
this.left=lnode||null;
this.clone=function(){
var c=new node();
if (this.value.value) c.value=this.value.clone();
else c.value=this.value;
if (this.left) c.left=this.left.clone();
if (this.right) c.right=this.right.clone();
}
this.compare=function(n){
if (this.value > n.value) return 1;
if (this.value < n.value) return -1;
return 0;
}
this.compareData=function(d){
if (this.value > d) return 1;
if (this.value < d) return -1;
return 0;
}
}
function inorderTraversalBuildup(current, a){
if (current){
inorderTraversalBuildup(current.left, a);
a.add(current);
inorderTraversalBuildup(current.right, a);
}
}
function preorderTraversal(current, sep){
var s="";
if (current){
s=current.value.toString() + sep;
s += preorderTraversal(current.left, sep);
s += preorderTraversal(current.right, sep);
}
return s;
}
function inorderTraversal(current, sep){
var s="";
if (current){
s=inorderTraversal(current.left, sep);
s += current.value.toString() + sep;
s += inorderTraversal(current.right, sep);
}
return s;
}
function postorderTraversal(current, sep){
var s="";
if (current){
s=postorderTraversal(current.left, sep);
s += postorderTraversal(current.right, sep);
s += current.value.toString() + sep;
}
return s;
}
function searchHelper(current, data){
if (!current) return null;
var i=current.compareData(data);
if (i==0) return current;
if (i>0) return searchHelper(current.left, data);
else return searchHelper(current.right, data);
}
this.add=function(data){
var n=new node(data);
var i;
var current=root;
var parent=null;
while (current){
i=current.compare(n);
if (i == 0) return;
parent=current;
if (i > 0) current=current.left;
else current=current.right;
}
this.count++;
if (!parent) root=n;
else {
i=parent.compare(n);
if (i > 0) parent.left=n;
else parent.right=n;
}
};
this.clear=function(){
root=null;
this.count=0;
};
this.clone=function(){
var c=new dojo.collections.BinaryTree();
c.root=root.clone();
c.count=this.count;
return c;
};
this.contains=function(data){
return this.search(data) != null;
};
this.deleteData=function(data){
var current=root;
var parent=null;
var i=current.compareData(data);
while (i != 0 && current != null){
if (i > 0){
parent=current;
current=current.left;
} else if (i < 0) {
parent=current;
current=current.right;
}
i=current.compareData(data);
}
if (!current) return;
this.count--;
if (!current.right) {
if (!parent) root=current.left;
else {
i=parent.compare(current);
if (i > 0) parent.left=current.left;
else if (i < 0) parent.right=current.left;
}
} else if (!current.right.left){
if (!parent) root=current.right;
else {
i=parent.compare(current);
if (i > 0) parent.left=current.right;
else if (i < 0) parent.right=current.right;
}
} else {
var leftmost=current.right.left;
var lmParent=current.right;
while (leftmost.left != null){
lmParent=leftmost;
leftmost=leftmost.left;
}
lmParent.left=leftmost.right;
leftmost.left=current.left;
leftmost.right=current.right;
if (!parent) root=leftmost;
else {
i=parent.compare(current);
if (i > 0) parent.left=leftmost;
else if (i < 0) parent.right=leftmost;
}
}
};
this.getIterator=function(){
var a=[];
inorderTraversalBuildup(root, a);
return new dojo.collections.Iterator(a);
};
this.search=function(data){
return searchHelper(root, data);
};
this.toString=function(order, sep){
if (!order) var order=dojo.collections.BinaryTree.TraversalMethods.Inorder;
if (!sep) var sep=" ";
var s="";
switch (order){
case dojo.collections.BinaryTree.TraversalMethods.Preorder:
s=preorderTraversal(root, sep);
break;
case dojo.collections.BinaryTree.TraversalMethods.Inorder:
s=inorderTraversal(root, sep);
break;
case dojo.collections.BinaryTree.TraversalMethods.Postorder:
s=postorderTraversal(root, sep);
break;
};
if (s.length == 0) return "";
else return s.substring(0, s.length - sep.length);
};
this.count=0;
var root=this.root=null;
if (data) {
this.add(data);
}
}
dojo.collections.BinaryTree.TraversalMethods={
Preorder : 1,
Inorder : 2,
Postorder : 3
};
@@ -0,0 +1,124 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Collections");
dojo.collections.DictionaryEntry=function(/* string */k, /* object */v){
// summary
// return an object of type dojo.collections.DictionaryEntry
this.key=k;
this.value=v;
this.valueOf=function(){
return this.value; // object
};
this.toString=function(){
return String(this.value); // string
};
}
/* Iterators
* The collections.Iterators (Iterator and DictionaryIterator) are built to
* work with the Collections included in this module. However, they *can*
* be used with arrays and objects, respectively, should one choose to do so.
*/
dojo.collections.Iterator=function(/* array */arr){
// summary
// return an object of type dojo.collections.Iterator
var a=arr;
var position=0;
this.element=a[position]||null;
this.atEnd=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
return (position>=a.length); // bool
};
this.get=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
if(this.atEnd()){
return null; // object
}
this.element=a[position++];
return this.element; // object
};
this.map=function(/* function */fn, /* object? */scope){
// summary
// Functional iteration with optional scope.
var s=scope||dj_global;
if(Array.map){
return Array.map(a,fn,s); // array
}else{
var arr=[];
for(var i=0; i<a.length; i++){
arr.push(fn.call(s,a[i]));
}
return arr; // array
}
};
this.reset=function(){
// summary
// reset the internal cursor.
position=0;
this.element=a[position];
};
}
/* Notes:
* The DictionaryIterator no longer supports a key and value property;
* the reality is that you can use this to iterate over a JS object
* being used as a hashtable.
*/
dojo.collections.DictionaryIterator=function(/* object */obj){
// summary
// return an object of type dojo.collections.DictionaryIterator
var a=[]; // Create an indexing array
var testObject={};
for(var p in obj){
if(!testObject[p]){
a.push(obj[p]); // fill it up
}
}
var position=0;
this.element=a[position]||null;
this.atEnd=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
return (position>=a.length); // bool
};
this.get=function(){
// summary
// Test to see if the internal cursor has reached the end of the internal collection.
if(this.atEnd()){
return null; // object
}
this.element=a[position++];
return this.element; // object
};
this.map=function(/* function */fn, /* object? */scope){
// summary
// Functional iteration with optional scope.
var s=scope||dj_global;
if(Array.map){
return Array.map(a,fn,s); // array
}else{
var arr=[];
for(var i=0; i<a.length; i++){
arr.push(fn.call(s,a[i]));
}
return arr; // array
}
};
this.reset=function() {
// summary
// reset the internal cursor.
position=0;
this.element=a[position];
};
};
@@ -0,0 +1,129 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Dictionary");
dojo.require("dojo.collections.Collections");
dojo.collections.Dictionary=function(/* dojo.collections.Dictionary? */dictionary){
// summary
// Returns an object of type dojo.collections.Dictionary
var items={};
this.count=0;
// comparator for property addition and access.
var testObject={};
this.add=function(/* string */k, /* object */v){
// summary
// Add a new item to the Dictionary.
var b=(k in items);
items[k]=new dojo.collections.DictionaryEntry(k,v);
if(!b){
this.count++;
}
};
this.clear=function(){
// summary
// Clears the internal dictionary.
items={};
this.count=0;
};
this.clone=function(){
// summary
// Returns a new instance of dojo.collections.Dictionary; note the the dictionary is a clone but items might not be.
return new dojo.collections.Dictionary(this); // dojo.collections.Dictionary
};
this.contains=this.containsKey=function(/* string */k){
// summary
// Check to see if the dictionary has an entry at key "k".
if(testObject[k]){
return false; // bool
}
return (items[k]!=null); // bool
};
this.containsValue=function(/* object */v){
// summary
// Check to see if the dictionary has an entry with value "v".
var e=this.getIterator();
while(e.get()){
if(e.element.value==v){
return true; // bool
}
}
return false; // bool
};
this.entry=function(/* string */k){
// summary
// Accessor method; similar to dojo.collections.Dictionary.item but returns the actual Entry object.
return items[k]; // dojo.collections.DictionaryEntry
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var a=[]; // Create an indexing array
for(var p in items) {
if(!testObject[p]){
a.push(items[p]); // fill it up
}
}
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(a, fn, s);
}else{
for(var i=0; i<a.length; i++){
fn.call(s, a[i], i, a);
}
}
};
this.getKeyList=function(){
// summary
// Returns an array of the keys in the dictionary.
return (this.getIterator()).map(function(entry){
return entry.key;
}); // array
};
this.getValueList=function(){
// summary
// Returns an array of the values in the dictionary.
return (this.getIterator()).map(function(entry){
return entry.value;
}); // array
};
this.item=function(/* string */k){
// summary
// Accessor method.
if(k in items){
return items[k].valueOf(); // object
}
return undefined; // object
};
this.getIterator=function(){
// summary
// Gets a dojo.collections.DictionaryIterator for iteration purposes.
return new dojo.collections.DictionaryIterator(items); // dojo.collections.DictionaryIterator
};
this.remove=function(/* string */k){
// summary
// Removes the item at k from the internal collection.
if(k in items && !testObject[k]){
delete items[k];
this.count--;
return true; // bool
}
return false; // bool
};
if (dictionary){
var e=dictionary.getIterator();
while(e.get()) {
this.add(e.element.key, e.element.value);
}
}
};
@@ -0,0 +1,153 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Graph");
dojo.require("dojo.collections.Collections");
dojo.experimental("dojo.collections.Graph");
dojo.collections.Graph=function(nodes){
function node(key, data, neighbors) {
this.key=key;
this.data=data;
this.neighbors=neighbors||new adjacencyList();
this.addDirected=function(){
if (arguments[0].constructor==edgeToNeighbor){
this.neighbors.add(arguments[0]);
}else{
var n=arguments[0];
var cost=arguments[1]||0;
this.neighbors.add(new edgeToNeighbor(n, cost));
}
}
}
function nodeList(){
var d=new dojo.collections.Dictionary();
function nodelistiterator(){
var o=[] ; // Create an indexing array
var e=d.getIterator();
while(e.get()){
o[o.length]=e.element;
}
var position=0;
this.element=o[position]||null;
this.atEnd=function(){
return (position>=o.length);
}
this.get=function(){
if(this.atEnd()){
return null; // object
}
this.element=o[position++];
return this.element; // object
};
this.map=function(/* function */fn, /* object? */scope){
var s=scope||dj_global;
if(Array.map){
return Array.map(o,fn,s); // array
}else{
var arr=[];
for(var i=0; i<o.length; i++){
arr.push(fn.call(s,o[i]));
}
return arr; // array
}
};
this.reset=function(){
position=0;
this.element=o[position];
};
}
this.add=function(node){
d.add(node.key, node);
};
this.clear=function(){
d.clear();
};
this.containsKey=function(key){
return d.containsKey(key);
};
this.getIterator=function(){
return new nodelistiterator(this);
};
this.item=function(key){
return d.item(key);
};
this.remove=function(node){
d.remove(node.key);
};
}
function edgeToNeighbor(node, cost){
this.neighbor=node;
this.cost=cost;
}
function adjacencyList(){
var d=[];
this.add=function(o){
d.push(o);
};
this.item=function(i){
return d[i];
};
this.getIterator=function(){
return new dojo.collections.Iterator([].concat(d));
};
}
this.nodes=nodes||new nodeList();
this.count=this.nodes.count;
this.clear=function(){
this.nodes.clear();
this.count=0;
};
this.addNode=function(){
var n=arguments[0];
if(arguments.length > 1){
n=new node(arguments[0],arguments[1]);
}
if(!this.nodes.containsKey(n.key)){
this.nodes.add(n);
this.count++;
}
};
this.addDirectedEdge=function(uKey, vKey, cost){
var uNode,vNode;
if(uKey.constructor!= node){
uNode=this.nodes.item(uKey);
vNode=this.nodes.item(vKey);
}else{
uNode=uKey;
vNode=vKey;
}
var c=cost||0;
uNode.addDirected(vNode,c);
};
this.addUndirectedEdge=function(uKey, vKey, cost){
var uNode, vNode;
if(uKey.constructor!=node){
uNode=this.nodes.item(uKey);
vNode=this.nodes.item(vKey);
}else{
uNode=uKey;
vNode=vKey;
}
var c=cost||0;
uNode.addDirected(vNode,c);
vNode.addDirected(uNode,c);
};
this.contains=function(n){
return this.nodes.containsKey(n.key);
};
this.containsKey=function(k){
return this.nodes.containsKey(k);
};
}
@@ -0,0 +1,87 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Queue");
dojo.require("dojo.collections.Collections");
dojo.collections.Queue=function(/* array? */arr){
// summary
// return an object of type dojo.collections.Queue
var q=[];
if (arr){
q=q.concat(arr);
}
this.count=q.length;
this.clear=function(){
// summary
// clears the internal collection
q=[];
this.count=q.length;
};
this.clone=function(){
// summary
// creates a new Queue based on this one
return new dojo.collections.Queue(q); // dojo.collections.Queue
};
this.contains=function(/* object */ o){
// summary
// Check to see if the passed object is an element in this queue
for(var i=0; i<q.length; i++){
if (q[i]==o){
return true; // bool
}
}
return false; // bool
};
this.copyTo=function(/* array */ arr, /* int */ i){
// summary
// Copy the contents of this queue into the passed array at index i.
arr.splice(i,0,q);
};
this.dequeue=function(){
// summary
// shift the first element off the queue and return it
var r=q.shift();
this.count=q.length;
return r; // object
};
this.enqueue=function(/* object */ o){
// summary
// put the passed object at the end of the queue
this.count=q.push(o);
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(q, fn, s);
}else{
for(var i=0; i<q.length; i++){
fn.call(s, q[i], i, q);
}
}
};
this.getIterator=function(){
// summary
// get an Iterator based on this queue.
return new dojo.collections.Iterator(q); // dojo.collections.Iterator
};
this.peek=function(){
// summary
// get the next element in the queue without altering the queue.
return q[0];
};
this.toArray=function(){
// summary
// return an array based on the internal array of the queue.
return [].concat(q);
};
};
@@ -0,0 +1,94 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Set");
dojo.require("dojo.collections.Collections");
dojo.require("dojo.collections.ArrayList");
dojo.collections.Set = new function(){
// summary
// Singleton for dealing with common set operations.
this.union = function(/* array */setA, /* array */setB){
// summary
// Return the union of the two passed sets.
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var result = new dojo.collections.ArrayList(setA.toArray());
var e = setB.getIterator();
while(!e.atEnd()){
var item=e.get();
if(!result.contains(item)){
result.add(item);
}
}
return result; // dojo.collections.ArrayList
};
this.intersection = function(/* array */setA, /* array */setB){
// summary
// Return the intersection of the two passed sets.
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var result = new dojo.collections.ArrayList();
var e = setB.getIterator();
while(!e.atEnd()){
var item=e.get();
if(setA.contains(item)){
result.add(item);
}
}
return result; // dojo.collections.ArrayList
};
this.difference = function(/* array */setA, /* array */setB){
// summary
// Returns everything in setA that is not in setB.
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var result = new dojo.collections.ArrayList();
var e=setA.getIterator();
while(!e.atEnd()){
var item=e.get();
if(!setB.contains(item)){
result.add(item);
}
}
return result; // dojo.collections.ArrayList
};
this.isSubSet = function(/* array */setA, /* array */setB) {
// summary
// Returns if set B is a subset of set A.
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var e = setA.getIterator();
while(!e.atEnd()){
if(!setB.contains(e.get())){
return false; // boolean
}
}
return true; // boolean
};
this.isSuperSet = function(/* array */setA, /* array */setB){
// summary
// Returns if set B is a superset of set A.
if (setA.constructor == Array) var setA = new dojo.collections.ArrayList(setA);
if (setB.constructor == Array) var setB = new dojo.collections.ArrayList(setB);
if (!setA.toArray || !setB.toArray) dojo.raise("Set operations can only be performed on array-based collections.");
var e = setB.getIterator();
while(!e.atEnd()){
if(!setA.contains(e.get())){
return false; // boolean
}
}
return true; // boolean
};
}();
@@ -0,0 +1,149 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.SkipList");
dojo.require("dojo.collections.Collections");
dojo.require("dojo.experimental");
dojo.experimental("dojo.collections.SkipList");
dojo.collections.SkipList = function(){
function node(height, val){
this.value = val;
this.height = height;
this.nodes = new nodeList(height);
this.compare = function(val){
if (this.value > val) return 1;
if (this.value < val) return -1;
return 0;
}
this.incrementHeight = function(){
this.nodes.incrementHeight();
this.height++;
};
this.decrementHeight = function(){
this.nodes.decrementHeight();
this.height--;
};
}
function nodeList(height){
var arr = [];
this.height = height;
for (var i = 0; i < height; i++) arr[i] = null;
this.item = function(i){
return arr[i];
};
this.incrementHeight = function(){
this.height++;
arr[this.height] = null;
};
this.decrementHeight = function(){
arr.splice(arr.length - 1, 1);
this.height--;
};
}
function iterator(list){
this.element = list.head;
this.atEnd = function(){
return (this.element==null);
}
this.get = function(){
if(this.atEnd()){
return null;
}
this.element=this.element.nodes[0];
return this.element;
}
this.reset = function(){
this.element = list.head;
}
}
function chooseRandomHeight(max){
var level = 1;
while (Math.random() < PROB && level < max) level++;
return level;
}
var PROB = 0.5;
var comparisons = 0;
this.head = new node(1);
this.count = 0;
this.add = function(val){
var updates = [];
var current = this.head;
for (var i = this.head.height; i >= 0; i--){
if (!(current.nodes[i] != null && current.nodes[i].compare(val) < 0)) comparisons++;
while (current.nodes[i] != null && current.nodes[i].compare(val) < 0){
current = current.nodes[i];
comparisons++;
}
updates[i] = current;
}
if (current.nodes[0] != null && current.nodes[0].compare(val) == 0) return;
var n = new node(val, chooseRandomHeight(this.head.height + 1));
this.count++;
if (n.height > this.head.height){
this.head.incrementHeight();
this.head.nodes[this.head.height - 1] = n;
}
for (i = 0; i < n.height; i++){
if (i < updates.length) {
n.nodes[i] = updates[i].nodes[i];
updates[i].nodes[i] = n;
}
}
};
this.contains = function(val){
var current = this.head;
var i;
for (i = this.head.height - 1; i >= 0; i--) {
while (current.item(i) != null) {
comparisons++;
var result = current.nodes[i].compare(val);
if (result == 0) return true;
else if (result < 0) current = current.nodes[i];
else break;
}
}
return false;
};
this.getIterator = function(){
return new iterator(this);
};
this.remove = function(val){
var updates = [];
var current = this.head;
for (var i = this.head.height - 1; i >= 0; i--){
if (!(current.nodes[i] != null && current.nodes[i].compare(val) < 0)) comparisons++;
while (current.nodes[i] != null && current.nodes[i].compare(val) < 0) {
current = current.nodes[i];
comparisons++;
}
updates[i] = current;
}
current = current.nodes[0];
if (current != null && current.compare(val) == 0){
this.count--;
for (var i = 0; i < this.head.height; i++){
if (updates[i].nodes[i] != current) break;
else updates[i].nodes[i] = current.nodes[i];
}
if (this.head.nodes[this.head.height - 1] == null) this.head.decrementHeight();
}
};
this.resetComparisons = function(){
comparisons = 0;
};
}
@@ -0,0 +1,211 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.SortedList");
dojo.require("dojo.collections.Collections");
dojo.collections.SortedList=function(/* object? */ dictionary){
// summary
// creates a collection that acts like a dictionary but is also internally sorted.
// Note that the act of adding any elements forces an internal resort, making this object potentially slow.
var _this=this;
var items={};
var q=[];
var sorter=function(a,b){
if (a.key > b.key) return 1;
if (a.key < b.key) return -1;
return 0;
};
var build=function(){
q=[];
var e=_this.getIterator();
while (!e.atEnd()){
q.push(e.get());
}
q.sort(sorter);
};
var testObject={};
this.count=q.length;
this.add=function(/* string */ k,/* object */v){
// summary
// add the passed value to the dictionary at location k
if (!items[k]) {
items[k]=new dojo.collections.DictionaryEntry(k,v);
this.count=q.push(items[k]);
q.sort(sorter);
}
};
this.clear=function(){
// summary
// clear the internal collections
items={};
q=[];
this.count=q.length;
};
this.clone=function(){
// summary
// create a clone of this sorted list
return new dojo.collections.SortedList(this); // dojo.collections.SortedList
};
this.contains=this.containsKey=function(/* string */ k){
// summary
// Check to see if the list has a location k
if(testObject[k]){
return false; // bool
}
return (items[k]!=null); // bool
};
this.containsValue=function(/* object */ o){
// summary
// Check to see if this list contains the passed object
var e=this.getIterator();
while (!e.atEnd()){
var item=e.get();
if(item.value==o){
return true; // bool
}
}
return false; // bool
};
this.copyTo=function(/* array */ arr, /* int */ i){
// summary
// copy the contents of the list into array arr at index i
var e=this.getIterator();
var idx=i;
while(!e.atEnd()){
arr.splice(idx,0,e.get());
idx++;
}
};
this.entry=function(/* string */ k){
// summary
// return the object at location k
return items[k]; // dojo.collections.DictionaryEntry
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(q, fn, s);
}else{
for(var i=0; i<q.length; i++){
fn.call(s, q[i], i, q);
}
}
};
this.getByIndex=function(/* int */ i){
// summary
// return the item at index i
return q[i].valueOf(); // object
};
this.getIterator=function(){
// summary
// get an iterator for this object
return new dojo.collections.DictionaryIterator(items); // dojo.collections.DictionaryIterator
};
this.getKey=function(/* int */ i){
// summary
// return the key of the item at index i
return q[i].key;
};
this.getKeyList=function(){
// summary
// return an array of the keys set in this list
var arr=[];
var e=this.getIterator();
while (!e.atEnd()){
arr.push(e.get().key);
}
return arr; // array
};
this.getValueList=function(){
// summary
// return an array of values in this list
var arr=[];
var e=this.getIterator();
while (!e.atEnd()){
arr.push(e.get().value);
}
return arr; // array
};
this.indexOfKey=function(/* string */ k){
// summary
// return the index of the passed key.
for (var i=0; i<q.length; i++){
if (q[i].key==k){
return i; // int
}
}
return -1; // int
};
this.indexOfValue=function(/* object */ o){
// summary
// return the first index of object o
for (var i=0; i<q.length; i++){
if (q[i].value==o){
return i; // int
}
}
return -1; // int
};
this.item=function(/* string */ k){
// summary
// return the value of the object at location k.
if(k in items && !testObject[k]){
return items[k].valueOf(); // object
}
return undefined; // object
};
this.remove=function(/* string */k){
// summary
// remove the item at location k and rebuild the internal collections.
delete items[k];
build();
this.count=q.length;
};
this.removeAt=function(/* int */ i){
// summary
// remove the item at index i, and rebuild the internal collections.
delete items[q[i].key];
build();
this.count=q.length;
};
this.replace=function(/* string */ k, /* object */ v){
// summary
// Replace an existing item if it's there, and add a new one if not.
if (!items[k]){
// we're adding a new object, return false
this.add(k,v);
return false; // bool
}else{
// we're replacing an object, return true
items[k]=new dojo.collections.DictionaryEntry(k,v);
q.sort(sorter);
return true; // bool
}
};
this.setByIndex=function(/* int */ i, /* object */ o){
// summary
// set an item by index
items[q[i].key].value=o;
build();
this.count=q.length;
};
if (dictionary){
var e=dictionary.getIterator();
while (!e.atEnd()){
var item=e.get();
q[q.length]=items[item.key]=new dojo.collections.DictionaryEntry(item.key,item.value);
}
q.sort(sorter);
}
}
@@ -0,0 +1,85 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Stack");
dojo.require("dojo.collections.Collections");
dojo.collections.Stack=function(/* array? */arr){
// summary
// returns an object of type dojo.collections.Stack
var q=[];
if (arr) q=q.concat(arr);
this.count=q.length;
this.clear=function(){
// summary
// Clear the internal array and reset the count
q=[];
this.count=q.length;
};
this.clone=function(){
// summary
// Create and return a clone of this Stack
return new dojo.collections.Stack(q);
};
this.contains=function(/* object */o){
// summary
// check to see if the stack contains object o
for (var i=0; i<q.length; i++){
if (q[i] == o){
return true; // bool
}
}
return false; // bool
};
this.copyTo=function(/* array */ arr, /* int */ i){
// summary
// copy the stack into array arr at index i
arr.splice(i,0,q);
};
this.forEach=function(/* function */ fn, /* object? */ scope){
// summary
// functional iterator, following the mozilla spec.
var s=scope||dj_global;
if(Array.forEach){
Array.forEach(q, fn, s);
}else{
for(var i=0; i<q.length; i++){
fn.call(s, q[i], i, q);
}
}
};
this.getIterator=function(){
// summary
// get an iterator for this collection
return new dojo.collections.Iterator(q); // dojo.collections.Iterator
};
this.peek=function(){
// summary
// Return the next item without altering the stack itself.
return q[(q.length-1)]; // object
};
this.pop=function(){
// summary
// pop and return the next item on the stack
var r=q.pop();
this.count=q.length;
return r; // object
};
this.push=function(/* object */ o){
// summary
// Push object o onto the stack
this.count=q.push(o);
};
this.toArray=function(){
// summary
// create and return an array based on the internal collection
return [].concat(q); // array
};
}
@@ -0,0 +1,279 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.collections.Store");
dojo.require("dojo.lang.common");
/* Store
* Designed to be a simple store of data with access methods...
* specifically to be mixed into other objects (such as widgets).
*/
dojo.collections.Store = function(/* array? */jsonArray){
// summary
// Data Store with accessor methods.
var data = [];
this.keyField = "Id";
this.get = function(){
// summary
// Get the internal data array, should not be used.
return data; // array
};
this.getByKey = function(/* string */key){
// summary
// Find the internal data object by key.
for(var i=0; i<data.length; i++){
if(data[i].key==key){
return data[i]; // object
}
}
return null; // null
};
this.getByIndex = function(/*number*/idx){
// summary
// Get the internal data object by index.
return data[idx]; // object
};
this.getData = function(){
// summary
// Get an array of source objects.
var arr = [];
for(var i=0; i<data.length; i++){
arr.push(data[i].src);
}
return arr; // array
};
this.getDataByKey = function(/*string*/key){
// summary
// Get the source object by key.
for(var i=0; i<data.length; i++){
if(data[i].key==key){
return data[i].src; // object
}
}
return null; // null
};
this.getDataByIndex = function(/*number*/idx){
// summary
// Get the source object at index idx.
return data[idx].src; // object
};
this.update = function(/* Object */obj, /* string */fieldPath, /* Object */val){
var parts=fieldPath.split("."), i=0, o=obj, field;
if(parts.length>1) {
field = parts.pop();
do{
if(parts[i].indexOf("()")>-1){
var temp=parts[i++].split("()")[0];
if(!o[temp]){
dojo.raise("dojo.collections.Store.getField(obj, '" + field + "'): '" + temp + "' is not a property of the passed object.");
} else {
// this *will* throw an error if the method in question can't be invoked without arguments.
o = o[temp]();
}
} else {
o = o[parts[i++]];
}
} while (i<parts.length && o != null);
} else {
field = parts[0];
}
obj[field] = val;
this.onUpdateField(obj, fieldPath, val);
};
this.forEach = function(/* function */fn){
// summary
// Functional iteration directly on the internal data array.
if(Array.forEach){
Array.forEach(data, fn, this);
}else{
for(var i=0; i<data.length; i++){
fn.call(this, data[i]);
}
}
};
this.forEachData = function(/* function */fn){
// summary
// Functional iteration on source objects in internal data array.
if(Array.forEach){
Array.forEach(this.getData(), fn, this);
}else{
var a=this.getData();
for(var i=0; i<a.length; i++){
fn.call(this, a[i]);
}
}
};
this.setData = function(/*array*/arr){
// summary
// Set up the internal data.
data = []; // don't fire onClearData
for(var i=0; i<arr.length; i++){
data.push({
key:arr[i][this.keyField],
src:arr[i]
});
}
this.onSetData();
};
this.clearData = function(){
// summary
// Clears the internal data array.
data = [];
this.onClearData();
};
this.addData = function(/*obj*/obj,/*string?*/key){
// summary
// Add an object with optional key to the internal data array.
var k = key || obj[this.keyField];
if(this.getByKey(k)){
var o = this.getByKey(k);
o.src = obj;
} else {
var o={ key:k, src:obj };
data.push(o);
}
this.onAddData(o);
};
this.addDataRange = function(/*array*/arr){
// summary
// Add a range of objects to the internal data array.
var objects=[];
for(var i=0; i<arr.length; i++){
var k = arr[i][this.keyField];
if(this.getByKey(k)){
var o = this.getByKey(k);
o.src = obj;
} else {
var o = { key:k, src:arr[i] };
data.push(o);
}
objects.push(o);
}
this.onAddDataRange(objects);
};
this.removeData = function(/*obj*/obj){
// summary
// remove the passed object from the internal data array.
var idx=-1;
var o=null;
for(var i=0; i<data.length; i++){
if(data[i].src==obj){
idx=i;
o=data[i];
break;
}
}
this.onRemoveData(o);
if(idx>-1){
data.splice(idx,1);
}
};
this.removeDataByKey = function(/*string*/key){
// summary
// remove the object at key from the internal data array.
this.removeData(this.getDataByKey(key));
};
this.removeDataByIndex = function(/*number*/idx){
// summary
// remove the object at idx from the internal data array.
this.removeData(this.getDataByIndex(idx));
};
if(jsonArray && jsonArray.length && jsonArray[0]){
this.setData(jsonArray);
}
};
dojo.extend(dojo.collections.Store, {
getField:function(/*object*/obj, /*string*/field){
// helper to get the nested value if needed.
var parts=field.split("."), i=0, o=obj;
do{
if(parts[i].indexOf("()")>-1){
var temp=parts[i++].split("()")[0];
if(!o[temp]){
dojo.raise("dojo.collections.Store.getField(obj, '" + field + "'): '" + temp + "' is not a property of the passed object.");
} else {
// this *will* throw an error if the method in question can't be invoked without arguments.
o = o[temp]();
}
} else {
o = o[parts[i++]];
}
} while (i<parts.length && o != null);
if(i < parts.length){
dojo.raise("dojo.collections.Store.getField(obj, '" + field + "'): '" + field + "' is not a property of the passed object.");
}
return o; // object
},
getFromHtml:function(/* array */meta, /* HTMLTableBody */body, /* function? */fnMod){
// summary
// Parse HTML data into native JSON structure for the store.
var rows = body.rows;
// create a data constructor.
var ctor=function(row){
var obj = {};
for(var i=0; i<meta.length; i++){
var o = obj;
var data = row.cells[i].innerHTML;
var p = meta[i].getField();
if(p.indexOf(".") > -1){
p = p.split(".");
while(p.length>1){
var pr = p.shift();
o[pr] = {};
o = o[pr];
}
p = p[0];
}
var type = meta[i].getType();
if(type == String){
o[p] = data;
} else {
if(data){
o[p] = new type(data);
} else {
o[p] = new type();
}
}
}
return obj;
};
// we have initialization data, let's parse it.
var arr=[];
for(var i=0; i<rows.length; i++){
var o = ctor(rows[i]);
if(fnMod){
fnMod(o, rows[i]); // apply any modifiers.
}
arr.push(o);
}
return arr; // array
},
onSetData:function(){ },
onClearData:function(){ },
onAddData:function(obj){ },
onAddDataRange:function(arr){ },
onRemoveData:function(obj){ },
onUpdateField:function(obj, field, val){ }
});
@@ -0,0 +1,22 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: [
"dojo.collections.Collections",
"dojo.collections.SortedList",
"dojo.collections.Dictionary",
"dojo.collections.Queue",
"dojo.collections.ArrayList",
"dojo.collections.Stack",
"dojo.collections.Set"
]
});
dojo.provide("dojo.collections.*");
@@ -0,0 +1,31 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.crypto");
dojo.crypto.cipherModes={
// summary
// Enumeration for various cipher modes.
ECB:0,
CBC:1,
PCBC:2,
CFB:3,
OFB:4,
CTR:5
};
dojo.crypto.outputTypes={
// summary
// Enumeration for input and output encodings.
Base64:0,
Hex:1,
String:2,
Raw:3
};
@@ -0,0 +1,576 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.require("dojo.crypto");
dojo.provide("dojo.crypto.Blowfish");
/* Blowfish
* Created based on the C# implementation by Marcus Hahn (http://www.hotpixel.net/)
* Unsigned math functions derived from Joe Gregorio's SecureSyndication GM script
* http://bitworking.org/projects/securesyndication/
* (Note that this is *not* an adaption of the above script)
*
* version 1.0
* TRT
* 2005-12-08
*/
dojo.crypto.Blowfish = new function(){
// summary
// Object for doing Blowfish encryption/decryption.
var POW2=Math.pow(2,2);
var POW3=Math.pow(2,3);
var POW4=Math.pow(2,4);
var POW8=Math.pow(2,8);
var POW16=Math.pow(2,16);
var POW24=Math.pow(2,24);
var iv=null; // CBC mode initialization vector
var boxes={
p:[
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
],
s0:[
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
],
s1:[
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
],
s2:[
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
],
s3:[
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
]
}
////////////////////////////////////////////////////////////////////////////
function add(x,y){
var sum=(x+y)&0xffffffff;
if (sum<0){
sum=-sum;
return (0x10000*((sum>>16)^0xffff))+(((sum&0xffff)^0xffff)+1);
}
return sum;
}
function split(x){
var r=x&0xffffffff;
if(r<0) {
r=-r;
return [((r&0xffff)^0xffff)+1,(r>>16)^0xffff];
}
return [r&0xffff,(r>>16)];
}
function xor(x,y){
var xs=split(x);
var ys=split(y);
return (0x10000*(xs[1]^ys[1]))+(xs[0]^ys[0]);
}
function $(v, box){
var d=v&0xff; v>>=8;
var c=v&0xff; v>>=8;
var b=v&0xff; v>>=8;
var a=v&0xff;
var r=add(box.s0[a],box.s1[b]);
r=xor(r,box.s2[c]);
return add(r,box.s3[d]);
}
////////////////////////////////////////////////////////////////////////////
function eb(o, box){
var l=o.left;
var r=o.right;
l=xor(l,box.p[0]);
r=xor(r,xor($(l,box),box.p[1]));
l=xor(l,xor($(r,box),box.p[2]));
r=xor(r,xor($(l,box),box.p[3]));
l=xor(l,xor($(r,box),box.p[4]));
r=xor(r,xor($(l,box),box.p[5]));
l=xor(l,xor($(r,box),box.p[6]));
r=xor(r,xor($(l,box),box.p[7]));
l=xor(l,xor($(r,box),box.p[8]));
r=xor(r,xor($(l,box),box.p[9]));
l=xor(l,xor($(r,box),box.p[10]));
r=xor(r,xor($(l,box),box.p[11]));
l=xor(l,xor($(r,box),box.p[12]));
r=xor(r,xor($(l,box),box.p[13]));
l=xor(l,xor($(r,box),box.p[14]));
r=xor(r,xor($(l,box),box.p[15]));
l=xor(l,xor($(r,box),box.p[16]));
o.right=l;
o.left=xor(r,box.p[17]);
}
function db(o, box){
var l=o.left;
var r=o.right;
l=xor(l,box.p[17]);
r=xor(r,xor($(l,box),box.p[16]));
l=xor(l,xor($(r,box),box.p[15]));
r=xor(r,xor($(l,box),box.p[14]));
l=xor(l,xor($(r,box),box.p[13]));
r=xor(r,xor($(l,box),box.p[12]));
l=xor(l,xor($(r,box),box.p[11]));
r=xor(r,xor($(l,box),box.p[10]));
l=xor(l,xor($(r,box),box.p[9]));
r=xor(r,xor($(l,box),box.p[8]));
l=xor(l,xor($(r,box),box.p[7]));
r=xor(r,xor($(l,box),box.p[6]));
l=xor(l,xor($(r,box),box.p[5]));
r=xor(r,xor($(l,box),box.p[4]));
l=xor(l,xor($(r,box),box.p[3]));
r=xor(r,xor($(l,box),box.p[2]));
l=xor(l,xor($(r,box),box.p[1]));
o.right=l;
o.left=xor(r,box.p[0]);
}
// Note that we aren't caching contexts here; it might take a little longer
// but we should be more secure this way.
function init(key){
var k=key;
if (typeof(k)=="string"){
var a=[];
for(var i=0; i<k.length; i++)
a.push(k.charCodeAt(i)&0xff);
k=a;
}
// init the boxes
var box = { p:[], s0:[], s1:[], s2:[], s3:[] };
for(var i=0; i<boxes.p.length; i++) box.p.push(boxes.p[i]);
for(var i=0; i<boxes.s0.length; i++) box.s0.push(boxes.s0[i]);
for(var i=0; i<boxes.s1.length; i++) box.s1.push(boxes.s1[i]);
for(var i=0; i<boxes.s2.length; i++) box.s2.push(boxes.s2[i]);
for(var i=0; i<boxes.s3.length; i++) box.s3.push(boxes.s3[i]);
// init p with the key
var pos=0;
var data=0;
for(var i=0; i < box.p.length; i++){
for (var j=0; j<4; j++){
data = (data*POW8) | k[pos];
if(++pos==k.length) pos=0;
}
box.p[i] = xor(box.p[i], data);
}
// encrypt p and the s boxes
var res={ left:0, right:0 };
for(var i=0; i<box.p.length;){
eb(res, box);
box.p[i++]=res.left;
box.p[i++]=res.right;
}
for (var i=0; i<4; i++){
for(var j=0; j<box["s"+i].length;){
eb(res, box);
box["s"+i][j++]=res.left;
box["s"+i][j++]=res.right;
}
}
return box;
}
////////////////////////////////////////////////////////////////////////////
// CONVERSION FUNCTIONS
////////////////////////////////////////////////////////////////////////////
// these operate on byte arrays, NOT word arrays.
function toBase64(ba){
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var s=[];
var l=ba.length;
var rm=l%3;
var x=l-rm;
for (var i=0; i<x;){
var t=ba[i++]<<16|ba[i++]<<8|ba[i++];
s.push(tab.charAt((t>>>18)&0x3f));
s.push(tab.charAt((t>>>12)&0x3f));
s.push(tab.charAt((t>>>6)&0x3f));
s.push(tab.charAt(t&0x3f));
}
// deal with trailers, based on patch from Peter Wood.
switch(rm){
case 2:{
var t=ba[i++]<<16|ba[i++]<<8;
s.push(tab.charAt((t>>>18)&0x3f));
s.push(tab.charAt((t>>>12)&0x3f));
s.push(tab.charAt((t>>>6)&0x3f));
s.push(p);
break;
}
case 1:{
var t=ba[i++]<<16;
s.push(tab.charAt((t>>>18)&0x3f));
s.push(tab.charAt((t>>>12)&0x3f));
s.push(p);
s.push(p);
break;
}
}
return s.join("");
}
function fromBase64(str){
var s=str.split("");
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var out=[];
var l=s.length;
while(s[--l]==p){ }
for (var i=0; i<l;){
var t=tab.indexOf(s[i++])<<18|tab.indexOf(s[i++])<<12|tab.indexOf(s[i++])<<6|tab.indexOf(s[i++]);
out.push((t>>>16)&0xff);
out.push((t>>>8)&0xff);
out.push(t&0xff);
}
return out;
}
////////////////////////////////////////////////////////////////////////////
// PUBLIC FUNCTIONS
// 0.2: Only supporting ECB mode for now.
////////////////////////////////////////////////////////////////////////////
this.getIV=function(/* dojo.crypto.outputTypes? */ outputType){
// summary
// returns the initialization vector in the output format specified by outputType
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
var s=[];
for(var i=0; i<iv.length; i++)
s.push((iv[i]).toString(16));
return s.join(""); // string
}
case dojo.crypto.outputTypes.String:{
return iv.join(""); // string
}
case dojo.crypto.outputTypes.Raw:{
return iv; // array
}
default:{
return toBase64(iv); // string
}
}
};
this.setIV=function(/* string */data, /* dojo.crypto.outputTypes? */inputType){
// summary
// sets the initialization vector to data (as interpreted as inputType)
var ip=inputType||dojo.crypto.outputTypes.Base64;
var ba=null;
switch(ip){
case dojo.crypto.outputTypes.String:{
ba=[];
for (var i=0; i<data.length; i++){
ba.push(data.charCodeAt(i));
}
break;
}
case dojo.crypto.outputTypes.Hex:{
ba=[];
var i=0;
while (i+1<data.length){
ba.push(parseInt(data.substr(i,2),16));
i+=2;
}
break;
}
case dojo.crypto.outputTypes.Raw:{
ba=data;
break;
}
default:{
ba=fromBase64(data);
break;
}
}
// make it a pair of words now
iv={};
iv.left=ba[0]*POW24|ba[1]*POW16|ba[2]*POW8|ba[3];
iv.right=ba[4]*POW24|ba[5]*POW16|ba[6]*POW8|ba[7];
}
this.encrypt = function(/* string */plaintext, /* string */key, /* object? */ao){
// summary
// encrypts plaintext using key; allows user to specify output type and cipher mode via keyword object "ao"
var out=dojo.crypto.outputTypes.Base64;
var mode=dojo.crypto.cipherModes.EBC;
if (ao){
if (ao.outputType) out=ao.outputType;
if (ao.cipherMode) mode=ao.cipherMode;
}
var bx = init(key);
var padding = 8-(plaintext.length&7);
for (var i=0; i<padding; i++) plaintext+=String.fromCharCode(padding);
var cipher=[];
var count=plaintext.length >> 3;
var pos=0;
var o={};
var isCBC=(mode==dojo.crypto.cipherModes.CBC);
var vector={left:iv.left||null, right:iv.right||null};
for(var i=0; i<count; i++){
o.left=plaintext.charCodeAt(pos)*POW24
|plaintext.charCodeAt(pos+1)*POW16
|plaintext.charCodeAt(pos+2)*POW8
|plaintext.charCodeAt(pos+3);
o.right=plaintext.charCodeAt(pos+4)*POW24
|plaintext.charCodeAt(pos+5)*POW16
|plaintext.charCodeAt(pos+6)*POW8
|plaintext.charCodeAt(pos+7);
if(isCBC){
o.left=xor(o.left, vector.left);
o.right=xor(o.right, vector.right);
}
eb(o, bx); // encrypt the block
if(isCBC){
vector.left=o.left;
vector.right=o.right;dojo.crypto.outputTypes.Hex
}
cipher.push((o.left>>24)&0xff);
cipher.push((o.left>>16)&0xff);
cipher.push((o.left>>8)&0xff);
cipher.push(o.left&0xff);
cipher.push((o.right>>24)&0xff);
cipher.push((o.right>>16)&0xff);
cipher.push((o.right>>8)&0xff);
cipher.push(o.right&0xff);
pos+=8;
}
switch(out){
case dojo.crypto.outputTypes.Hex:{
var s=[];
for(var i=0; i<cipher.length; i++)
s.push((cipher[i]).toString(16));
return s.join(""); // string
}
case dojo.crypto.outputTypes.String:{
return cipher.join(""); // string
}
case dojo.crypto.outputTypes.Raw:{
return cipher; // array
}
default:{
return toBase64(cipher); // string
}
}
};
this.decrypt = function(/* string */ciphertext, /* string */key, /* object? */ao){
// summary
// decrypts ciphertext using key; allows specification of how ciphertext is encoded via ao.
var ip=dojo.crypto.outputTypes.Base64;
var mode=dojo.crypto.cipherModes.EBC;
if (ao){
if (ao.outputType) ip=ao.outputType;
if (ao.cipherMode) mode=ao.cipherMode;
}
var bx = init(key);
var pt=[];
var c=null;
switch(ip){
case dojo.crypto.outputTypes.Hex:{
c=[];
var i=0;
while (i+1<ciphertext.length){
c.push(parseInt(ciphertext.substr(i,2),16));
i+=2;
}
break;
}
case dojo.crypto.outputTypes.String:{
c=[];
for (var i=0; i<ciphertext.length; i++){
c.push(ciphertext.charCodeAt(i));
}
break;
}
case dojo.crypto.outputTypes.Raw:{
c=ciphertext; // should be a byte array
break;
}
default:{
c=fromBase64(ciphertext);
break;
}
}
var count=c.length >> 3;
var pos=0;
var o={};
var isCBC=(mode==dojo.crypto.cipherModes.CBC);
var vector={left:iv.left||null, right:iv.right||null};
for(var i=0; i<count; i++){
o.left=c[pos]*POW24|c[pos+1]*POW16|c[pos+2]*POW8|c[pos+3];
o.right=c[pos+4]*POW24|c[pos+5]*POW16|c[pos+6]*POW8|c[pos+7];
if(isCBC){
var left=o.left;
var right=o.right;
}
db(o, bx); // decrypt the block
if(isCBC){
o.left=xor(o.left, vector.left);
o.right=xor(o.right, vector.right);
vector.left=left;
vector.right=right;
}
pt.push((o.left>>24)&0xff);
pt.push((o.left>>16)&0xff);
pt.push((o.left>>8)&0xff);
pt.push(o.left&0xff);
pt.push((o.right>>24)&0xff);
pt.push((o.right>>16)&0xff);
pt.push((o.right>>8)&0xff);
pt.push(o.right&0xff);
pos+=8;
}
// check for padding, and remove.
if(pt[pt.length-1]==pt[pt.length-2]||pt[pt.length-1]==0x01){
var n=pt[pt.length-1];
pt.splice(pt.length-n, n);
}
// convert to string
for(var i=0; i<pt.length; i++)
pt[i]=String.fromCharCode(pt[i]);
return pt.join(""); // string
};
this.setIV("0000000000000000", dojo.crypto.outputTypes.Hex);
}();
@@ -0,0 +1,11 @@
License Disclaimer:
All contents of this directory are Copyright (c) the Dojo Foundation, with the
following exceptions:
-------------------------------------------------------------------------------
MD5.js, SHA1.js:
* Copyright 1998-2005, Paul Johnstone
Distributed under the terms of the BSD License
@@ -0,0 +1,199 @@
dojo.require("dojo.crypto");
dojo.provide("dojo.crypto.MD5");
/* Return to a port of Paul Johnstone's MD5 implementation
* http://pajhome.org.uk/crypt/md5/index.html
*
* Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
*
* Dojo port by Tom Trenka
*
* 2005-12-7
* All conversions are internalized (no dependencies)
* implemented getHMAC for message digest auth.
*/
dojo.crypto.MD5 = new function(){
// summary
// object for creating digests using the MD5 algorithm
var chrsz=8;
var mask=(1<<chrsz)-1;
function toWord(s) {
var wa=[];
for(var i=0; i<s.length*chrsz; i+=chrsz)
wa[i>>5]|=(s.charCodeAt(i/chrsz)&mask)<<(i%32);
return wa;
}
function toString(wa){
var s=[];
for(var i=0; i<wa.length*32; i+=chrsz)
s.push(String.fromCharCode((wa[i>>5]>>>(i%32))&mask));
return s.join("");
}
function toHex(wa) {
var h="0123456789abcdef";
var s=[];
for(var i=0; i<wa.length*4; i++){
s.push(h.charAt((wa[i>>2]>>((i%4)*8+4))&0xF)+h.charAt((wa[i>>2]>>((i%4)*8))&0xF));
}
return s.join("");
}
function toBase64(wa){
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var s=[];
for(var i=0; i<wa.length*4; i+=3){
var t=(((wa[i>>2]>>8*(i%4))&0xFF)<<16)|(((wa[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((wa[i+2>>2]>>8*((i+2)%4))&0xFF);
for(var j=0; j<4; j++){
if(i*8+j*6>wa.length*32) s.push(p);
else s.push(tab.charAt((t>>6*(3-j))&0x3F));
}
}
return s.join("");
}
function add(x,y) {
var l=(x&0xFFFF)+(y&0xFFFF);
var m=(x>>16)+(y>>16)+(l>>16);
return (m<<16)|(l&0xFFFF);
}
function R(n,c){ return (n<<c)|(n>>>(32-c)); }
function C(q,a,b,x,s,t){ return add(R(add(add(a,q),add(x,t)),s),b); }
function FF(a,b,c,d,x,s,t){ return C((b&c)|((~b)&d),a,b,x,s,t); }
function GG(a,b,c,d,x,s,t){ return C((b&d)|(c&(~d)),a,b,x,s,t); }
function HH(a,b,c,d,x,s,t){ return C(b^c^d,a,b,x,s,t); }
function II(a,b,c,d,x,s,t){ return C(c^(b|(~d)),a,b,x,s,t); }
function core(x,len){
x[len>>5]|=0x80<<((len)%32);
x[(((len+64)>>>9)<<4)+14]=len;
var a= 1732584193;
var b=-271733879;
var c=-1732584194;
var d= 271733878;
for(var i=0; i<x.length; i+=16){
var olda=a;
var oldb=b;
var oldc=c;
var oldd=d;
a=FF(a,b,c,d,x[i+ 0],7 ,-680876936);
d=FF(d,a,b,c,x[i+ 1],12,-389564586);
c=FF(c,d,a,b,x[i+ 2],17, 606105819);
b=FF(b,c,d,a,x[i+ 3],22,-1044525330);
a=FF(a,b,c,d,x[i+ 4],7 ,-176418897);
d=FF(d,a,b,c,x[i+ 5],12, 1200080426);
c=FF(c,d,a,b,x[i+ 6],17,-1473231341);
b=FF(b,c,d,a,x[i+ 7],22,-45705983);
a=FF(a,b,c,d,x[i+ 8],7 , 1770035416);
d=FF(d,a,b,c,x[i+ 9],12,-1958414417);
c=FF(c,d,a,b,x[i+10],17,-42063);
b=FF(b,c,d,a,x[i+11],22,-1990404162);
a=FF(a,b,c,d,x[i+12],7 , 1804603682);
d=FF(d,a,b,c,x[i+13],12,-40341101);
c=FF(c,d,a,b,x[i+14],17,-1502002290);
b=FF(b,c,d,a,x[i+15],22, 1236535329);
a=GG(a,b,c,d,x[i+ 1],5 ,-165796510);
d=GG(d,a,b,c,x[i+ 6],9 ,-1069501632);
c=GG(c,d,a,b,x[i+11],14, 643717713);
b=GG(b,c,d,a,x[i+ 0],20,-373897302);
a=GG(a,b,c,d,x[i+ 5],5 ,-701558691);
d=GG(d,a,b,c,x[i+10],9 , 38016083);
c=GG(c,d,a,b,x[i+15],14,-660478335);
b=GG(b,c,d,a,x[i+ 4],20,-405537848);
a=GG(a,b,c,d,x[i+ 9],5 , 568446438);
d=GG(d,a,b,c,x[i+14],9 ,-1019803690);
c=GG(c,d,a,b,x[i+ 3],14,-187363961);
b=GG(b,c,d,a,x[i+ 8],20, 1163531501);
a=GG(a,b,c,d,x[i+13],5 ,-1444681467);
d=GG(d,a,b,c,x[i+ 2],9 ,-51403784);
c=GG(c,d,a,b,x[i+ 7],14, 1735328473);
b=GG(b,c,d,a,x[i+12],20,-1926607734);
a=HH(a,b,c,d,x[i+ 5],4 ,-378558);
d=HH(d,a,b,c,x[i+ 8],11,-2022574463);
c=HH(c,d,a,b,x[i+11],16, 1839030562);
b=HH(b,c,d,a,x[i+14],23,-35309556);
a=HH(a,b,c,d,x[i+ 1],4 ,-1530992060);
d=HH(d,a,b,c,x[i+ 4],11, 1272893353);
c=HH(c,d,a,b,x[i+ 7],16,-155497632);
b=HH(b,c,d,a,x[i+10],23,-1094730640);
a=HH(a,b,c,d,x[i+13],4 , 681279174);
d=HH(d,a,b,c,x[i+ 0],11,-358537222);
c=HH(c,d,a,b,x[i+ 3],16,-722521979);
b=HH(b,c,d,a,x[i+ 6],23, 76029189);
a=HH(a,b,c,d,x[i+ 9],4 ,-640364487);
d=HH(d,a,b,c,x[i+12],11,-421815835);
c=HH(c,d,a,b,x[i+15],16, 530742520);
b=HH(b,c,d,a,x[i+ 2],23,-995338651);
a=II(a,b,c,d,x[i+ 0],6 ,-198630844);
d=II(d,a,b,c,x[i+ 7],10, 1126891415);
c=II(c,d,a,b,x[i+14],15,-1416354905);
b=II(b,c,d,a,x[i+ 5],21,-57434055);
a=II(a,b,c,d,x[i+12],6 , 1700485571);
d=II(d,a,b,c,x[i+ 3],10,-1894986606);
c=II(c,d,a,b,x[i+10],15,-1051523);
b=II(b,c,d,a,x[i+ 1],21,-2054922799);
a=II(a,b,c,d,x[i+ 8],6 , 1873313359);
d=II(d,a,b,c,x[i+15],10,-30611744);
c=II(c,d,a,b,x[i+ 6],15,-1560198380);
b=II(b,c,d,a,x[i+13],21, 1309151649);
a=II(a,b,c,d,x[i+ 4],6 ,-145523070);
d=II(d,a,b,c,x[i+11],10,-1120210379);
c=II(c,d,a,b,x[i+ 2],15, 718787259);
b=II(b,c,d,a,x[i+ 9],21,-343485551);
a = add(a,olda);
b = add(b,oldb);
c = add(c,oldc);
d = add(d,oldd);
}
return [a,b,c,d];
}
function hmac(data,key){
var wa=toWord(key);
if(wa.length>16) wa=core(wa,key.length*chrsz);
var l=[], r=[];
for(var i=0; i<16; i++){
l[i]=wa[i]^0x36363636;
r[i]=wa[i]^0x5c5c5c5c;
}
var h=core(l.concat(toWord(data)),512+data.length*chrsz);
return core(r.concat(h),640);
}
// Public functions
this.compute=function(/* string */data, /* dojo.crypto.outputTypes */outputType){
// summary
// computes the digest of data, and returns the result as a string of type outputType
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(core(toWord(data),data.length*chrsz)); // string
}
case dojo.crypto.outputTypes.String:{
return toString(core(toWord(data),data.length*chrsz)); // string
}
default:{
return toBase64(core(toWord(data),data.length*chrsz)); // string
}
}
};
this.getHMAC=function(/* string */data, /* string */key, /* dojo.crypto.outputTypes */outputType){
// summary
// computes a digest of data using key, and returns the result as a string of outputType
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(hmac(data,key)); // string
}
case dojo.crypto.outputTypes.String:{
return toString(hmac(data,key)); // string
}
default:{
return toBase64(hmac(data,key)); // string
}
}
};
}();
@@ -0,0 +1,22 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.crypto.Rijndael");
dojo.require("dojo.crypto");
dojo.require("dojo.experimental");
dojo.experimental("dojo.crypto.Rijndael");
dojo.crypto.Rijndael = new function(){
this.encrypt=function(plaintext, key){
};
this.decrypt=function(ciphertext, key){
};
}();
@@ -0,0 +1,154 @@
dojo.require("dojo.crypto");
dojo.provide("dojo.crypto.SHA1");
dojo.require("dojo.experimental");
/*
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
* in FIPS PUB 180-1
*
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for details.
*
* Dojo port by Tom Trenka
*/
dojo.experimental("dojo.crypto.SHA1");
dojo.crypto.SHA1 = new function(){
var chrsz=8;
var mask=(1<<chrsz)-1;
function toWord(s) {
var wa=[];
for(var i=0; i<s.length*chrsz; i+=chrsz)
wa[i>>5]|=(s.charCodeAt(i/chrsz)&mask)<<(i%32);
return wa;
}
function toString(wa){
var s=[];
for(var i=0; i<wa.length*32; i+=chrsz)
s.push(String.fromCharCode((wa[i>>5]>>>(i%32))&mask));
return s.join("");
}
function toHex(wa) {
var h="0123456789abcdef";
var s=[];
for(var i=0; i<wa.length*4; i++){
s.push(h.charAt((wa[i>>2]>>((i%4)*8+4))&0xF)+h.charAt((wa[i>>2]>>((i%4)*8))&0xF));
}
return s.join("");
}
function toBase64(wa){
var p="=";
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var s=[];
for(var i=0; i<wa.length*4; i+=3){
var t=(((wa[i>>2]>>8*(i%4))&0xFF)<<16)|(((wa[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|((wa[i+2>>2]>>8*((i+2)%4))&0xFF);
for(var j=0; j<4; j++){
if(i*8+j*6>wa.length*32) s.push(p);
else s.push(tab.charAt((t>>6*(3-j))&0x3F));
}
}
return s.join("");
}
// math
function add(x,y){
var l=(x&0xffff)+(y&0xffff);
var m=(x>>16)+(y>>16)+(l>>16);
return (m<<16)|(l&0xffff);
}
function r(x,n){ return (x<<n)|(x>>>(32-n)); }
// SHA rounds
function f(u,v,w){ return ((u&v)|(~u&w)); }
function g(u,v,w){ return ((u&v)|(u&w)|(v&w)); }
function h(u,v,w){ return (u^v^w); }
function fn(i,u,v,w){
if(i<20) return f(u,v,w);
if(i<40) return h(u,v,w);
if(i<60) return g(u,v,w);
return h(u,v,w);
}
function cnst(i){
if(i<20) return 1518500249;
if(i<40) return 1859775393;
if(i<60) return -1894007588;
return -899497514;
}
function core(x,len){
x[len>>5]|=0x80<<(24-len%32);
x[((len+64>>9)<<4)+15]=len;
var w=[];
var a= 1732584193; // 0x67452301
var b=-271733879; // 0xefcdab89
var c=-1732584194; // 0x98badcfe
var d= 271733878; // 0x10325476
var e=-1009589776; // 0xc3d2e1f0
for(var i=0; i<x.length; i+=16){
var olda=a;
var oldb=b;
var oldc=c;
var oldd=d;
var olde=e;
for(var j=0; j<80; j++){
if(j<16) w[j]=x[i+j];
else w[j]=r(w[j-3]^w[j-8]^w[j-14]^w[j-16],1);
var t=add(add(r(a,5),fn(j,b,c,d)),add(add(e,w[j]),cnst(j)));
e=d; d=c; c=r(b,30); b=a; a=t;
}
a=add(a,olda);
b=add(b,oldb);
c=add(c,oldc);
d=add(d,oldd);
e=add(e,olde);
}
return [a,b,c,d,e];
}
function hmac(data,key){
var wa=toWord(key);
if(wa.length>16) wa=core(wa,key.length*chrsz);
var l=[], r=[];
for(var i=0; i<16; i++){
l[i]=wa[i]^0x36363636;
r[i]=wa[i]^0x5c5c5c5c;
}
var h=core(l.concat(toWord(data)),512+data.length*chrsz);
return core(r.concat(h),640);
}
this.compute=function(data,outputType){
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(core(toWord(data),data.length*chrsz));
}
case dojo.crypto.outputTypes.String:{
return toString(core(toWord(data),data.length*chrsz));
}
default:{
return toBase64(core(toWord(data),data.length*chrsz));
}
}
};
this.getHMAC=function(data,key,outputType){
var out=outputType||dojo.crypto.outputTypes.Base64;
switch(out){
case dojo.crypto.outputTypes.Hex:{
return toHex(hmac(data,key));
}
case dojo.crypto.outputTypes.String:{
return toString(hmac(data,key));
}
default:{
return toBase64(hmac(data,key));
}
}
};
}();
@@ -0,0 +1,20 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.crypto.SHA256");
dojo.require("dojo.crypto");
dojo.require("dojo.experimental");
dojo.experimental("dojo.crypto.SHA256");
dojo.crypto.SHA256 = new function(){
this.compute=function(s){
};
}();
@@ -0,0 +1,17 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.kwCompoundRequire({
common: [
"dojo.crypto",
"dojo.crypto.MD5"
]
});
dojo.provide("dojo.crypto.*");
@@ -0,0 +1,15 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data");
// currently a stub for dojo.data
dojo.data = {};
@@ -0,0 +1,224 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Read");
dojo.require("dojo.lang.declare");
dojo.require("dojo.data.Result");
dojo.require("dojo.experimental");
/* summary:
* This is an abstract API that data provider implementations conform to.
* This file defines methods signatures and intentionally leaves all the
* methods unimplemented.
*/
dojo.experimental("dojo.data.Read");
dojo.declare("dojo.data.Read", null, {
get:
function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* value? */ defaultValue) {
/* summary:
* Returns a single attribute value.
* Returns defaultValue if item does not have a value for attribute.
* Returns null if null was explicitly set as the attribute value.
* Returns undefined if the item does not have a value for the given attribute.
* (So, if store.hasAttribute(item, attribute) returns false, then
* store.get(item, attribute) will return undefined.)
*/
/* exceptions:
* Conforming implementations should throw an exception if *item* is not
* an item, or *attribute* is neither an attribute object or a string.
* examples:
* var darthVader = store.get(lukeSkywalker, "father");
*/
dojo.unimplemented('dojo.data.Read.get');
var attributeValue = null;
return attributeValue; // a literal, an item, null, or undefined (never an array)
},
getValues:
function(/* item */ item, /* attribute || attribute-name-string */ attribute) {
/* summary:
* This getValues() method works just like the get() method, but getValues()
* always returns an array rather than a single attribute value. The array
* may be empty, may contain a single attribute value, or may contain many
* attribute values.
* If the item does not have a value for the given attribute, then getValues()
* will return an empty array: []. (So, if store.hasAttribute(item, attribute)
* returns false, then store.getValues(item, attribute) will return [].)
*/
/* exceptions:
* Throws an exception if item is not an item, or attribute is neither an
* attribute object or a string.
* examples:
* var friendsOfLuke = store.get(lukeSkywalker, "friends");
*/
dojo.unimplemented('dojo.data.Read.getValues');
var array = null;
return array; // an array that may contain literals and items
},
getAttributes:
function(/* item */ item) {
/* summary:
* Returns an array with all the attributes that this item has.
*/
/* exceptions:
* Throws an exception if item is not an item.
* examples:
* var array = store.getAttributes(kermit);
*/
dojo.unimplemented('dojo.data.Read.getAttributes');
var array = null;
return array; // array
},
hasAttribute:
function(/* item */ item, /* attribute || attribute-name-string */ attribute) {
/* summary:
* Returns true if the given *item* has a value or the given *attribute*.
*/
/* exceptions:
* Throws an exception if item is not an item, or attribute is neither an
* attribute object or a string.
* examples:
* var yes = store.hasAttribute(kermit, "color");
*/
dojo.unimplemented('dojo.data.Read.hasAttribute');
return false; // boolean
},
hasAttributeValue:
function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* anything */ value) {
/* summary:
* Returns true if the given *value* is one of the values that getValue()
* would return.
*/
/* exceptions:
* Throws an exception if item is not an item, or attribute is neither an
* attribute object or a string.
* examples:
* var yes = store.hasAttributeValue(kermit, "color", "green");
*/
dojo.unimplemented('dojo.data.Read.hasAttributeValue');
return false; // boolean
},
isItem:
function(/* anything */ something) {
/* summary:
* Returns true if *something* is an item. Returns false if *something*
* is a literal or is any object other than an item.
*/
/* examples:
* var yes = store.isItem(store.newItem());
* var no = store.isItem("green");
*/
dojo.unimplemented('dojo.data.Read.isItem');
return false; // boolean
},
find:
function(/* implementation-dependent */ query, /* object */ optionalKeywordArgs ) {
/* summary:
* Given a query, this method returns a Result object containing
* all the items in the query result set.
* description:
* A Result object will always be returned, even if the result set
* is empty. A Result object will always be returned immediately.
* By default the Result object will be fully populated with result
* items as soon as it is created (synchronously). The caller may request
* an asynchronous Result, meaning a Result that will be populated
* with result items at some point in the future. If the caller requests
* an asynchronous Result, the data store may return either a synchronous
* or asynchronous Result, whichever it prefers. Simple data store
* implementations may always return synchronous Results.
* For more info about the Result API, see dojo.data.Result
* query:
* The query may be optional in some data store implementations.
* The dojo.data.Read API does not specify the syntax or semantics
* of the query itself -- each different data store implementation
* may have its own notion of what a query should look like.
* In most implementations the query will probably be a string, but
* in some implementations the query might be a Date, or a number,
* or some complex keyword parameter object. The dojo.data.Read
* API is completely agnostic about what the query actually is.
* optionalKeywordArgs:
* The optionalKeywordArgs argument is a object like {async: true}.
* All implementations should accept {async: true} and {async: false}
* as valid parameters, although the API does not require that the
* the implementation actually perform asynchronously when
* {async: true} is set. Some implementations may take additional
* keyword options, such as {async: true, maxResults:100}.
*/
/* exceptions:
* Throws an exception if the query is not valid, or if the query
* is required but was not supplied.
* examples:
* var results = store.find("all books");
* var results = store.find();
* var results = store.find("foo/bar", {async: true});
* var results = store.find("foo/bar", {async: false});
* var results = store.find({author:"King", {async: true, maxResults:100});
*/
dojo.unimplemented('dojo.data.Read.find');
var result = null; // new dojo.data.Result().
return result; // an object that implements dojo.data.Result
},
getIdentity:
function(/* item */ item) {
/* summary:
* Returns a unique identifer for an item. The return value will be
* either a string or something that has a toString() method (such as,
* for example, a dojo.uuid.Uuid object).
* description:
* ISSUE -
* Should we move this method out of dojo.data.Read, and put it somewhere
* else, like maybe dojo.data.Identity?
*/
/* exceptions:
* Conforming implementations may throw an exception or return null if
* item is not an item.
* examples:
* var itemId = store.getIdentity(kermit);
* assert(kermit === store.getByIdentity(store.getIdentity(kermit)));
*/
dojo.unimplemented('dojo.data.Read.getIdentity');
var itemIdentifyString = null;
return itemIdentifyString; // string
},
getByIdentity:
function(/* string */ id) {
/* summary:
* Given the id of an item, this method returns the item that has that id.
* Conforming implementations should return null if there is no item with
* the given id.
* description:
* ISSUE -
* We may want to change the name from getByIdentity() to findByIdentity(),
* to reflect the fact that an implementation may not be able to get the
* item from a local cache, and may need to send a request to the server.
* ISSUE -
* Can this method run asynchronously? Should the return value be a Deferred?
* ISSUE -
* Should we move this method out of dojo.data.Read, and put it somewhere
* else, like maybe dojo.data.Identity?
*/
/* examples:
* var alaska = store.getByIdentity("AK");
* assert("AK" == store.getIdentity(store.getByIdentity("AK")));
*/
dojo.unimplemented('dojo.data.Read.getByIdentity');
var item = null;
return item; // item
}
});
@@ -0,0 +1,158 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Result");
dojo.require("dojo.lang.declare");
dojo.require("dojo.experimental");
/* summary:
* This is an abstract API used by data provider implementations.
* This file defines methods signatures and intentionally leaves all the
* methods unimplemented.
*/
dojo.experimental("dojo.data.Result");
dojo.declare("dojo.data.Result", null, {
forEach:
function(/* function */ callbackFunction, /* object? */ callbackObject, /* object? */ optionalKeywordArgs) {
/* summary:
* Loops through the result list, calling a callback function
* for each item in the result list.
* description:
* The forEach() method will call the callback function once for
* each item in the result list. The forEach() method will pass
* 3 arguments to the callbackFunction: an item, the index of
* item in the context of this forEach() loop, and the result object
* itself. The signature of this forEach() method was modeled on
* the forEach() method of Mozilla's Array object in JavaScript 1.6:
* http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
* The forEach() method will returns true if the entire result list
* has been looped through, or false if the result list has not yet
* been looped through.
* The forEach() method will ignore any return value returned by
* the callbackFunction.
* After the forEach() operation has finished (or been cancelled)
* result.forEach() can be called again on the same result object.
* ISSUES -
* We haven't yet decided what other parameters we might allow to
* support fancy features. Here are some ideas:
* results.forEach({callback:callbackFunction, onCompletion: finishedFunction});
* results.forEach({callback:callbackFunction, first: 201, last: 300}); // partial loop
* results.forEach({callback:callbackFunction, first: 200, numItems: 50}); // partial loop from 200 to 250
* CCM - How to specify datastore-specific options to allow caching n
* items before/after current window of items being viewed?
* callbackObject:
* If a callbackObject is provided the callbackFunction will be called
* in the context of the callbackObject (the callbackObject will be
* used as the 'this' for each invocation of the callbackFunction).
* If callbackObject is not provided, or is null, the global object
* associated with callback is used instead.
* optionalKeywordArgs:
* The forEach() method may accept a third parameter, which should be
* an object with keyword parameters. Different implementations may
* make use of different keyword paramters. Conforming
* implementations ignore keyword parameters that they don't
* recognize.
*/
/* examples:
* var results = store.find("recent books"); // synchronous
* var results = store.find("all books", {sync: false}); // asynchronous
* someCallbackFunction = function(item, resultObject) {};
* results.forEach(someCallbackFunction);
* results.forEach({object:someHandlerObject, callback:"someCallbackMethod"});
*/
dojo.unimplemented('dojo.data.Result.forEach');
return false; // boolean
},
getLength:
function() {
/* summary:
* Returns an integer -- the number of items in the result list.
* Returns -1 if the length is not known when the method is called.
*/
dojo.unimplemented('dojo.data.Result.getLength');
return -1; // integer
},
inProgress:
function() {
/* summary:
* Returns true if a forEach() loop is in progress.
*/
dojo.unimplemented('dojo.data.Result.inProgress');
return false; // boolean
},
cancel:
function() {
/* summary:
* Calling cancel() stops any and all processing associated with this
* result object.
* description:
* If a forEach() loop is in progress, calling cancel() will stop
* the loop. If a store.find() is in progress, and that find()
* involves an XMLHttpRequest, calling cancel() will abort the
* XMLHttpRequest. If callbacks have been set using setOnFindCompleted()
* or setOnError(), calling cancel() will cause those callbacks to
* not be called under any circumstances.
*/
dojo.unimplemented('dojo.data.Result.cancel');
},
setOnFindCompleted:
function(/* function */ callbackFunction, /* object? */ callbackObject) {
/* summary:
* Allows you to register a callbackFunction that will
* be called when all the results are available.
* description:
* If a callbackObject is provided the callbackFunction will be
* called in the context of the callbackObject (the callbackObject
* will be used as the 'this' for each invocation of the
* callbackFunction). If callbackObject is not provided, or is
* null, the global object associated with callback is used instead.
* The setOnFindCompleted() method will ignore any return value
* returned by the callbackFunction.
* ISSUES -
* We have not yet decided what parameters the setOnFindCompleted()
* will pass to the callbackFunction...
* (A) The setOnFindCompleted() method will pass one parameter to the
* callbackFunction: the result object itself.
* (B) The setOnFindCompleted() method will pass two parameters to the
* callbackFunction: an iterator object, and the result object itself.
*/
dojo.unimplemented('dojo.data.Result.setOnFindCompleted');
},
setOnError:
function(/* function */ errorCallbackFunction, /* object? */ callbackObject) {
/* summary:
* Allows you to register a errorCallbackFunction that
* will be called if there is any sort of error.
* description:
* If a callbackObject is provided the errorCallbackFunction will
* be called in the context of the callbackObject (the callbackObject
* will be used as the 'this' for each invocation of the
* errorCallbackFunction). If callbackObject is not provided, or is
* null, the global object associated with callback is used instead.
* The setOnError() method will pass two parameters to the
* errorCallbackFunction: an Error object, and the result object
* itself:
* errorCallbackFunction(errorObject, resultObject);
* The setOnError() method will ignore any return value returned
* by the errorCallbackFunction.
*/
dojo.unimplemented('dojo.data.Result.setOnError');
},
getStore:
function() {
/* summary:
* Returns the datastore object that created this result list
*/
dojo.unimplemented('dojo.data.Result.getStore');
return null; // an object that implements dojo.data.Read
}
});
@@ -0,0 +1,169 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.Write");
dojo.require("dojo.lang.declare");
dojo.require("dojo.data.Read");
dojo.require("dojo.experimental");
/* summary:
* This is an abstract API that data provider implementations conform to.
* This file defines methods signatures and intentionally leaves all the
* methods unimplemented.
*/
dojo.experimental("dojo.data.Write");
dojo.declare("dojo.data.Write", dojo.data.Read, {
newItem:
function(/* object? */ keywordArgs) {
/* summary:
* Returns a newly created item. Sets the attributes of the new
* item based on the keywordArgs provided.
*/
/* exceptions:
* Throws an exception if *keywordArgs* is a string or a number or
* anything other than a simple anonymous object.
* examples:
* var kermit = store.newItem({name: "Kermit"});
*/
var newItem;
dojo.unimplemented('dojo.data.Write.newItem');
return newItem; // item
},
deleteItem:
function(/* item */ item) {
/* summary:
* Deletes an item from the store.
*/
/* exceptions:
* Throws an exception if *item* is not an item (if store.isItem(item)
* returns false).
* examples:
* var success = store.deleteItem(kermit);
*/
dojo.unimplemented('dojo.data.Write.deleteItem');
return false; // boolean
},
set:
function(/* item */ item, /* attribute || string */ attribute, /* almost anything */ value) {
/* summary:
* Sets the value of an attribute on an item.
* Replaces any previous value or values.
*/
/* exceptions:
* Throws an exception if *item* is not an item, or if *attribute*
* is neither an attribute object or a string.
* Throws an exception if *value* is undefined.
* examples:
* var success = store.set(kermit, "color", "green");
*/
dojo.unimplemented('dojo.data.Write.set');
return false; // boolean
},
setValues:
function(/* item */ item, /* attribute || string */ attribute, /* array */ values) {
/* summary:
* Adds each value in the *values* array as a value of the given
* attribute on the given item.
* Replaces any previous value or values.
* Calling store.setValues(x, y, []) (with *values* as an empty array) has
* the same effect as calling store.clear(x, y).
*/
/* exceptions:
* Throws an exception if *values* is not an array, if *item* is not an
* item, or if *attribute* is neither an attribute object or a string.
* examples:
* var success = store.setValues(kermit, "color", ["green", "aqua"]);
* success = store.setValues(kermit, "color", []);
* if (success) {assert(!store.hasAttribute(kermit, "color"));}
*/
dojo.unimplemented('dojo.data.Write.setValues');
return false; // boolean
},
clear:
function(/* item */ item, /* attribute || string */ attribute) {
/* summary:
* Deletes all the values of an attribute on an item.
*/
/* exceptions:
* Throws an exception if *item* is not an item, or if *attribute*
* is neither an attribute object or a string.
* examples:
* var success = store.clear(kermit, "color");
* if (success) {assert(!store.hasAttribute(kermit, "color"));}
*/
dojo.unimplemented('dojo.data.Write.clear');
return false; // boolean
},
save:
function() {
/* summary:
* Saves to the server all the changes that have been made locally.
* The save operation may take some time. By default the save will
* be done synchronously, before the call returns. The caller may
* be request an asynchronous save by passing {async: true}.
* If the caller requests an asynchronous save, the data store may do
* either a synchronous or asynchronous save, whichever it prefers.
* Different data store implementations may take additional optional
* parameters.
* description:
* ISSUE -
* Should the async save take a callback, like this:
* store.save({async: true, onComplete: callback});
* Or should the async save return a Deferred, like this:
* var deferred = store.save({async: true});
* deferred.addCallbacks(successCallback, errorCallback);
* Or should save() return boolean, like this:
* var success = store.save();
*/
/* examples:
* var success = store.save();
* var success = store.save({async: true});
*/
dojo.unimplemented('dojo.data.Write.save');
return false; // boolean
},
revert:
function() {
/* summary:
* Discards any unsaved changes.
*/
/* examples:
* var success = store.revert();
*/
dojo.unimplemented('dojo.data.Write.revert');
return false; // boolean
},
isDirty:
function(/* item (or store) */ item) {
/* summary:
* Returns true if the given item has been modified since the last save().
* If the datastore object itself is given as a parameter instead of an
* item, then this method returns true if any item has been modified since
* the last save().
*/
/* exceptions:
* Throws an exception if *item* is neither an item nor the datastore itself.
* examples:
* var trueOrFalse = store.isDirty(kermit); // true if kermit is dirty
* var trueOrFalse = store.isDirty(store); // true if any item is dirty
*/
dojo.unimplemented('dojo.data.Write.isDirty');
return false; // boolean
}
});
@@ -0,0 +1,14 @@
/*
Copyright (c) 2004-2005, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.hostenv.conditionalLoadModule({
common: ["dojo.data"]
});
dojo.hostenv.moduleLoaded("dojo.data.*");
@@ -0,0 +1,220 @@
/*
Copyright (c) 2004-2006, The Dojo Foundation
All Rights Reserved.
Licensed under the Academic Free License version 2.1 or above OR the
modified BSD license. For more information on Dojo licensing, see:
http://dojotoolkit.org/community/licensing.shtml
*/
dojo.provide("dojo.data.csv.CsvStore");
dojo.require("dojo.data.Read");
dojo.require("dojo.lang.assert");
dojo.declare("dojo.data.csv.CsvStore", dojo.data.Read, {
/* summary:
* The CsvStore implements the dojo.data.Read API.
*/
/* examples:
* var csvStore = new dojo.data.csv.CsvStore({url:"movies.csv");
* var csvStore = new dojo.data.csv.CsvStore({url:"http://example.com/movies.csv");
* var fileContents = dojo.hostenv.getText("movies.csv");
* var csvStore = new dojo.data.csv.CsvStore({string:fileContents);
*/
initializer:
function(/* object */ keywordParameters) {
// keywordParameters: {string: String, url: String}
this._arrayOfItems = [];
this._loadFinished = false;
this._csvFileUrl = keywordParameters["url"];
this._csvFileContents = keywordParameters["string"];
},
get:
function(/* item */ item, /* attribute or attribute-name-string */ attribute, /* value? */ defaultValue) {
// summary: See dojo.data.Read.get()
var attributeValue = item[attribute] || defaultValue;
return attributeValue; // a literal, an item, null, or undefined (never an array)
},
getValues:
function(/* item */ item, /* attribute or attribute-name-string */ attribute) {
// summary: See dojo.data.Read.getValues()
var array = [this.get(item, attribute)];
return array; // an array that may contain literals and items
},
getAttributes:
function(/* item */ item) {
// summary: See dojo.data.Read.getAttributes()
var array = this._arrayOfKeys;
return array; // array
},
hasAttribute:
function(/* item */ item, /* attribute or attribute-name-string */ attribute) {
// summary: See dojo.data.Read.hasAttribute()
for (var i in this._arrayOfKeys) {
if (this._arrayOfKeys[i] == attribute) {
return true;
}
}
return false; // boolean
},
hasAttributeValue:
function(/* item */ item, /* attribute or attribute-name-string */ attribute, /* anything */ value) {
// summary: See dojo.data.Read.hasAttributeValue()
return (this.get(item, attribute) == value); // boolean
},
isItem:
function(/* anything */ something) {
// summary: See dojo.data.Read.isItem()
for (var i in this._arrayOfItems) {
if (this._arrayOfItems[i] == something) {
return true;
}
}
return false; // boolean
},
find:
function(/* implementation-dependent */ query, /* object */ optionalKeywordArgs ) {
// summary: See dojo.data.Read.find()
if (!this._loadFinished) {
if (this._csvFileUrl) {
this._csvFileContents = dojo.hostenv.getText(this._csvFileUrl);
}
var arrayOfArrays = this._getArrayOfArraysFromCsvFileContents(this._csvFileContents);
if (arrayOfArrays.length == 0) {
this._arrayOfKeys = [];
} else {
this._arrayOfKeys = arrayOfArrays[0];
}
this._arrayOfItems = this._getArrayOfItemsFromArrayOfArrays(arrayOfArrays);
}
var result = new dojo.data.csv.Result(this._arrayOfItems, this);
return result; // dojo.data.csv.Result
},
getIdentity:
function(/* item */ item) {
// summary: See dojo.data.Read.getIdentity()
for (var i in this._arrayOfItems) {
if (this._arrayOfItems[i] == item) {
return i;
}
}
return null; // boolean
},
getByIdentity:
function(/* string */ id) {
// summary: See dojo.data.Read.getByIdentity()
var i = parseInt(id);
if (i < this._arrayOfItems.length) {
return this._arrayOfItems[i];
} else {
return null;
}
},
// -------------------------------------------------------------------
// Private methods
_getArrayOfArraysFromCsvFileContents:
function(/* string */ csvFileContents) {
/* summary:
* Parses a string of CSV records into a nested array structure.
* description:
* Given a string containing CSV records, this method parses
* the string and returns a data structure containing the parsed
* content. The data structure we return is an array of length
* R, where R is the number of rows (lines) in the CSV data. The
* return array contains one sub-array for each CSV line, and each
* sub-array contains C string values, where C is the number of
* columns in the CSV data.
*/
/* example:
* For example, given this CSV string as input:
* "Title, Year, Producer \n Alien, 1979, Ridley Scott \n Blade Runner, 1982, Ridley Scott"
* We will return this data structure:
* [["Title", "Year", "Producer"]
* ["Alien", "1979", "Ridley Scott"],
* ["Blade Runner", "1982", "Ridley Scott"]]
*/
dojo.lang.assertType(csvFileContents, String);
var lineEndingCharacters = new RegExp("\r\n|\n|\r");
var leadingWhiteSpaceCharacters = new RegExp("^\\s+",'g');
var trailingWhiteSpaceCharacters = new RegExp("\\s+$",'g');
var doubleQuotes = new RegExp('""','g');
var arrayOfOutputRecords = [];
var arrayOfInputLines = csvFileContents.split(lineEndingCharacters);
for (var i in arrayOfInputLines) {
var singleLine = arrayOfInputLines[i];
if (singleLine.length > 0) {
var listOfFields = singleLine.split(',');
var j = 0;
while (j < listOfFields.length) {
var space_field_space = listOfFields[j];
var field_space = space_field_space.replace(leadingWhiteSpaceCharacters, ''); // trim leading whitespace
var field = field_space.replace(trailingWhiteSpaceCharacters, ''); // trim trailing whitespace
var firstChar = field.charAt(0);
var lastChar = field.charAt(field.length - 1);
var secondToLastChar = field.charAt(field.length - 2);
var thirdToLastChar = field.charAt(field.length - 3);
if ((firstChar == '"') &&
((lastChar != '"') ||
((lastChar == '"') && (secondToLastChar == '"') && (thirdToLastChar != '"')) )) {
if (j+1 === listOfFields.length) {
// alert("The last field in record " + i + " is corrupted:\n" + field);
return null;
}
var nextField = listOfFields[j+1];
listOfFields[j] = field_space + ',' + nextField;
listOfFields.splice(j+1, 1); // delete element [j+1] from the list
} else {
if ((firstChar == '"') && (lastChar == '"')) {
field = field.slice(1, (field.length - 1)); // trim the " characters off the ends
field = field.replace(doubleQuotes, '"'); // replace "" with "
}
listOfFields[j] = field;
j += 1;
}
}
arrayOfOutputRecords.push(listOfFields);
}
}
return arrayOfOutputRecords; // Array
},
_getArrayOfItemsFromArrayOfArrays:
function(/* array */ arrayOfArrays) {
/* summary:
* Converts a nested array structure into an array of keyword objects.
*/
/* example:
* For example, given this as input:
* [["Title", "Year", "Producer"]
* ["Alien", "1979", "Ridley Scott"],
* ["Blade Runner", "1982", "Ridley Scott"]]
* We will return this as output:
* [{"Title":"Alien", "Year":"1979", "Producer":"Ridley Scott"},
* {"Title":"Blade Runner", "Year":"1982", "Producer":"Ridley Scott"}]
*/
dojo.lang.assertType(arrayOfArrays, Array);
var arrayOfItems = [];
if (arrayOfArrays.length > 1) {
var arrayOfKeys = arrayOfArrays[0];
for (var i = 1; i < arrayOfArrays.length; ++i) {
var row = arrayOfArrays[i];
var item = {};
for (var j in row) {
var value = row[j];
var key = arrayOfKeys[j];
item[key] = value;
}
arrayOfItems.push(item);
}
}
return arrayOfItems; // Array
}
});

Some files were not shown because too many files have changed in this diff Show More